projen 0.54.10 → 0.54.13

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.
Files changed (147) hide show
  1. package/.jsii +4 -4
  2. package/changelog.md +1 -6
  3. package/docs/deps.md +3 -0
  4. package/docs/node.md +38 -10
  5. package/lib/awscdk/auto-discover.js +4 -4
  6. package/lib/awscdk/awscdk-app-java.js +1 -1
  7. package/lib/awscdk/awscdk-app-py.js +1 -1
  8. package/lib/awscdk/awscdk-app-ts.js +1 -1
  9. package/lib/awscdk/awscdk-construct.js +2 -2
  10. package/lib/awscdk/awscdk-deps-java.js +1 -1
  11. package/lib/awscdk/awscdk-deps-js.js +1 -1
  12. package/lib/awscdk/awscdk-deps.js +1 -1
  13. package/lib/awscdk/cdk-config.js +1 -1
  14. package/lib/awscdk/cdk-tasks.js +1 -1
  15. package/lib/awscdk/integration-test.js +1 -1
  16. package/lib/awscdk/lambda-extension.js +1 -1
  17. package/lib/awscdk/lambda-function.js +2 -2
  18. package/lib/build/build-workflow.js +1 -1
  19. package/lib/cdk/auto-discover-base.js +2 -2
  20. package/lib/cdk/construct-lib.js +1 -1
  21. package/lib/cdk/integration-test-base.js +1 -1
  22. package/lib/cdk/jsii-docgen.js +1 -1
  23. package/lib/cdk/jsii-project.js +1 -1
  24. package/lib/cdk8s/auto-discover.js +2 -2
  25. package/lib/cdk8s/cdk8s-app-ts.js +1 -1
  26. package/lib/cdk8s/cdk8s-construct.js +1 -1
  27. package/lib/cdk8s/integration-test.js +1 -1
  28. package/lib/cdktf/cdktf-construct.js +1 -1
  29. package/lib/component.js +1 -1
  30. package/lib/dependencies.js +1 -1
  31. package/lib/dev-env.js +1 -1
  32. package/lib/docker-compose.js +2 -2
  33. package/lib/file.js +1 -1
  34. package/lib/gitattributes.js +1 -1
  35. package/lib/github/auto-approve.js +1 -1
  36. package/lib/github/auto-merge.js +1 -1
  37. package/lib/github/dependabot.js +1 -1
  38. package/lib/github/github-credentials.js +1 -1
  39. package/lib/github/github-project.js +1 -1
  40. package/lib/github/github.js +1 -1
  41. package/lib/github/mergify.js +1 -1
  42. package/lib/github/pr-template.js +1 -1
  43. package/lib/github/pull-request-lint.js +1 -1
  44. package/lib/github/stale.js +1 -1
  45. package/lib/github/task-workflow.js +1 -1
  46. package/lib/github/workflows.js +1 -1
  47. package/lib/gitlab/configuration.js +1 -1
  48. package/lib/gitlab/gitlab-configuration.js +1 -1
  49. package/lib/gitlab/nested-configuration.js +1 -1
  50. package/lib/gitpod.js +1 -1
  51. package/lib/ignore-file.js +1 -1
  52. package/lib/ini.js +1 -1
  53. package/lib/java/java-project.js +1 -1
  54. package/lib/java/junit.js +1 -1
  55. package/lib/java/maven-compile.js +1 -1
  56. package/lib/java/maven-packaging.js +1 -1
  57. package/lib/java/maven-sample.js +1 -1
  58. package/lib/java/pom.js +1 -1
  59. package/lib/java/projenrc.js +1 -1
  60. package/lib/javascript/bundler.js +1 -1
  61. package/lib/javascript/eslint.js +1 -1
  62. package/lib/javascript/jest.js +1 -1
  63. package/lib/javascript/node-package.js +1 -1
  64. package/lib/javascript/node-project.js +1 -1
  65. package/lib/javascript/npm-config.js +1 -1
  66. package/lib/javascript/prettier.js +1 -1
  67. package/lib/javascript/projenrc.js +1 -1
  68. package/lib/javascript/typescript-config.js +1 -1
  69. package/lib/javascript/upgrade-dependencies.js +2 -2
  70. package/lib/json.js +1 -1
  71. package/lib/license.js +1 -1
  72. package/lib/logger.js +1 -1
  73. package/lib/makefile.js +1 -1
  74. package/lib/object-file.js +1 -1
  75. package/lib/project-build.js +1 -1
  76. package/lib/project.js +1 -1
  77. package/lib/projects.js +1 -1
  78. package/lib/projenrc-json.js +1 -1
  79. package/lib/python/pip.js +1 -1
  80. package/lib/python/poetry.js +2 -2
  81. package/lib/python/projenrc.js +1 -1
  82. package/lib/python/pytest-sample.js +1 -1
  83. package/lib/python/pytest.js +1 -1
  84. package/lib/python/python-project.js +1 -1
  85. package/lib/python/python-sample.js +1 -1
  86. package/lib/python/requirements-file.js +1 -1
  87. package/lib/python/setuppy.js +1 -1
  88. package/lib/python/setuptools.js +1 -1
  89. package/lib/python/venv.js +1 -1
  90. package/lib/readme.js +1 -1
  91. package/lib/release/publisher.js +1 -1
  92. package/lib/release/release-trigger.js +1 -1
  93. package/lib/release/release.js +1 -1
  94. package/lib/sample-file.js +2 -2
  95. package/lib/semver.js +1 -1
  96. package/lib/source-code.js +1 -1
  97. package/lib/task-runtime.js +1 -1
  98. package/lib/task.js +1 -1
  99. package/lib/tasks.js +1 -1
  100. package/lib/testing.js +1 -1
  101. package/lib/textfile.js +1 -1
  102. package/lib/toml.js +1 -1
  103. package/lib/typescript/projenrc.js +1 -1
  104. package/lib/typescript/typescript-typedoc.js +1 -1
  105. package/lib/typescript/typescript.js +3 -3
  106. package/lib/version.js +1 -1
  107. package/lib/vscode/devcontainer.js +1 -1
  108. package/lib/vscode/launch-config.js +1 -1
  109. package/lib/vscode/vscode.js +1 -1
  110. package/lib/web/next.js +3 -3
  111. package/lib/web/postcss.js +1 -1
  112. package/lib/web/react.js +4 -4
  113. package/lib/web/tailwind.js +1 -1
  114. package/lib/xmlfile.js +1 -1
  115. package/lib/yaml.js +1 -1
  116. package/node_modules/{yallist → lru-cache}/LICENSE +1 -1
  117. package/node_modules/lru-cache/README.md +699 -0
  118. package/node_modules/lru-cache/index.js +815 -0
  119. package/node_modules/{semver/node_modules/lru-cache → lru-cache}/package.json +17 -7
  120. package/node_modules/semver/README.md +3 -1
  121. package/node_modules/semver/bin/semver.js +17 -8
  122. package/node_modules/semver/classes/comparator.js +3 -2
  123. package/node_modules/semver/classes/index.js +1 -1
  124. package/node_modules/semver/classes/range.js +31 -22
  125. package/node_modules/semver/functions/cmp.js +8 -4
  126. package/node_modules/semver/functions/coerce.js +3 -2
  127. package/node_modules/semver/functions/parse.js +1 -1
  128. package/node_modules/semver/internal/constants.js +2 -2
  129. package/node_modules/semver/internal/identifiers.js +1 -1
  130. package/node_modules/semver/internal/parse-options.js +3 -3
  131. package/node_modules/semver/internal/re.js +3 -3
  132. package/node_modules/semver/package.json +46 -13
  133. package/node_modules/semver/ranges/min-version.js +2 -1
  134. package/node_modules/semver/ranges/outside.js +1 -1
  135. package/node_modules/semver/ranges/simplify.js +15 -12
  136. package/node_modules/semver/ranges/subset.js +53 -31
  137. package/package.json +6 -6
  138. package/releasetag.txt +1 -1
  139. package/version.txt +1 -1
  140. package/node_modules/semver/CHANGELOG.md +0 -111
  141. package/node_modules/semver/node_modules/lru-cache/LICENSE +0 -15
  142. package/node_modules/semver/node_modules/lru-cache/README.md +0 -166
  143. package/node_modules/semver/node_modules/lru-cache/index.js +0 -334
  144. package/node_modules/yallist/README.md +0 -204
  145. package/node_modules/yallist/iterator.js +0 -8
  146. package/node_modules/yallist/package.json +0 -29
  147. package/node_modules/yallist/yallist.js +0 -426
@@ -0,0 +1,815 @@
1
+ const perf = typeof performance === 'object' && performance &&
2
+ typeof performance.now === 'function' ? performance : Date
3
+
4
+ const hasAbortController = typeof AbortController !== 'undefined'
5
+
6
+ // minimal backwards-compatibility polyfill
7
+ const AC = hasAbortController ? AbortController : Object.assign(
8
+ class AbortController {
9
+ constructor () { this.signal = new AC.AbortSignal }
10
+ abort () { this.signal.aborted = true }
11
+ },
12
+ { AbortSignal: class AbortSignal { constructor () { this.aborted = false }}}
13
+ )
14
+
15
+ const warned = new Set()
16
+ const deprecatedOption = (opt, instead) => {
17
+ const code = `LRU_CACHE_OPTION_${opt}`
18
+ if (shouldWarn(code)) {
19
+ warn(code, `${opt} option`, `options.${instead}`, LRUCache)
20
+ }
21
+ }
22
+ const deprecatedMethod = (method, instead) => {
23
+ const code = `LRU_CACHE_METHOD_${method}`
24
+ if (shouldWarn(code)) {
25
+ const { prototype } = LRUCache
26
+ const { get } = Object.getOwnPropertyDescriptor(prototype, method)
27
+ warn(code, `${method} method`, `cache.${instead}()`, get)
28
+ }
29
+ }
30
+ const deprecatedProperty = (field, instead) => {
31
+ const code = `LRU_CACHE_PROPERTY_${field}`
32
+ if (shouldWarn(code)) {
33
+ const { prototype } = LRUCache
34
+ const { get } = Object.getOwnPropertyDescriptor(prototype, field)
35
+ warn(code, `${field} property`, `cache.${instead}`, get)
36
+ }
37
+ }
38
+
39
+ const emitWarning = (...a) => {
40
+ typeof process === 'object' &&
41
+ process &&
42
+ typeof process.emitWarning === 'function'
43
+ ? process.emitWarning(...a)
44
+ : console.error(...a)
45
+ }
46
+
47
+ const shouldWarn = code => !warned.has(code)
48
+
49
+ const warn = (code, what, instead, fn) => {
50
+ warned.add(code)
51
+ const msg = `The ${what} is deprecated. Please use ${instead} instead.`
52
+ emitWarning(msg, 'DeprecationWarning', code, fn)
53
+ }
54
+
55
+ const isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n)
56
+
57
+ /* istanbul ignore next - This is a little bit ridiculous, tbh.
58
+ * The maximum array length is 2^32-1 or thereabouts on most JS impls.
59
+ * And well before that point, you're caching the entire world, I mean,
60
+ * that's ~32GB of just integers for the next/prev links, plus whatever
61
+ * else to hold that many keys and values. Just filling the memory with
62
+ * zeroes at init time is brutal when you get that big.
63
+ * But why not be complete?
64
+ * Maybe in the future, these limits will have expanded. */
65
+ const getUintArray = max => !isPosInt(max) ? null
66
+ : max <= Math.pow(2, 8) ? Uint8Array
67
+ : max <= Math.pow(2, 16) ? Uint16Array
68
+ : max <= Math.pow(2, 32) ? Uint32Array
69
+ : max <= Number.MAX_SAFE_INTEGER ? ZeroArray
70
+ : null
71
+
72
+ class ZeroArray extends Array {
73
+ constructor (size) {
74
+ super(size)
75
+ this.fill(0)
76
+ }
77
+ }
78
+
79
+ class Stack {
80
+ constructor (max) {
81
+ const UintArray = max ? getUintArray(max) : Array
82
+ this.heap = new UintArray(max)
83
+ this.length = 0
84
+ }
85
+ push (n) {
86
+ this.heap[this.length++] = n
87
+ }
88
+ pop () {
89
+ return this.heap[--this.length]
90
+ }
91
+ }
92
+
93
+ class LRUCache {
94
+ constructor (options = {}) {
95
+ const {
96
+ max = 0,
97
+ ttl,
98
+ ttlResolution = 1,
99
+ ttlAutopurge,
100
+ updateAgeOnGet,
101
+ updateAgeOnHas,
102
+ allowStale,
103
+ dispose,
104
+ disposeAfter,
105
+ noDisposeOnSet,
106
+ noUpdateTTL,
107
+ maxSize = 0,
108
+ sizeCalculation,
109
+ fetchMethod,
110
+ } = options
111
+
112
+ // deprecated options, don't trigger a warning for getting them if
113
+ // the thing being passed in is another LRUCache we're copying.
114
+ const {
115
+ length,
116
+ maxAge,
117
+ stale,
118
+ } = options instanceof LRUCache ? {} : options
119
+
120
+ if (max !== 0 && !isPosInt(max)) {
121
+ throw new TypeError('max option must be a nonnegative integer')
122
+ }
123
+
124
+ const UintArray = max ? getUintArray(max) : Array
125
+ if (!UintArray) {
126
+ throw new Error('invalid max value: ' + max)
127
+ }
128
+
129
+ this.max = max
130
+ this.maxSize = maxSize
131
+ this.sizeCalculation = sizeCalculation || length
132
+ if (this.sizeCalculation) {
133
+ if (!this.maxSize) {
134
+ throw new TypeError('cannot set sizeCalculation without setting maxSize')
135
+ }
136
+ if (typeof this.sizeCalculation !== 'function') {
137
+ throw new TypeError('sizeCalculation set to non-function')
138
+ }
139
+ }
140
+
141
+ this.fetchMethod = fetchMethod || null
142
+ if (this.fetchMethod && typeof this.fetchMethod !== 'function') {
143
+ throw new TypeError('fetchMethod must be a function if specified')
144
+ }
145
+
146
+
147
+ this.keyMap = new Map()
148
+ this.keyList = new Array(max).fill(null)
149
+ this.valList = new Array(max).fill(null)
150
+ this.next = new UintArray(max)
151
+ this.prev = new UintArray(max)
152
+ this.head = 0
153
+ this.tail = 0
154
+ this.free = new Stack(max)
155
+ this.initialFill = 1
156
+ this.size = 0
157
+
158
+ if (typeof dispose === 'function') {
159
+ this.dispose = dispose
160
+ }
161
+ if (typeof disposeAfter === 'function') {
162
+ this.disposeAfter = disposeAfter
163
+ this.disposed = []
164
+ } else {
165
+ this.disposeAfter = null
166
+ this.disposed = null
167
+ }
168
+ this.noDisposeOnSet = !!noDisposeOnSet
169
+ this.noUpdateTTL = !!noUpdateTTL
170
+
171
+ if (this.maxSize !== 0) {
172
+ if (!isPosInt(this.maxSize)) {
173
+ throw new TypeError('maxSize must be a positive integer if specified')
174
+ }
175
+ this.initializeSizeTracking()
176
+ }
177
+
178
+ this.allowStale = !!allowStale || !!stale
179
+ this.updateAgeOnGet = !!updateAgeOnGet
180
+ this.updateAgeOnHas = !!updateAgeOnHas
181
+ this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0
182
+ ? ttlResolution : 1
183
+ this.ttlAutopurge = !!ttlAutopurge
184
+ this.ttl = ttl || maxAge || 0
185
+ if (this.ttl) {
186
+ if (!isPosInt(this.ttl)) {
187
+ throw new TypeError('ttl must be a positive integer if specified')
188
+ }
189
+ this.initializeTTLTracking()
190
+ }
191
+
192
+ // do not allow completely unbounded caches
193
+ if (this.max === 0 && this.ttl === 0 && this.maxSize === 0) {
194
+ throw new TypeError('At least one of max, maxSize, or ttl is required')
195
+ }
196
+ if (!this.ttlAutopurge && !this.max && !this.maxSize) {
197
+ const code = 'LRU_CACHE_UNBOUNDED'
198
+ if (shouldWarn(code)) {
199
+ warned.add(code)
200
+ const msg = 'TTL caching without ttlAutopurge, max, or maxSize can ' +
201
+ 'result in unbounded memory consumption.'
202
+ emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache)
203
+ }
204
+ }
205
+
206
+ if (stale) {
207
+ deprecatedOption('stale', 'allowStale')
208
+ }
209
+ if (maxAge) {
210
+ deprecatedOption('maxAge', 'ttl')
211
+ }
212
+ if (length) {
213
+ deprecatedOption('length', 'sizeCalculation')
214
+ }
215
+ }
216
+
217
+ getRemainingTTL (key) {
218
+ return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0
219
+ }
220
+
221
+ initializeTTLTracking () {
222
+ this.ttls = new ZeroArray(this.max)
223
+ this.starts = new ZeroArray(this.max)
224
+
225
+ this.setItemTTL = (index, ttl) => {
226
+ this.starts[index] = ttl !== 0 ? perf.now() : 0
227
+ this.ttls[index] = ttl
228
+ if (ttl !== 0 && this.ttlAutopurge) {
229
+ const t = setTimeout(() => {
230
+ if (this.isStale(index)) {
231
+ this.delete(this.keyList[index])
232
+ }
233
+ }, ttl + 1)
234
+ /* istanbul ignore else - unref() not supported on all platforms */
235
+ if (t.unref) {
236
+ t.unref()
237
+ }
238
+ }
239
+ }
240
+
241
+ this.updateItemAge = (index) => {
242
+ this.starts[index] = this.ttls[index] !== 0 ? perf.now() : 0
243
+ }
244
+
245
+ // debounce calls to perf.now() to 1s so we're not hitting
246
+ // that costly call repeatedly.
247
+ let cachedNow = 0
248
+ const getNow = () => {
249
+ const n = perf.now()
250
+ if (this.ttlResolution > 0) {
251
+ cachedNow = n
252
+ const t = setTimeout(() => cachedNow = 0, this.ttlResolution)
253
+ /* istanbul ignore else - not available on all platforms */
254
+ if (t.unref) {
255
+ t.unref()
256
+ }
257
+ }
258
+ return n
259
+ }
260
+
261
+ this.getRemainingTTL = (key) => {
262
+ const index = this.keyMap.get(key)
263
+ if (index === undefined) {
264
+ return 0
265
+ }
266
+ return this.ttls[index] === 0 || this.starts[index] === 0 ? Infinity
267
+ : ((this.starts[index] + this.ttls[index]) - (cachedNow || getNow()))
268
+ }
269
+
270
+ this.isStale = (index) => {
271
+ return this.ttls[index] !== 0 && this.starts[index] !== 0 &&
272
+ ((cachedNow || getNow()) - this.starts[index] > this.ttls[index])
273
+ }
274
+ }
275
+ updateItemAge (index) {}
276
+ setItemTTL (index, ttl) {}
277
+ isStale (index) { return false }
278
+
279
+ initializeSizeTracking () {
280
+ this.calculatedSize = 0
281
+ this.sizes = new ZeroArray(this.max)
282
+ this.removeItemSize = index => this.calculatedSize -= this.sizes[index]
283
+ this.requireSize = (k, v, size, sizeCalculation) => {
284
+ if (!isPosInt(size)) {
285
+ if (sizeCalculation) {
286
+ if (typeof sizeCalculation !== 'function') {
287
+ throw new TypeError('sizeCalculation must be a function')
288
+ }
289
+ size = sizeCalculation(v, k)
290
+ if (!isPosInt(size)) {
291
+ throw new TypeError('sizeCalculation return invalid (expect positive integer)')
292
+ }
293
+ } else {
294
+ throw new TypeError('invalid size value (must be positive integer)')
295
+ }
296
+ }
297
+ return size
298
+ }
299
+ this.addItemSize = (index, v, k, size) => {
300
+ this.sizes[index] = size
301
+ const maxSize = this.maxSize - this.sizes[index]
302
+ while (this.calculatedSize > maxSize) {
303
+ this.evict()
304
+ }
305
+ this.calculatedSize += this.sizes[index]
306
+ }
307
+ this.delete = k => {
308
+ if (this.size !== 0) {
309
+ const index = this.keyMap.get(k)
310
+ if (index !== undefined) {
311
+ this.calculatedSize -= this.sizes[index]
312
+ }
313
+ }
314
+ return LRUCache.prototype.delete.call(this, k)
315
+ }
316
+ }
317
+ removeItemSize (index) {}
318
+ addItemSize (index, v, k, size) {}
319
+ requireSize (k, v, size, sizeCalculation) {
320
+ if (size || sizeCalculation) {
321
+ throw new TypeError('cannot set size without setting maxSize on cache')
322
+ }
323
+ }
324
+
325
+ *indexes ({ allowStale = this.allowStale } = {}) {
326
+ if (this.size) {
327
+ for (let i = this.tail; true; ) {
328
+ if (!this.isValidIndex(i)) {
329
+ break
330
+ }
331
+ if (allowStale || !this.isStale(i)) {
332
+ yield i
333
+ }
334
+ if (i === this.head) {
335
+ break
336
+ } else {
337
+ i = this.prev[i]
338
+ }
339
+ }
340
+ }
341
+ }
342
+
343
+ *rindexes ({ allowStale = this.allowStale } = {}) {
344
+ if (this.size) {
345
+ for (let i = this.head; true; ) {
346
+ if (!this.isValidIndex(i)) {
347
+ break
348
+ }
349
+ if (allowStale || !this.isStale(i)) {
350
+ yield i
351
+ }
352
+ if (i === this.tail) {
353
+ break
354
+ } else {
355
+ i = this.next[i]
356
+ }
357
+ }
358
+ }
359
+ }
360
+
361
+ isValidIndex (index) {
362
+ return this.keyMap.get(this.keyList[index]) === index
363
+ }
364
+
365
+ *entries () {
366
+ for (const i of this.indexes()) {
367
+ yield [this.keyList[i], this.valList[i]]
368
+ }
369
+ }
370
+ *rentries () {
371
+ for (const i of this.rindexes()) {
372
+ yield [this.keyList[i], this.valList[i]]
373
+ }
374
+ }
375
+
376
+ *keys () {
377
+ for (const i of this.indexes()) {
378
+ yield this.keyList[i]
379
+ }
380
+ }
381
+ *rkeys () {
382
+ for (const i of this.rindexes()) {
383
+ yield this.keyList[i]
384
+ }
385
+ }
386
+
387
+ *values () {
388
+ for (const i of this.indexes()) {
389
+ yield this.valList[i]
390
+ }
391
+ }
392
+ *rvalues () {
393
+ for (const i of this.rindexes()) {
394
+ yield this.valList[i]
395
+ }
396
+ }
397
+
398
+ [Symbol.iterator] () {
399
+ return this.entries()
400
+ }
401
+
402
+ find (fn, getOptions = {}) {
403
+ for (const i of this.indexes()) {
404
+ if (fn(this.valList[i], this.keyList[i], this)) {
405
+ return this.get(this.keyList[i], getOptions)
406
+ }
407
+ }
408
+ }
409
+
410
+ forEach (fn, thisp = this) {
411
+ for (const i of this.indexes()) {
412
+ fn.call(thisp, this.valList[i], this.keyList[i], this)
413
+ }
414
+ }
415
+
416
+ rforEach (fn, thisp = this) {
417
+ for (const i of this.rindexes()) {
418
+ fn.call(thisp, this.valList[i], this.keyList[i], this)
419
+ }
420
+ }
421
+
422
+ get prune () {
423
+ deprecatedMethod('prune', 'purgeStale')
424
+ return this.purgeStale
425
+ }
426
+
427
+ purgeStale () {
428
+ let deleted = false
429
+ for (const i of this.rindexes({ allowStale: true })) {
430
+ if (this.isStale(i)) {
431
+ this.delete(this.keyList[i])
432
+ deleted = true
433
+ }
434
+ }
435
+ return deleted
436
+ }
437
+
438
+ dump () {
439
+ const arr = []
440
+ for (const i of this.indexes()) {
441
+ const key = this.keyList[i]
442
+ const value = this.valList[i]
443
+ const entry = { value }
444
+ if (this.ttls) {
445
+ entry.ttl = this.ttls[i]
446
+ }
447
+ if (this.sizes) {
448
+ entry.size = this.sizes[i]
449
+ }
450
+ arr.unshift([key, entry])
451
+ }
452
+ return arr
453
+ }
454
+
455
+ load (arr) {
456
+ this.clear()
457
+ for (const [key, entry] of arr) {
458
+ this.set(key, entry.value, entry)
459
+ }
460
+ }
461
+
462
+ dispose (v, k, reason) {}
463
+
464
+ set (k, v, {
465
+ ttl = this.ttl,
466
+ noDisposeOnSet = this.noDisposeOnSet,
467
+ size = 0,
468
+ sizeCalculation = this.sizeCalculation,
469
+ noUpdateTTL = this.noUpdateTTL,
470
+ } = {}) {
471
+ size = this.requireSize(k, v, size, sizeCalculation)
472
+ let index = this.size === 0 ? undefined : this.keyMap.get(k)
473
+ if (index === undefined) {
474
+ // addition
475
+ index = this.newIndex()
476
+ this.keyList[index] = k
477
+ this.valList[index] = v
478
+ this.keyMap.set(k, index)
479
+ this.next[this.tail] = index
480
+ this.prev[index] = this.tail
481
+ this.tail = index
482
+ this.size ++
483
+ this.addItemSize(index, v, k, size)
484
+ noUpdateTTL = false
485
+ } else {
486
+ // update
487
+ const oldVal = this.valList[index]
488
+ if (v !== oldVal) {
489
+ if (this.isBackgroundFetch(oldVal)) {
490
+ oldVal.__abortController.abort()
491
+ } else {
492
+ if (!noDisposeOnSet) {
493
+ this.dispose(oldVal, k, 'set')
494
+ if (this.disposeAfter) {
495
+ this.disposed.push([oldVal, k, 'set'])
496
+ }
497
+ }
498
+ }
499
+ this.removeItemSize(index)
500
+ this.valList[index] = v
501
+ this.addItemSize(index, v, k, size)
502
+ }
503
+ this.moveToTail(index)
504
+ }
505
+ if (ttl !== 0 && this.ttl === 0 && !this.ttls) {
506
+ this.initializeTTLTracking()
507
+ }
508
+ if (!noUpdateTTL) {
509
+ this.setItemTTL(index, ttl)
510
+ }
511
+ if (this.disposeAfter) {
512
+ while (this.disposed.length) {
513
+ this.disposeAfter(...this.disposed.shift())
514
+ }
515
+ }
516
+ return this
517
+ }
518
+
519
+ newIndex () {
520
+ if (this.size === 0) {
521
+ return this.tail
522
+ }
523
+ if (this.size === this.max) {
524
+ return this.evict()
525
+ }
526
+ if (this.free.length !== 0) {
527
+ return this.free.pop()
528
+ }
529
+ // initial fill, just keep writing down the list
530
+ return this.initialFill++
531
+ }
532
+
533
+ pop () {
534
+ if (this.size) {
535
+ const val = this.valList[this.head]
536
+ this.evict()
537
+ return val
538
+ }
539
+ }
540
+
541
+ evict () {
542
+ const head = this.head
543
+ const k = this.keyList[head]
544
+ const v = this.valList[head]
545
+ if (this.isBackgroundFetch(v)) {
546
+ v.__abortController.abort()
547
+ } else {
548
+ this.dispose(v, k, 'evict')
549
+ if (this.disposeAfter) {
550
+ this.disposed.push([v, k, 'evict'])
551
+ }
552
+ }
553
+ this.removeItemSize(head)
554
+ this.head = this.next[head]
555
+ this.keyMap.delete(k)
556
+ this.size --
557
+ return head
558
+ }
559
+
560
+ has (k, { updateAgeOnHas = this.updateAgeOnHas } = {}) {
561
+ const index = this.keyMap.get(k)
562
+ if (index !== undefined) {
563
+ if (!this.isStale(index)) {
564
+ if (updateAgeOnHas) {
565
+ this.updateItemAge(index)
566
+ }
567
+ return true
568
+ }
569
+ }
570
+ return false
571
+ }
572
+
573
+ // like get(), but without any LRU updating or TTL expiration
574
+ peek (k, { allowStale = this.allowStale } = {}) {
575
+ const index = this.keyMap.get(k)
576
+ if (index !== undefined && (allowStale || !this.isStale(index))) {
577
+ return this.valList[index]
578
+ }
579
+ }
580
+
581
+ backgroundFetch (k, index, options) {
582
+ const v = index === undefined ? undefined : this.valList[index]
583
+ if (this.isBackgroundFetch(v)) {
584
+ return v
585
+ }
586
+ const ac = new AC()
587
+ const fetchOpts = {
588
+ signal: ac.signal,
589
+ options,
590
+ }
591
+ const p = Promise.resolve(this.fetchMethod(k, v, fetchOpts)).then(v => {
592
+ if (!ac.signal.aborted) {
593
+ this.set(k, v, fetchOpts.options)
594
+ }
595
+ return v
596
+ })
597
+ p.__abortController = ac
598
+ p.__staleWhileFetching = v
599
+ if (index === undefined) {
600
+ this.set(k, p, fetchOpts.options)
601
+ index = this.keyMap.get(k)
602
+ } else {
603
+ this.valList[index] = p
604
+ }
605
+ return p
606
+ }
607
+
608
+ isBackgroundFetch (p) {
609
+ return p && typeof p === 'object' && typeof p.then === 'function' &&
610
+ Object.prototype.hasOwnProperty.call(p, '__staleWhileFetching')
611
+ }
612
+
613
+ // this takes the union of get() and set() opts, because it does both
614
+ async fetch (k, {
615
+ allowStale = this.allowStale,
616
+ updateAgeOnGet = this.updateAgeOnGet,
617
+ ttl = this.ttl,
618
+ noDisposeOnSet = this.noDisposeOnSet,
619
+ size = 0,
620
+ sizeCalculation = this.sizeCalculation,
621
+ noUpdateTTL = this.noUpdateTTL,
622
+ } = {}) {
623
+ if (!this.fetchMethod) {
624
+ return this.get(k, {allowStale, updateAgeOnGet})
625
+ }
626
+
627
+ const options = {
628
+ allowStale,
629
+ updateAgeOnGet,
630
+ ttl,
631
+ noDisposeOnSet,
632
+ size,
633
+ sizeCalculation,
634
+ noUpdateTTL,
635
+ }
636
+
637
+ let index = this.keyMap.get(k)
638
+ if (index === undefined) {
639
+ return this.backgroundFetch(k, index, options)
640
+ } else {
641
+ // in cache, maybe already fetching
642
+ const v = this.valList[index]
643
+ if (this.isBackgroundFetch(v)) {
644
+ return allowStale && v.__staleWhileFetching !== undefined
645
+ ? v.__staleWhileFetching : v
646
+ }
647
+
648
+ if (!this.isStale(index)) {
649
+ this.moveToTail(index)
650
+ if (updateAgeOnGet) {
651
+ this.updateItemAge(index)
652
+ }
653
+ return v
654
+ }
655
+
656
+ // ok, it is stale, and not already fetching
657
+ // refresh the cache.
658
+ const p = this.backgroundFetch(k, index, options)
659
+ return allowStale && p.__staleWhileFetching !== undefined
660
+ ? p.__staleWhileFetching : p
661
+ }
662
+ }
663
+
664
+ get (k, {
665
+ allowStale = this.allowStale,
666
+ updateAgeOnGet = this.updateAgeOnGet,
667
+ } = {}) {
668
+ const index = this.keyMap.get(k)
669
+ if (index !== undefined) {
670
+ const value = this.valList[index]
671
+ const fetching = this.isBackgroundFetch(value)
672
+ if (this.isStale(index)) {
673
+ // delete only if not an in-flight background fetch
674
+ if (!fetching) {
675
+ this.delete(k)
676
+ return allowStale ? value : undefined
677
+ } else {
678
+ return allowStale ? value.__staleWhileFetching : undefined
679
+ }
680
+ } else {
681
+ // if we're currently fetching it, we don't actually have it yet
682
+ // it's not stale, which means this isn't a staleWhileRefetching,
683
+ // so we just return undefined
684
+ if (fetching) {
685
+ return undefined
686
+ }
687
+ this.moveToTail(index)
688
+ if (updateAgeOnGet) {
689
+ this.updateItemAge(index)
690
+ }
691
+ return value
692
+ }
693
+ }
694
+ }
695
+
696
+ connect (p, n) {
697
+ this.prev[n] = p
698
+ this.next[p] = n
699
+ }
700
+
701
+ moveToTail (index) {
702
+ // if tail already, nothing to do
703
+ // if head, move head to next[index]
704
+ // else
705
+ // move next[prev[index]] to next[index] (head has no prev)
706
+ // move prev[next[index]] to prev[index]
707
+ // prev[index] = tail
708
+ // next[tail] = index
709
+ // tail = index
710
+ if (index !== this.tail) {
711
+ if (index === this.head) {
712
+ this.head = this.next[index]
713
+ } else {
714
+ this.connect(this.prev[index], this.next[index])
715
+ }
716
+ this.connect(this.tail, index)
717
+ this.tail = index
718
+ }
719
+ }
720
+
721
+ get del () {
722
+ deprecatedMethod('del', 'delete')
723
+ return this.delete
724
+ }
725
+ delete (k) {
726
+ let deleted = false
727
+ if (this.size !== 0) {
728
+ const index = this.keyMap.get(k)
729
+ if (index !== undefined) {
730
+ deleted = true
731
+ if (this.size === 1) {
732
+ this.clear()
733
+ } else {
734
+ this.removeItemSize(index)
735
+ const v = this.valList[index]
736
+ if (this.isBackgroundFetch(v)) {
737
+ v.__abortController.abort()
738
+ } else {
739
+ this.dispose(v, k, 'delete')
740
+ if (this.disposeAfter) {
741
+ this.disposed.push([v, k, 'delete'])
742
+ }
743
+ }
744
+ this.keyMap.delete(k)
745
+ this.keyList[index] = null
746
+ this.valList[index] = null
747
+ if (index === this.tail) {
748
+ this.tail = this.prev[index]
749
+ } else if (index === this.head) {
750
+ this.head = this.next[index]
751
+ } else {
752
+ this.next[this.prev[index]] = this.next[index]
753
+ this.prev[this.next[index]] = this.prev[index]
754
+ }
755
+ this.size --
756
+ this.free.push(index)
757
+ }
758
+ }
759
+ }
760
+ if (this.disposed) {
761
+ while (this.disposed.length) {
762
+ this.disposeAfter(...this.disposed.shift())
763
+ }
764
+ }
765
+ return deleted
766
+ }
767
+
768
+ clear () {
769
+ for (const index of this.rindexes({ allowStale: true })) {
770
+ const v = this.valList[index]
771
+ if (this.isBackgroundFetch(v)) {
772
+ v.__abortController.abort()
773
+ } else {
774
+ const k = this.keyList[index]
775
+ this.dispose(v, k, 'delete')
776
+ if (this.disposeAfter) {
777
+ this.disposed.push([v, k, 'delete'])
778
+ }
779
+ }
780
+ }
781
+
782
+ this.keyMap.clear()
783
+ this.valList.fill(null)
784
+ this.keyList.fill(null)
785
+ if (this.ttls) {
786
+ this.ttls.fill(0)
787
+ this.starts.fill(0)
788
+ }
789
+ if (this.sizes) {
790
+ this.sizes.fill(0)
791
+ }
792
+ this.head = 0
793
+ this.tail = 0
794
+ this.initialFill = 1
795
+ this.free.length = 0
796
+ this.calculatedSize = 0
797
+ this.size = 0
798
+ if (this.disposed) {
799
+ while (this.disposed.length) {
800
+ this.disposeAfter(...this.disposed.shift())
801
+ }
802
+ }
803
+ }
804
+ get reset () {
805
+ deprecatedMethod('reset', 'clear')
806
+ return this.clear
807
+ }
808
+
809
+ get length () {
810
+ deprecatedProperty('length', 'size')
811
+ return this.size
812
+ }
813
+ }
814
+
815
+ module.exports = LRUCache