-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdev.js
More file actions
118 lines (104 loc) · 3.63 KB
/
dev.js
File metadata and controls
118 lines (104 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { clock } from '@dr-js/core/module/common/time.js'
import { time } from '@dr-js/core/module/common/format.js'
import { isCompactArrayShallowEqual } from '@dr-js/core/module/common/immutable/check.js'
// memorize expensive immutable transform, with info output, mostly for debug // TODO: remove or reduce code size?
const createTransformCacheWithInfo = (outputInfo = DEFAULT_OUTPUT_INFO, shouldOutputInfo = DEFAULT_SHOULD_OUTPUT_INFO) => {
const infoArray = []
const checkInfo = (info) => {
if (!shouldOutputInfo(info, infoArray)) return
outputInfo(info, infoArray)
info.sumHitCount += info.hitCount
info.sumMissCount += info.missCount
info.hitCount = 0
info.missCount = 0
}
return (transformFunc) => {
let cacheResult = null
let cacheArgs = null
// record debug info
const info = {
id: `#${infoArray.length}`,
stackInfo: new Error().stack.split('\n')[ 2 ].trim(), // one line
sumHitCount: 0,
sumMissCount: 0,
hitCount: 0,
missCount: 0
}
infoArray.push(info, infoArray)
return (...args) => { // drop context for immutable transform should not need <this>
if (!cacheArgs || !isCompactArrayShallowEqual(cacheArgs, args)) {
cacheResult = transformFunc.apply(null, args)
cacheArgs = args
info.missCount++
} else info.hitCount++
// check for output
checkInfo(info)
return cacheResult
}
}
}
const DEFAULT_SHOULD_OUTPUT_INFO = (info, infoArray) => (
(info.hitCount + info.missCount >= 10 && info.hitCount <= info.missCount) ||
(info.hitCount + info.missCount >= Math.max(info.sumHitCount, info.sumMissCount, 200))
)
const DEFAULT_OUTPUT_INFO = (info, infoArray) => {
const isBadCache = info.hitCount <= info.missCount && info.sumHitCount <= info.sumMissCount
console[ isBadCache ? 'warn' : 'log' ](
`[DEBUG][transformCache] ${isBadCache ? 'bad' : 'good'} cache with` +
` HIT[${info.hitCount}/${info.hitCount + info.missCount}]` +
` SUM[${info.sumHitCount}/${info.sumHitCount + info.sumMissCount}]` +
`\n[${info.id} of ${infoArray.length}] ${info.stackInfo}`
)
}
const hijackSetTimeoutInterval = () => {
const hijackPool = new Map()
const setTimeoutOrg = setTimeout
const clearTimeoutOrg = clearTimeout
const setIntervalOrg = setInterval
const clearIntervalOrg = clearInterval
globalThis.setTimeout = (func, delay, ...args) => {
const token = setTimeoutOrg((...args) => {
hijackPool.delete(token)
return func(...args)
}, delay, ...args)
hijackPool.set(token, {
type: 'setTimeout',
stackList: new Error().stack.split('\n').slice(2),
startTime: clock(),
delay
})
return token
}
globalThis.clearTimeout = (token) => {
hijackPool.delete(token)
clearTimeoutOrg(token)
}
globalThis.setInterval = (func, delay, ...args) => {
const token = setIntervalOrg(func, delay, ...args)
hijackPool.set(token, {
type: 'setInterval',
stackList: new Error().stack.split('\n').slice(2),
startTime: clock(),
delay
})
return token
}
globalThis.clearInterval = (token) => {
hijackPool.delete(token)
clearIntervalOrg(token)
}
const logHijackPool = () => {
const currentTime = clock()
const stackList = [ ...hijackPool.values() ]
.map(({ type, stackList, startTime, delay }) => [ ` [${type}] delay: ${time(delay)}, left: ${time(currentTime - startTime)}`, ...stackList ].join('\n'))
console.log([ '[devSetTimeoutHijack|logHijackPool]', ...stackList ].join('\n'))
}
return {
hijackPool,
logHijackPool
}
}
export {
createTransformCacheWithInfo,
hijackSetTimeoutInterval
}