pnpm 7.9.1 → 7.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -7
- package/bin/pnpm.cjs +3 -0
- package/bin/pnpx.cjs +1 -15
- package/dist/node_modules/.modules.yaml +3 -3
- package/dist/node_modules/.pnpm/lock.yaml +76 -42
- package/dist/node_modules/@npmcli/fs/lib/common/owner-sync.js +96 -0
- package/dist/node_modules/@npmcli/fs/lib/common/owner.js +8 -4
- package/dist/node_modules/@npmcli/fs/lib/copy-file.js +3 -9
- package/dist/node_modules/@npmcli/fs/lib/fs.js +9 -3
- package/dist/node_modules/@npmcli/fs/lib/index.js +3 -1
- package/dist/node_modules/@npmcli/fs/lib/mkdir.js +19 -0
- package/dist/node_modules/@npmcli/fs/lib/mkdtemp.js +3 -8
- package/dist/node_modules/@npmcli/fs/lib/with-owner-sync.js +21 -0
- package/dist/node_modules/@npmcli/fs/lib/with-owner.js +21 -0
- package/dist/node_modules/@npmcli/fs/lib/with-temp-dir.js +4 -2
- package/dist/node_modules/@npmcli/fs/lib/write-file.js +3 -8
- package/dist/node_modules/@npmcli/fs/package.json +21 -9
- package/dist/node_modules/@npmcli/move-file/{index.js → lib/index.js} +50 -27
- package/dist/node_modules/@npmcli/move-file/package.json +20 -7
- package/dist/node_modules/@tootallnate/once/LICENSE +21 -0
- package/dist/node_modules/@tootallnate/once/dist/index.js +21 -36
- package/dist/node_modules/@tootallnate/once/dist/index.js.map +1 -1
- package/dist/node_modules/@tootallnate/once/dist/overloaded-parameters.js +3 -0
- package/dist/node_modules/@tootallnate/once/dist/overloaded-parameters.js.map +1 -0
- package/dist/node_modules/@tootallnate/once/dist/types.js +3 -0
- package/dist/node_modules/@tootallnate/once/dist/types.js.map +1 -0
- package/dist/node_modules/@tootallnate/once/package.json +22 -15
- package/dist/node_modules/cacache/lib/content/read.js +99 -102
- package/dist/node_modules/cacache/lib/content/rm.js +9 -8
- package/dist/node_modules/cacache/lib/content/write.js +67 -67
- package/dist/node_modules/cacache/lib/entry-index.js +128 -118
- package/dist/node_modules/cacache/{get.js → lib/get.js} +88 -100
- package/dist/node_modules/cacache/{index.js → lib/index.js} +5 -6
- package/dist/node_modules/cacache/lib/memoization.js +10 -11
- package/dist/node_modules/cacache/{put.js → lib/put.js} +23 -26
- package/dist/node_modules/cacache/{rm.js → lib/rm.js} +3 -3
- package/dist/node_modules/cacache/lib/util/fix-owner.js +41 -38
- package/dist/node_modules/cacache/lib/util/move-file.js +36 -47
- package/dist/node_modules/cacache/lib/util/tmp.js +5 -7
- package/dist/node_modules/cacache/lib/verify.js +160 -190
- package/dist/node_modules/cacache/node_modules/brace-expansion/.github/FUNDING.yml +2 -0
- package/dist/node_modules/cacache/node_modules/brace-expansion/LICENSE +21 -0
- package/dist/node_modules/cacache/node_modules/brace-expansion/index.js +203 -0
- package/dist/node_modules/cacache/node_modules/brace-expansion/package.json +46 -0
- package/dist/node_modules/cacache/node_modules/glob/LICENSE +15 -0
- package/dist/node_modules/cacache/node_modules/glob/common.js +240 -0
- package/dist/node_modules/cacache/node_modules/glob/glob.js +790 -0
- package/dist/node_modules/cacache/node_modules/glob/package.json +55 -0
- package/dist/node_modules/cacache/node_modules/glob/sync.js +486 -0
- package/dist/node_modules/cacache/node_modules/minimatch/LICENSE +15 -0
- package/dist/node_modules/cacache/node_modules/minimatch/lib/path.js +4 -0
- package/dist/node_modules/cacache/node_modules/minimatch/minimatch.js +906 -0
- package/dist/node_modules/cacache/node_modules/minimatch/package.json +32 -0
- package/dist/node_modules/cacache/package.json +34 -30
- package/dist/node_modules/http-proxy-agent/dist/agent.js +3 -3
- package/dist/node_modules/http-proxy-agent/dist/agent.js.map +1 -1
- package/dist/node_modules/http-proxy-agent/package.json +4 -4
- package/dist/node_modules/lru-cache/LICENSE +1 -1
- package/dist/node_modules/lru-cache/index.js +921 -247
- package/dist/node_modules/lru-cache/package.json +49 -9
- package/dist/node_modules/make-fetch-happen/LICENSE +1 -1
- package/dist/node_modules/make-fetch-happen/lib/agent.js +34 -14
- package/dist/node_modules/make-fetch-happen/lib/cache/entry.js +90 -106
- package/dist/node_modules/make-fetch-happen/lib/cache/errors.js +1 -0
- package/dist/node_modules/make-fetch-happen/lib/cache/index.js +10 -6
- package/dist/node_modules/make-fetch-happen/lib/cache/policy.js +21 -21
- package/dist/node_modules/make-fetch-happen/lib/dns.js +49 -0
- package/dist/node_modules/make-fetch-happen/lib/fetch.js +40 -22
- package/dist/node_modules/make-fetch-happen/lib/index.js +4 -3
- package/dist/node_modules/make-fetch-happen/lib/options.js +17 -9
- package/dist/node_modules/make-fetch-happen/lib/pipeline.js +41 -0
- package/dist/node_modules/make-fetch-happen/lib/remote.js +28 -9
- package/dist/node_modules/make-fetch-happen/package.json +36 -33
- package/dist/node_modules/minipass-fetch/lib/blob.js +4 -4
- package/dist/node_modules/minipass-fetch/lib/body.js +63 -49
- package/dist/node_modules/minipass-fetch/lib/fetch-error.js +2 -1
- package/dist/node_modules/minipass-fetch/lib/headers.js +38 -21
- package/dist/node_modules/minipass-fetch/lib/index.js +130 -106
- package/dist/node_modules/minipass-fetch/lib/request.js +46 -28
- package/dist/node_modules/minipass-fetch/lib/response.js +3 -2
- package/dist/node_modules/minipass-fetch/package.json +27 -14
- package/dist/node_modules/node-gyp/.github/workflows/release-please.yml +1 -1
- package/dist/node_modules/node-gyp/.github/workflows/tests.yml +16 -9
- package/dist/node_modules/node-gyp/.github/workflows/visual-studio.yml +16 -8
- package/dist/node_modules/node-gyp/lib/build.js +7 -0
- package/dist/node_modules/node-gyp/lib/configure.js +26 -1
- package/dist/node_modules/node-gyp/lib/create-config-gypi.js +2 -1
- package/dist/node_modules/node-gyp/lib/find-visualstudio.js +9 -8
- package/dist/node_modules/node-gyp/lib/node-gyp.js +4 -0
- package/dist/node_modules/node-gyp/package.json +4 -4
- package/dist/node_modules/semver/node_modules/lru-cache/LICENSE +15 -0
- package/dist/node_modules/semver/node_modules/lru-cache/index.js +334 -0
- package/dist/node_modules/semver/node_modules/lru-cache/package.json +34 -0
- package/dist/node_modules/socks-proxy-agent/dist/index.js +3 -3
- package/dist/node_modules/socks-proxy-agent/dist/index.js.map +1 -1
- package/dist/node_modules/socks-proxy-agent/package.json +2 -2
- package/dist/node_modules/ssri/{index.js → lib/index.js} +78 -24
- package/dist/node_modules/ssri/package.json +27 -16
- package/dist/pnpm.cjs +67042 -65886
- package/package.json +6 -6
- package/dist/node_modules/@npmcli/fs/lib/common/file-url-to-path/index.js +0 -17
- package/dist/node_modules/@npmcli/fs/lib/common/file-url-to-path/polyfill.js +0 -121
- package/dist/node_modules/@npmcli/fs/lib/mkdir/index.js +0 -32
- package/dist/node_modules/@npmcli/fs/lib/mkdir/polyfill.js +0 -81
- package/dist/node_modules/cacache/lib/util/disposer.js +0 -30
- package/dist/node_modules/cacache/ls.js +0 -6
- package/dist/node_modules/cacache/verify.js +0 -3
- package/dist/node_modules/minipass-fetch/index.js +0 -1
|
@@ -1,334 +1,1008 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
// cache is a Map (or PseudoMap) that matches the keys to
|
|
26
|
-
// the Yallist.Node object.
|
|
27
|
-
class LRUCache {
|
|
28
|
-
constructor (options) {
|
|
29
|
-
if (typeof options === 'number')
|
|
30
|
-
options = { max: options }
|
|
31
|
-
|
|
32
|
-
if (!options)
|
|
33
|
-
options = {}
|
|
1
|
+
const perf =
|
|
2
|
+
typeof performance === 'object' &&
|
|
3
|
+
performance &&
|
|
4
|
+
typeof performance.now === 'function'
|
|
5
|
+
? performance
|
|
6
|
+
: Date
|
|
7
|
+
|
|
8
|
+
const hasAbortController = typeof AbortController === 'function'
|
|
9
|
+
|
|
10
|
+
// minimal backwards-compatibility polyfill
|
|
11
|
+
// this doesn't have nearly all the checks and whatnot that
|
|
12
|
+
// actual AbortController/Signal has, but it's enough for
|
|
13
|
+
// our purposes, and if used properly, behaves the same.
|
|
14
|
+
const AC = hasAbortController
|
|
15
|
+
? AbortController
|
|
16
|
+
: class AbortController {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.signal = new AS()
|
|
19
|
+
}
|
|
20
|
+
abort() {
|
|
21
|
+
this.signal.dispatchEvent('abort')
|
|
22
|
+
}
|
|
23
|
+
}
|
|
34
24
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
const hasAbortSignal = typeof AbortSignal === 'function'
|
|
26
|
+
// Some polyfills put this on the AC class, not global
|
|
27
|
+
const hasACAbortSignal = typeof AC.AbortSignal === 'function'
|
|
28
|
+
const AS = hasAbortSignal
|
|
29
|
+
? AbortSignal
|
|
30
|
+
: hasACAbortSignal
|
|
31
|
+
? AC.AbortController
|
|
32
|
+
: class AbortSignal {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.aborted = false
|
|
35
|
+
this._listeners = []
|
|
36
|
+
}
|
|
37
|
+
dispatchEvent(type) {
|
|
38
|
+
if (type === 'abort') {
|
|
39
|
+
this.aborted = true
|
|
40
|
+
const e = { type, target: this }
|
|
41
|
+
this.onabort(e)
|
|
42
|
+
this._listeners.forEach(f => f(e), this)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
onabort() {}
|
|
46
|
+
addEventListener(ev, fn) {
|
|
47
|
+
if (ev === 'abort') {
|
|
48
|
+
this._listeners.push(fn)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
removeEventListener(ev, fn) {
|
|
52
|
+
if (ev === 'abort') {
|
|
53
|
+
this._listeners = this._listeners.filter(f => f !== fn)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
39
57
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
const warned = new Set()
|
|
59
|
+
const deprecatedOption = (opt, instead) => {
|
|
60
|
+
const code = `LRU_CACHE_OPTION_${opt}`
|
|
61
|
+
if (shouldWarn(code)) {
|
|
62
|
+
warn(code, `${opt} option`, `options.${instead}`, LRUCache)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const deprecatedMethod = (method, instead) => {
|
|
66
|
+
const code = `LRU_CACHE_METHOD_${method}`
|
|
67
|
+
if (shouldWarn(code)) {
|
|
68
|
+
const { prototype } = LRUCache
|
|
69
|
+
const { get } = Object.getOwnPropertyDescriptor(prototype, method)
|
|
70
|
+
warn(code, `${method} method`, `cache.${instead}()`, get)
|
|
50
71
|
}
|
|
72
|
+
}
|
|
73
|
+
const deprecatedProperty = (field, instead) => {
|
|
74
|
+
const code = `LRU_CACHE_PROPERTY_${field}`
|
|
75
|
+
if (shouldWarn(code)) {
|
|
76
|
+
const { prototype } = LRUCache
|
|
77
|
+
const { get } = Object.getOwnPropertyDescriptor(prototype, field)
|
|
78
|
+
warn(code, `${field} property`, `cache.${instead}`, get)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
51
81
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
82
|
+
const emitWarning = (...a) => {
|
|
83
|
+
typeof process === 'object' &&
|
|
84
|
+
process &&
|
|
85
|
+
typeof process.emitWarning === 'function'
|
|
86
|
+
? process.emitWarning(...a)
|
|
87
|
+
: console.error(...a)
|
|
88
|
+
}
|
|
56
89
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
90
|
+
const shouldWarn = code => !warned.has(code)
|
|
91
|
+
|
|
92
|
+
const warn = (code, what, instead, fn) => {
|
|
93
|
+
warned.add(code)
|
|
94
|
+
const msg = `The ${what} is deprecated. Please use ${instead} instead.`
|
|
95
|
+
emitWarning(msg, 'DeprecationWarning', code, fn)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n)
|
|
99
|
+
|
|
100
|
+
/* istanbul ignore next - This is a little bit ridiculous, tbh.
|
|
101
|
+
* The maximum array length is 2^32-1 or thereabouts on most JS impls.
|
|
102
|
+
* And well before that point, you're caching the entire world, I mean,
|
|
103
|
+
* that's ~32GB of just integers for the next/prev links, plus whatever
|
|
104
|
+
* else to hold that many keys and values. Just filling the memory with
|
|
105
|
+
* zeroes at init time is brutal when you get that big.
|
|
106
|
+
* But why not be complete?
|
|
107
|
+
* Maybe in the future, these limits will have expanded. */
|
|
108
|
+
const getUintArray = max =>
|
|
109
|
+
!isPosInt(max)
|
|
110
|
+
? null
|
|
111
|
+
: max <= Math.pow(2, 8)
|
|
112
|
+
? Uint8Array
|
|
113
|
+
: max <= Math.pow(2, 16)
|
|
114
|
+
? Uint16Array
|
|
115
|
+
: max <= Math.pow(2, 32)
|
|
116
|
+
? Uint32Array
|
|
117
|
+
: max <= Number.MAX_SAFE_INTEGER
|
|
118
|
+
? ZeroArray
|
|
119
|
+
: null
|
|
120
|
+
|
|
121
|
+
class ZeroArray extends Array {
|
|
122
|
+
constructor(size) {
|
|
123
|
+
super(size)
|
|
124
|
+
this.fill(0)
|
|
62
125
|
}
|
|
126
|
+
}
|
|
63
127
|
|
|
64
|
-
|
|
65
|
-
|
|
128
|
+
class Stack {
|
|
129
|
+
constructor(max) {
|
|
130
|
+
if (max === 0) {
|
|
131
|
+
return []
|
|
132
|
+
}
|
|
133
|
+
const UintArray = getUintArray(max)
|
|
134
|
+
this.heap = new UintArray(max)
|
|
135
|
+
this.length = 0
|
|
136
|
+
}
|
|
137
|
+
push(n) {
|
|
138
|
+
this.heap[this.length++] = n
|
|
66
139
|
}
|
|
67
|
-
|
|
68
|
-
return this[
|
|
140
|
+
pop() {
|
|
141
|
+
return this.heap[--this.length]
|
|
69
142
|
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
class LRUCache {
|
|
146
|
+
constructor(options = {}) {
|
|
147
|
+
const {
|
|
148
|
+
max = 0,
|
|
149
|
+
ttl,
|
|
150
|
+
ttlResolution = 1,
|
|
151
|
+
ttlAutopurge,
|
|
152
|
+
updateAgeOnGet,
|
|
153
|
+
updateAgeOnHas,
|
|
154
|
+
allowStale,
|
|
155
|
+
dispose,
|
|
156
|
+
disposeAfter,
|
|
157
|
+
noDisposeOnSet,
|
|
158
|
+
noUpdateTTL,
|
|
159
|
+
maxSize = 0,
|
|
160
|
+
maxEntrySize = 0,
|
|
161
|
+
sizeCalculation,
|
|
162
|
+
fetchMethod,
|
|
163
|
+
fetchContext,
|
|
164
|
+
noDeleteOnFetchRejection,
|
|
165
|
+
noDeleteOnStaleGet,
|
|
166
|
+
} = options
|
|
167
|
+
|
|
168
|
+
// deprecated options, don't trigger a warning for getting them if
|
|
169
|
+
// the thing being passed in is another LRUCache we're copying.
|
|
170
|
+
const { length, maxAge, stale } =
|
|
171
|
+
options instanceof LRUCache ? {} : options
|
|
172
|
+
|
|
173
|
+
if (max !== 0 && !isPosInt(max)) {
|
|
174
|
+
throw new TypeError('max option must be a nonnegative integer')
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const UintArray = max ? getUintArray(max) : Array
|
|
178
|
+
if (!UintArray) {
|
|
179
|
+
throw new Error('invalid max value: ' + max)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
this.max = max
|
|
183
|
+
this.maxSize = maxSize
|
|
184
|
+
this.maxEntrySize = maxEntrySize || this.maxSize
|
|
185
|
+
this.sizeCalculation = sizeCalculation || length
|
|
186
|
+
if (this.sizeCalculation) {
|
|
187
|
+
if (!this.maxSize && !this.maxEntrySize) {
|
|
188
|
+
throw new TypeError(
|
|
189
|
+
'cannot set sizeCalculation without setting maxSize or maxEntrySize'
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
if (typeof this.sizeCalculation !== 'function') {
|
|
193
|
+
throw new TypeError('sizeCalculation set to non-function')
|
|
194
|
+
}
|
|
195
|
+
}
|
|
70
196
|
|
|
71
|
-
|
|
72
|
-
if (typeof
|
|
73
|
-
throw new TypeError(
|
|
197
|
+
this.fetchMethod = fetchMethod || null
|
|
198
|
+
if (this.fetchMethod && typeof this.fetchMethod !== 'function') {
|
|
199
|
+
throw new TypeError(
|
|
200
|
+
'fetchMethod must be a function if specified'
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.fetchContext = fetchContext
|
|
205
|
+
if (!this.fetchMethod && fetchContext !== undefined) {
|
|
206
|
+
throw new TypeError(
|
|
207
|
+
'cannot set fetchContext without fetchMethod'
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
this.keyMap = new Map()
|
|
212
|
+
this.keyList = new Array(max).fill(null)
|
|
213
|
+
this.valList = new Array(max).fill(null)
|
|
214
|
+
this.next = new UintArray(max)
|
|
215
|
+
this.prev = new UintArray(max)
|
|
216
|
+
this.head = 0
|
|
217
|
+
this.tail = 0
|
|
218
|
+
this.free = new Stack(max)
|
|
219
|
+
this.initialFill = 1
|
|
220
|
+
this.size = 0
|
|
221
|
+
|
|
222
|
+
if (typeof dispose === 'function') {
|
|
223
|
+
this.dispose = dispose
|
|
224
|
+
}
|
|
225
|
+
if (typeof disposeAfter === 'function') {
|
|
226
|
+
this.disposeAfter = disposeAfter
|
|
227
|
+
this.disposed = []
|
|
228
|
+
} else {
|
|
229
|
+
this.disposeAfter = null
|
|
230
|
+
this.disposed = null
|
|
231
|
+
}
|
|
232
|
+
this.noDisposeOnSet = !!noDisposeOnSet
|
|
233
|
+
this.noUpdateTTL = !!noUpdateTTL
|
|
234
|
+
this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection
|
|
235
|
+
|
|
236
|
+
// NB: maxEntrySize is set to maxSize if it's set
|
|
237
|
+
if (this.maxEntrySize !== 0) {
|
|
238
|
+
if (this.maxSize !== 0) {
|
|
239
|
+
if (!isPosInt(this.maxSize)) {
|
|
240
|
+
throw new TypeError(
|
|
241
|
+
'maxSize must be a positive integer if specified'
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (!isPosInt(this.maxEntrySize)) {
|
|
246
|
+
throw new TypeError(
|
|
247
|
+
'maxEntrySize must be a positive integer if specified'
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
this.initializeSizeTracking()
|
|
251
|
+
}
|
|
74
252
|
|
|
75
|
-
this
|
|
76
|
-
|
|
253
|
+
this.allowStale = !!allowStale || !!stale
|
|
254
|
+
this.noDeleteOnStaleGet = !!noDeleteOnStaleGet
|
|
255
|
+
this.updateAgeOnGet = !!updateAgeOnGet
|
|
256
|
+
this.updateAgeOnHas = !!updateAgeOnHas
|
|
257
|
+
this.ttlResolution =
|
|
258
|
+
isPosInt(ttlResolution) || ttlResolution === 0
|
|
259
|
+
? ttlResolution
|
|
260
|
+
: 1
|
|
261
|
+
this.ttlAutopurge = !!ttlAutopurge
|
|
262
|
+
this.ttl = ttl || maxAge || 0
|
|
263
|
+
if (this.ttl) {
|
|
264
|
+
if (!isPosInt(this.ttl)) {
|
|
265
|
+
throw new TypeError(
|
|
266
|
+
'ttl must be a positive integer if specified'
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
this.initializeTTLTracking()
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// do not allow completely unbounded caches
|
|
273
|
+
if (this.max === 0 && this.ttl === 0 && this.maxSize === 0) {
|
|
274
|
+
throw new TypeError(
|
|
275
|
+
'At least one of max, maxSize, or ttl is required'
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
if (!this.ttlAutopurge && !this.max && !this.maxSize) {
|
|
279
|
+
const code = 'LRU_CACHE_UNBOUNDED'
|
|
280
|
+
if (shouldWarn(code)) {
|
|
281
|
+
warned.add(code)
|
|
282
|
+
const msg =
|
|
283
|
+
'TTL caching without ttlAutopurge, max, or maxSize can ' +
|
|
284
|
+
'result in unbounded memory consumption.'
|
|
285
|
+
emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (stale) {
|
|
290
|
+
deprecatedOption('stale', 'allowStale')
|
|
291
|
+
}
|
|
292
|
+
if (maxAge) {
|
|
293
|
+
deprecatedOption('maxAge', 'ttl')
|
|
294
|
+
}
|
|
295
|
+
if (length) {
|
|
296
|
+
deprecatedOption('length', 'sizeCalculation')
|
|
297
|
+
}
|
|
77
298
|
}
|
|
78
|
-
|
|
79
|
-
|
|
299
|
+
|
|
300
|
+
getRemainingTTL(key) {
|
|
301
|
+
return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0
|
|
80
302
|
}
|
|
81
303
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
304
|
+
initializeTTLTracking() {
|
|
305
|
+
this.ttls = new ZeroArray(this.max)
|
|
306
|
+
this.starts = new ZeroArray(this.max)
|
|
307
|
+
|
|
308
|
+
this.setItemTTL = (index, ttl, start = perf.now()) => {
|
|
309
|
+
this.starts[index] = ttl !== 0 ? start : 0
|
|
310
|
+
this.ttls[index] = ttl
|
|
311
|
+
if (ttl !== 0 && this.ttlAutopurge) {
|
|
312
|
+
const t = setTimeout(() => {
|
|
313
|
+
if (this.isStale(index)) {
|
|
314
|
+
this.delete(this.keyList[index])
|
|
315
|
+
}
|
|
316
|
+
}, ttl + 1)
|
|
317
|
+
/* istanbul ignore else - unref() not supported on all platforms */
|
|
318
|
+
if (t.unref) {
|
|
319
|
+
t.unref()
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
86
323
|
|
|
87
|
-
|
|
88
|
-
this[
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
324
|
+
this.updateItemAge = index => {
|
|
325
|
+
this.starts[index] = this.ttls[index] !== 0 ? perf.now() : 0
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// debounce calls to perf.now() to 1s so we're not hitting
|
|
329
|
+
// that costly call repeatedly.
|
|
330
|
+
let cachedNow = 0
|
|
331
|
+
const getNow = () => {
|
|
332
|
+
const n = perf.now()
|
|
333
|
+
if (this.ttlResolution > 0) {
|
|
334
|
+
cachedNow = n
|
|
335
|
+
const t = setTimeout(
|
|
336
|
+
() => (cachedNow = 0),
|
|
337
|
+
this.ttlResolution
|
|
338
|
+
)
|
|
339
|
+
/* istanbul ignore else - not available on all platforms */
|
|
340
|
+
if (t.unref) {
|
|
341
|
+
t.unref()
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return n
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
this.getRemainingTTL = key => {
|
|
348
|
+
const index = this.keyMap.get(key)
|
|
349
|
+
if (index === undefined) {
|
|
350
|
+
return 0
|
|
351
|
+
}
|
|
352
|
+
return this.ttls[index] === 0 || this.starts[index] === 0
|
|
353
|
+
? Infinity
|
|
354
|
+
: this.starts[index] +
|
|
355
|
+
this.ttls[index] -
|
|
356
|
+
(cachedNow || getNow())
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
this.isStale = index => {
|
|
360
|
+
return (
|
|
361
|
+
this.ttls[index] !== 0 &&
|
|
362
|
+
this.starts[index] !== 0 &&
|
|
363
|
+
(cachedNow || getNow()) - this.starts[index] >
|
|
364
|
+
this.ttls[index]
|
|
365
|
+
)
|
|
94
366
|
}
|
|
95
|
-
trim(this)
|
|
96
367
|
}
|
|
97
|
-
|
|
368
|
+
updateItemAge(index) {}
|
|
369
|
+
setItemTTL(index, ttl, start) {}
|
|
370
|
+
isStale(index) {
|
|
371
|
+
return false
|
|
372
|
+
}
|
|
98
373
|
|
|
99
|
-
|
|
100
|
-
|
|
374
|
+
initializeSizeTracking() {
|
|
375
|
+
this.calculatedSize = 0
|
|
376
|
+
this.sizes = new ZeroArray(this.max)
|
|
377
|
+
this.removeItemSize = index => {
|
|
378
|
+
this.calculatedSize -= this.sizes[index]
|
|
379
|
+
this.sizes[index] = 0
|
|
380
|
+
}
|
|
381
|
+
this.requireSize = (k, v, size, sizeCalculation) => {
|
|
382
|
+
if (!isPosInt(size)) {
|
|
383
|
+
if (sizeCalculation) {
|
|
384
|
+
if (typeof sizeCalculation !== 'function') {
|
|
385
|
+
throw new TypeError('sizeCalculation must be a function')
|
|
386
|
+
}
|
|
387
|
+
size = sizeCalculation(v, k)
|
|
388
|
+
if (!isPosInt(size)) {
|
|
389
|
+
throw new TypeError(
|
|
390
|
+
'sizeCalculation return invalid (expect positive integer)'
|
|
391
|
+
)
|
|
392
|
+
}
|
|
393
|
+
} else {
|
|
394
|
+
throw new TypeError(
|
|
395
|
+
'invalid size value (must be positive integer)'
|
|
396
|
+
)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return size
|
|
400
|
+
}
|
|
401
|
+
this.addItemSize = (index, size) => {
|
|
402
|
+
this.sizes[index] = size
|
|
403
|
+
const maxSize = this.maxSize - this.sizes[index]
|
|
404
|
+
while (this.calculatedSize > maxSize) {
|
|
405
|
+
this.evict(true)
|
|
406
|
+
}
|
|
407
|
+
this.calculatedSize += this.sizes[index]
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
removeItemSize(index) {}
|
|
411
|
+
addItemSize(index, size) {}
|
|
412
|
+
requireSize(k, v, size, sizeCalculation) {
|
|
413
|
+
if (size || sizeCalculation) {
|
|
414
|
+
throw new TypeError(
|
|
415
|
+
'cannot set size without setting maxSize or maxEntrySize on cache'
|
|
416
|
+
)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
101
419
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
420
|
+
*indexes({ allowStale = this.allowStale } = {}) {
|
|
421
|
+
if (this.size) {
|
|
422
|
+
for (let i = this.tail; true; ) {
|
|
423
|
+
if (!this.isValidIndex(i)) {
|
|
424
|
+
break
|
|
425
|
+
}
|
|
426
|
+
if (allowStale || !this.isStale(i)) {
|
|
427
|
+
yield i
|
|
428
|
+
}
|
|
429
|
+
if (i === this.head) {
|
|
430
|
+
break
|
|
431
|
+
} else {
|
|
432
|
+
i = this.prev[i]
|
|
433
|
+
}
|
|
434
|
+
}
|
|
108
435
|
}
|
|
109
436
|
}
|
|
110
437
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
438
|
+
*rindexes({ allowStale = this.allowStale } = {}) {
|
|
439
|
+
if (this.size) {
|
|
440
|
+
for (let i = this.head; true; ) {
|
|
441
|
+
if (!this.isValidIndex(i)) {
|
|
442
|
+
break
|
|
443
|
+
}
|
|
444
|
+
if (allowStale || !this.isStale(i)) {
|
|
445
|
+
yield i
|
|
446
|
+
}
|
|
447
|
+
if (i === this.tail) {
|
|
448
|
+
break
|
|
449
|
+
} else {
|
|
450
|
+
i = this.next[i]
|
|
451
|
+
}
|
|
452
|
+
}
|
|
117
453
|
}
|
|
118
454
|
}
|
|
119
455
|
|
|
120
|
-
|
|
121
|
-
return this[
|
|
456
|
+
isValidIndex(index) {
|
|
457
|
+
return this.keyMap.get(this.keyList[index]) === index
|
|
122
458
|
}
|
|
123
459
|
|
|
124
|
-
|
|
125
|
-
|
|
460
|
+
*entries() {
|
|
461
|
+
for (const i of this.indexes()) {
|
|
462
|
+
yield [this.keyList[i], this.valList[i]]
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
*rentries() {
|
|
466
|
+
for (const i of this.rindexes()) {
|
|
467
|
+
yield [this.keyList[i], this.valList[i]]
|
|
468
|
+
}
|
|
126
469
|
}
|
|
127
470
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this[LRU_LIST].length) {
|
|
132
|
-
this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value))
|
|
471
|
+
*keys() {
|
|
472
|
+
for (const i of this.indexes()) {
|
|
473
|
+
yield this.keyList[i]
|
|
133
474
|
}
|
|
475
|
+
}
|
|
476
|
+
*rkeys() {
|
|
477
|
+
for (const i of this.rindexes()) {
|
|
478
|
+
yield this.keyList[i]
|
|
479
|
+
}
|
|
480
|
+
}
|
|
134
481
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
482
|
+
*values() {
|
|
483
|
+
for (const i of this.indexes()) {
|
|
484
|
+
yield this.valList[i]
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
*rvalues() {
|
|
488
|
+
for (const i of this.rindexes()) {
|
|
489
|
+
yield this.valList[i]
|
|
490
|
+
}
|
|
138
491
|
}
|
|
139
492
|
|
|
140
|
-
|
|
141
|
-
return this
|
|
142
|
-
isStale(this, hit) ? false : {
|
|
143
|
-
k: hit.key,
|
|
144
|
-
v: hit.value,
|
|
145
|
-
e: hit.now + (hit.maxAge || 0)
|
|
146
|
-
}).toArray().filter(h => h)
|
|
493
|
+
[Symbol.iterator]() {
|
|
494
|
+
return this.entries()
|
|
147
495
|
}
|
|
148
496
|
|
|
149
|
-
|
|
150
|
-
|
|
497
|
+
find(fn, getOptions = {}) {
|
|
498
|
+
for (const i of this.indexes()) {
|
|
499
|
+
if (fn(this.valList[i], this.keyList[i], this)) {
|
|
500
|
+
return this.get(this.keyList[i], getOptions)
|
|
501
|
+
}
|
|
502
|
+
}
|
|
151
503
|
}
|
|
152
504
|
|
|
153
|
-
|
|
154
|
-
|
|
505
|
+
forEach(fn, thisp = this) {
|
|
506
|
+
for (const i of this.indexes()) {
|
|
507
|
+
fn.call(thisp, this.valList[i], this.keyList[i], this)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
155
510
|
|
|
156
|
-
|
|
157
|
-
|
|
511
|
+
rforEach(fn, thisp = this) {
|
|
512
|
+
for (const i of this.rindexes()) {
|
|
513
|
+
fn.call(thisp, this.valList[i], this.keyList[i], this)
|
|
514
|
+
}
|
|
515
|
+
}
|
|
158
516
|
|
|
159
|
-
|
|
160
|
-
|
|
517
|
+
get prune() {
|
|
518
|
+
deprecatedMethod('prune', 'purgeStale')
|
|
519
|
+
return this.purgeStale
|
|
520
|
+
}
|
|
161
521
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
522
|
+
purgeStale() {
|
|
523
|
+
let deleted = false
|
|
524
|
+
for (const i of this.rindexes({ allowStale: true })) {
|
|
525
|
+
if (this.isStale(i)) {
|
|
526
|
+
this.delete(this.keyList[i])
|
|
527
|
+
deleted = true
|
|
166
528
|
}
|
|
529
|
+
}
|
|
530
|
+
return deleted
|
|
531
|
+
}
|
|
167
532
|
|
|
168
|
-
|
|
169
|
-
|
|
533
|
+
dump() {
|
|
534
|
+
const arr = []
|
|
535
|
+
for (const i of this.indexes({ allowStale: true })) {
|
|
536
|
+
const key = this.keyList[i]
|
|
537
|
+
const v = this.valList[i]
|
|
538
|
+
const value = this.isBackgroundFetch(v)
|
|
539
|
+
? v.__staleWhileFetching
|
|
540
|
+
: v
|
|
541
|
+
const entry = { value }
|
|
542
|
+
if (this.ttls) {
|
|
543
|
+
entry.ttl = this.ttls[i]
|
|
544
|
+
// always dump the start relative to a portable timestamp
|
|
545
|
+
// it's ok for this to be a bit slow, it's a rare operation.
|
|
546
|
+
const age = perf.now() - this.starts[i]
|
|
547
|
+
entry.start = Math.floor(Date.now() - age)
|
|
548
|
+
}
|
|
549
|
+
if (this.sizes) {
|
|
550
|
+
entry.size = this.sizes[i]
|
|
551
|
+
}
|
|
552
|
+
arr.unshift([key, entry])
|
|
553
|
+
}
|
|
554
|
+
return arr
|
|
555
|
+
}
|
|
170
556
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
557
|
+
load(arr) {
|
|
558
|
+
this.clear()
|
|
559
|
+
for (const [key, entry] of arr) {
|
|
560
|
+
if (entry.start) {
|
|
561
|
+
// entry.start is a portable timestamp, but we may be using
|
|
562
|
+
// node's performance.now(), so calculate the offset.
|
|
563
|
+
// it's ok for this to be a bit slow, it's a rare operation.
|
|
564
|
+
const age = Date.now() - entry.start
|
|
565
|
+
entry.start = perf.now() - age
|
|
176
566
|
}
|
|
567
|
+
this.set(key, entry.value, entry)
|
|
568
|
+
}
|
|
569
|
+
}
|
|
177
570
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
571
|
+
dispose(v, k, reason) {}
|
|
572
|
+
|
|
573
|
+
set(
|
|
574
|
+
k,
|
|
575
|
+
v,
|
|
576
|
+
{
|
|
577
|
+
ttl = this.ttl,
|
|
578
|
+
start,
|
|
579
|
+
noDisposeOnSet = this.noDisposeOnSet,
|
|
580
|
+
size = 0,
|
|
581
|
+
sizeCalculation = this.sizeCalculation,
|
|
582
|
+
noUpdateTTL = this.noUpdateTTL,
|
|
583
|
+
} = {}
|
|
584
|
+
) {
|
|
585
|
+
size = this.requireSize(k, v, size, sizeCalculation)
|
|
586
|
+
// if the item doesn't fit, don't do anything
|
|
587
|
+
// NB: maxEntrySize set to maxSize by default
|
|
588
|
+
if (this.maxEntrySize && size > this.maxEntrySize) {
|
|
589
|
+
return this
|
|
186
590
|
}
|
|
591
|
+
let index = this.size === 0 ? undefined : this.keyMap.get(k)
|
|
592
|
+
if (index === undefined) {
|
|
593
|
+
// addition
|
|
594
|
+
index = this.newIndex()
|
|
595
|
+
this.keyList[index] = k
|
|
596
|
+
this.valList[index] = v
|
|
597
|
+
this.keyMap.set(k, index)
|
|
598
|
+
this.next[this.tail] = index
|
|
599
|
+
this.prev[index] = this.tail
|
|
600
|
+
this.tail = index
|
|
601
|
+
this.size++
|
|
602
|
+
this.addItemSize(index, size)
|
|
603
|
+
noUpdateTTL = false
|
|
604
|
+
} else {
|
|
605
|
+
// update
|
|
606
|
+
const oldVal = this.valList[index]
|
|
607
|
+
if (v !== oldVal) {
|
|
608
|
+
if (this.isBackgroundFetch(oldVal)) {
|
|
609
|
+
oldVal.__abortController.abort()
|
|
610
|
+
} else {
|
|
611
|
+
if (!noDisposeOnSet) {
|
|
612
|
+
this.dispose(oldVal, k, 'set')
|
|
613
|
+
if (this.disposeAfter) {
|
|
614
|
+
this.disposed.push([oldVal, k, 'set'])
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
this.removeItemSize(index)
|
|
619
|
+
this.valList[index] = v
|
|
620
|
+
this.addItemSize(index, size)
|
|
621
|
+
}
|
|
622
|
+
this.moveToTail(index)
|
|
623
|
+
}
|
|
624
|
+
if (ttl !== 0 && this.ttl === 0 && !this.ttls) {
|
|
625
|
+
this.initializeTTLTracking()
|
|
626
|
+
}
|
|
627
|
+
if (!noUpdateTTL) {
|
|
628
|
+
this.setItemTTL(index, ttl, start)
|
|
629
|
+
}
|
|
630
|
+
if (this.disposeAfter) {
|
|
631
|
+
while (this.disposed.length) {
|
|
632
|
+
this.disposeAfter(...this.disposed.shift())
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return this
|
|
636
|
+
}
|
|
187
637
|
|
|
188
|
-
|
|
638
|
+
newIndex() {
|
|
639
|
+
if (this.size === 0) {
|
|
640
|
+
return this.tail
|
|
641
|
+
}
|
|
642
|
+
if (this.size === this.max && this.max !== 0) {
|
|
643
|
+
return this.evict(false)
|
|
644
|
+
}
|
|
645
|
+
if (this.free.length !== 0) {
|
|
646
|
+
return this.free.pop()
|
|
647
|
+
}
|
|
648
|
+
// initial fill, just keep writing down the list
|
|
649
|
+
return this.initialFill++
|
|
650
|
+
}
|
|
189
651
|
|
|
190
|
-
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
652
|
+
pop() {
|
|
653
|
+
if (this.size) {
|
|
654
|
+
const val = this.valList[this.head]
|
|
655
|
+
this.evict(true)
|
|
656
|
+
return val
|
|
657
|
+
}
|
|
658
|
+
}
|
|
194
659
|
|
|
195
|
-
|
|
660
|
+
evict(free) {
|
|
661
|
+
const head = this.head
|
|
662
|
+
const k = this.keyList[head]
|
|
663
|
+
const v = this.valList[head]
|
|
664
|
+
if (this.isBackgroundFetch(v)) {
|
|
665
|
+
v.__abortController.abort()
|
|
666
|
+
} else {
|
|
667
|
+
this.dispose(v, k, 'evict')
|
|
668
|
+
if (this.disposeAfter) {
|
|
669
|
+
this.disposed.push([v, k, 'evict'])
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
this.removeItemSize(head)
|
|
673
|
+
// if we aren't about to use the index, then null these out
|
|
674
|
+
if (free) {
|
|
675
|
+
this.keyList[head] = null
|
|
676
|
+
this.valList[head] = null
|
|
677
|
+
this.free.push(head)
|
|
196
678
|
}
|
|
679
|
+
this.head = this.next[head]
|
|
680
|
+
this.keyMap.delete(k)
|
|
681
|
+
this.size--
|
|
682
|
+
return head
|
|
683
|
+
}
|
|
197
684
|
|
|
198
|
-
|
|
199
|
-
this
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
685
|
+
has(k, { updateAgeOnHas = this.updateAgeOnHas } = {}) {
|
|
686
|
+
const index = this.keyMap.get(k)
|
|
687
|
+
if (index !== undefined) {
|
|
688
|
+
if (!this.isStale(index)) {
|
|
689
|
+
if (updateAgeOnHas) {
|
|
690
|
+
this.updateItemAge(index)
|
|
691
|
+
}
|
|
692
|
+
return true
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return false
|
|
203
696
|
}
|
|
204
697
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
698
|
+
// like get(), but without any LRU updating or TTL expiration
|
|
699
|
+
peek(k, { allowStale = this.allowStale } = {}) {
|
|
700
|
+
const index = this.keyMap.get(k)
|
|
701
|
+
if (index !== undefined && (allowStale || !this.isStale(index))) {
|
|
702
|
+
const v = this.valList[index]
|
|
703
|
+
// either stale and allowed, or forcing a refresh of non-stale value
|
|
704
|
+
return this.isBackgroundFetch(v) ? v.__staleWhileFetching : v
|
|
705
|
+
}
|
|
209
706
|
}
|
|
210
707
|
|
|
211
|
-
|
|
212
|
-
|
|
708
|
+
backgroundFetch(k, index, options, context) {
|
|
709
|
+
const v = index === undefined ? undefined : this.valList[index]
|
|
710
|
+
if (this.isBackgroundFetch(v)) {
|
|
711
|
+
return v
|
|
712
|
+
}
|
|
713
|
+
const ac = new AC()
|
|
714
|
+
const fetchOpts = {
|
|
715
|
+
signal: ac.signal,
|
|
716
|
+
options,
|
|
717
|
+
context,
|
|
718
|
+
}
|
|
719
|
+
const cb = v => {
|
|
720
|
+
if (!ac.signal.aborted) {
|
|
721
|
+
this.set(k, v, fetchOpts.options)
|
|
722
|
+
}
|
|
723
|
+
return v
|
|
724
|
+
}
|
|
725
|
+
const eb = er => {
|
|
726
|
+
if (this.valList[index] === p) {
|
|
727
|
+
const del =
|
|
728
|
+
!options.noDeleteOnFetchRejection ||
|
|
729
|
+
p.__staleWhileFetching === undefined
|
|
730
|
+
if (del) {
|
|
731
|
+
this.delete(k)
|
|
732
|
+
} else {
|
|
733
|
+
// still replace the *promise* with the stale value,
|
|
734
|
+
// since we are done with the promise at this point.
|
|
735
|
+
this.valList[index] = p.__staleWhileFetching
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (p.__returned === p) {
|
|
739
|
+
throw er
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
const pcall = res => res(this.fetchMethod(k, v, fetchOpts))
|
|
743
|
+
const p = new Promise(pcall).then(cb, eb)
|
|
744
|
+
p.__abortController = ac
|
|
745
|
+
p.__staleWhileFetching = v
|
|
746
|
+
p.__returned = null
|
|
747
|
+
if (index === undefined) {
|
|
748
|
+
this.set(k, p, fetchOpts.options)
|
|
749
|
+
index = this.keyMap.get(k)
|
|
750
|
+
} else {
|
|
751
|
+
this.valList[index] = p
|
|
752
|
+
}
|
|
753
|
+
return p
|
|
213
754
|
}
|
|
214
755
|
|
|
215
|
-
|
|
216
|
-
return
|
|
756
|
+
isBackgroundFetch(p) {
|
|
757
|
+
return (
|
|
758
|
+
p &&
|
|
759
|
+
typeof p === 'object' &&
|
|
760
|
+
typeof p.then === 'function' &&
|
|
761
|
+
Object.prototype.hasOwnProperty.call(
|
|
762
|
+
p,
|
|
763
|
+
'__staleWhileFetching'
|
|
764
|
+
) &&
|
|
765
|
+
Object.prototype.hasOwnProperty.call(p, '__returned') &&
|
|
766
|
+
(p.__returned === p || p.__returned === null)
|
|
767
|
+
)
|
|
217
768
|
}
|
|
218
769
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
770
|
+
// this takes the union of get() and set() opts, because it does both
|
|
771
|
+
async fetch(
|
|
772
|
+
k,
|
|
773
|
+
{
|
|
774
|
+
// get options
|
|
775
|
+
allowStale = this.allowStale,
|
|
776
|
+
updateAgeOnGet = this.updateAgeOnGet,
|
|
777
|
+
noDeleteOnStaleGet = this.noDeleteOnStaleGet,
|
|
778
|
+
// set options
|
|
779
|
+
ttl = this.ttl,
|
|
780
|
+
noDisposeOnSet = this.noDisposeOnSet,
|
|
781
|
+
size = 0,
|
|
782
|
+
sizeCalculation = this.sizeCalculation,
|
|
783
|
+
noUpdateTTL = this.noUpdateTTL,
|
|
784
|
+
// fetch exclusive options
|
|
785
|
+
noDeleteOnFetchRejection = this.noDeleteOnFetchRejection,
|
|
786
|
+
fetchContext = this.fetchContext,
|
|
787
|
+
forceRefresh = false,
|
|
788
|
+
} = {}
|
|
789
|
+
) {
|
|
790
|
+
if (!this.fetchMethod) {
|
|
791
|
+
return this.get(k, {
|
|
792
|
+
allowStale,
|
|
793
|
+
updateAgeOnGet,
|
|
794
|
+
noDeleteOnStaleGet,
|
|
795
|
+
})
|
|
796
|
+
}
|
|
223
797
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
798
|
+
const options = {
|
|
799
|
+
allowStale,
|
|
800
|
+
updateAgeOnGet,
|
|
801
|
+
noDeleteOnStaleGet,
|
|
802
|
+
ttl,
|
|
803
|
+
noDisposeOnSet,
|
|
804
|
+
size,
|
|
805
|
+
sizeCalculation,
|
|
806
|
+
noUpdateTTL,
|
|
807
|
+
noDeleteOnFetchRejection,
|
|
808
|
+
}
|
|
227
809
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
810
|
+
let index = this.keyMap.get(k)
|
|
811
|
+
if (index === undefined) {
|
|
812
|
+
const p = this.backgroundFetch(k, index, options, fetchContext)
|
|
813
|
+
return (p.__returned = p)
|
|
814
|
+
} else {
|
|
815
|
+
// in cache, maybe already fetching
|
|
816
|
+
const v = this.valList[index]
|
|
817
|
+
if (this.isBackgroundFetch(v)) {
|
|
818
|
+
return allowStale && v.__staleWhileFetching !== undefined
|
|
819
|
+
? v.__staleWhileFetching
|
|
820
|
+
: (v.__returned = v)
|
|
821
|
+
}
|
|
231
822
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
823
|
+
// if we force a refresh, that means do NOT serve the cached value,
|
|
824
|
+
// unless we are already in the process of refreshing the cache.
|
|
825
|
+
if (!forceRefresh && !this.isStale(index)) {
|
|
826
|
+
this.moveToTail(index)
|
|
827
|
+
if (updateAgeOnGet) {
|
|
828
|
+
this.updateItemAge(index)
|
|
829
|
+
}
|
|
830
|
+
return v
|
|
831
|
+
}
|
|
235
832
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
833
|
+
// ok, it is stale or a forced refresh, and not already fetching.
|
|
834
|
+
// refresh the cache.
|
|
835
|
+
const p = this.backgroundFetch(k, index, options, fetchContext)
|
|
836
|
+
return allowStale && p.__staleWhileFetching !== undefined
|
|
837
|
+
? p.__staleWhileFetching
|
|
838
|
+
: (p.__returned = p)
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
get(
|
|
843
|
+
k,
|
|
844
|
+
{
|
|
845
|
+
allowStale = this.allowStale,
|
|
846
|
+
updateAgeOnGet = this.updateAgeOnGet,
|
|
847
|
+
noDeleteOnStaleGet = this.noDeleteOnStaleGet,
|
|
848
|
+
} = {}
|
|
849
|
+
) {
|
|
850
|
+
const index = this.keyMap.get(k)
|
|
851
|
+
if (index !== undefined) {
|
|
852
|
+
const value = this.valList[index]
|
|
853
|
+
const fetching = this.isBackgroundFetch(value)
|
|
854
|
+
if (this.isStale(index)) {
|
|
855
|
+
// delete only if not an in-flight background fetch
|
|
856
|
+
if (!fetching) {
|
|
857
|
+
if (!noDeleteOnStaleGet) {
|
|
858
|
+
this.delete(k)
|
|
859
|
+
}
|
|
860
|
+
return allowStale ? value : undefined
|
|
861
|
+
} else {
|
|
862
|
+
return allowStale ? value.__staleWhileFetching : undefined
|
|
863
|
+
}
|
|
864
|
+
} else {
|
|
865
|
+
// if we're currently fetching it, we don't actually have it yet
|
|
866
|
+
// it's not stale, which means this isn't a staleWhileRefetching,
|
|
867
|
+
// so we just return undefined
|
|
868
|
+
if (fetching) {
|
|
869
|
+
return undefined
|
|
249
870
|
}
|
|
871
|
+
this.moveToTail(index)
|
|
872
|
+
if (updateAgeOnGet) {
|
|
873
|
+
this.updateItemAge(index)
|
|
874
|
+
}
|
|
875
|
+
return value
|
|
250
876
|
}
|
|
251
877
|
}
|
|
252
878
|
}
|
|
253
879
|
|
|
254
|
-
|
|
255
|
-
this[
|
|
880
|
+
connect(p, n) {
|
|
881
|
+
this.prev[n] = p
|
|
882
|
+
this.next[p] = n
|
|
256
883
|
}
|
|
257
|
-
}
|
|
258
884
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
885
|
+
moveToTail(index) {
|
|
886
|
+
// if tail already, nothing to do
|
|
887
|
+
// if head, move head to next[index]
|
|
888
|
+
// else
|
|
889
|
+
// move next[prev[index]] to next[index] (head has no prev)
|
|
890
|
+
// move prev[next[index]] to prev[index]
|
|
891
|
+
// prev[index] = tail
|
|
892
|
+
// next[tail] = index
|
|
893
|
+
// tail = index
|
|
894
|
+
if (index !== this.tail) {
|
|
895
|
+
if (index === this.head) {
|
|
896
|
+
this.head = this.next[index]
|
|
897
|
+
} else {
|
|
898
|
+
this.connect(this.prev[index], this.next[index])
|
|
272
899
|
}
|
|
900
|
+
this.connect(this.tail, index)
|
|
901
|
+
this.tail = index
|
|
273
902
|
}
|
|
274
|
-
return hit.value
|
|
275
903
|
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const isStale = (self, hit) => {
|
|
279
|
-
if (!hit || (!hit.maxAge && !self[MAX_AGE]))
|
|
280
|
-
return false
|
|
281
904
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
905
|
+
get del() {
|
|
906
|
+
deprecatedMethod('del', 'delete')
|
|
907
|
+
return this.delete
|
|
908
|
+
}
|
|
286
909
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
910
|
+
delete(k) {
|
|
911
|
+
let deleted = false
|
|
912
|
+
if (this.size !== 0) {
|
|
913
|
+
const index = this.keyMap.get(k)
|
|
914
|
+
if (index !== undefined) {
|
|
915
|
+
deleted = true
|
|
916
|
+
if (this.size === 1) {
|
|
917
|
+
this.clear()
|
|
918
|
+
} else {
|
|
919
|
+
this.removeItemSize(index)
|
|
920
|
+
const v = this.valList[index]
|
|
921
|
+
if (this.isBackgroundFetch(v)) {
|
|
922
|
+
v.__abortController.abort()
|
|
923
|
+
} else {
|
|
924
|
+
this.dispose(v, k, 'delete')
|
|
925
|
+
if (this.disposeAfter) {
|
|
926
|
+
this.disposed.push([v, k, 'delete'])
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
this.keyMap.delete(k)
|
|
930
|
+
this.keyList[index] = null
|
|
931
|
+
this.valList[index] = null
|
|
932
|
+
if (index === this.tail) {
|
|
933
|
+
this.tail = this.prev[index]
|
|
934
|
+
} else if (index === this.head) {
|
|
935
|
+
this.head = this.next[index]
|
|
936
|
+
} else {
|
|
937
|
+
this.next[this.prev[index]] = this.next[index]
|
|
938
|
+
this.prev[this.next[index]] = this.prev[index]
|
|
939
|
+
}
|
|
940
|
+
this.size--
|
|
941
|
+
this.free.push(index)
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
if (this.disposed) {
|
|
946
|
+
while (this.disposed.length) {
|
|
947
|
+
this.disposeAfter(...this.disposed.shift())
|
|
948
|
+
}
|
|
297
949
|
}
|
|
950
|
+
return deleted
|
|
298
951
|
}
|
|
299
|
-
}
|
|
300
952
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
953
|
+
clear() {
|
|
954
|
+
for (const index of this.rindexes({ allowStale: true })) {
|
|
955
|
+
const v = this.valList[index]
|
|
956
|
+
if (this.isBackgroundFetch(v)) {
|
|
957
|
+
v.__abortController.abort()
|
|
958
|
+
} else {
|
|
959
|
+
const k = this.keyList[index]
|
|
960
|
+
this.dispose(v, k, 'delete')
|
|
961
|
+
if (this.disposeAfter) {
|
|
962
|
+
this.disposed.push([v, k, 'delete'])
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
306
966
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
967
|
+
this.keyMap.clear()
|
|
968
|
+
this.valList.fill(null)
|
|
969
|
+
this.keyList.fill(null)
|
|
970
|
+
if (this.ttls) {
|
|
971
|
+
this.ttls.fill(0)
|
|
972
|
+
this.starts.fill(0)
|
|
973
|
+
}
|
|
974
|
+
if (this.sizes) {
|
|
975
|
+
this.sizes.fill(0)
|
|
976
|
+
}
|
|
977
|
+
this.head = 0
|
|
978
|
+
this.tail = 0
|
|
979
|
+
this.initialFill = 1
|
|
980
|
+
this.free.length = 0
|
|
981
|
+
this.calculatedSize = 0
|
|
982
|
+
this.size = 0
|
|
983
|
+
if (this.disposed) {
|
|
984
|
+
while (this.disposed.length) {
|
|
985
|
+
this.disposeAfter(...this.disposed.shift())
|
|
986
|
+
}
|
|
987
|
+
}
|
|
310
988
|
}
|
|
311
|
-
}
|
|
312
989
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
this.
|
|
316
|
-
this.value = value
|
|
317
|
-
this.length = length
|
|
318
|
-
this.now = now
|
|
319
|
-
this.maxAge = maxAge || 0
|
|
990
|
+
get reset() {
|
|
991
|
+
deprecatedMethod('reset', 'clear')
|
|
992
|
+
return this.clear
|
|
320
993
|
}
|
|
321
|
-
}
|
|
322
994
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
995
|
+
get length() {
|
|
996
|
+
deprecatedProperty('length', 'size')
|
|
997
|
+
return this.size
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
static get AbortController() {
|
|
1001
|
+
return AC
|
|
1002
|
+
}
|
|
1003
|
+
static get AbortSignal() {
|
|
1004
|
+
return AS
|
|
329
1005
|
}
|
|
330
|
-
if (hit)
|
|
331
|
-
fn.call(thisp, hit.value, hit.key, self)
|
|
332
1006
|
}
|
|
333
1007
|
|
|
334
1008
|
module.exports = LRUCache
|