Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: isaacs/node-lru-cache
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v7.10.1
Choose a base ref
...
head repository: isaacs/node-lru-cache
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v7.10.2
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on May 12, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    af168ff View commit details

Commits on Jun 23, 2022

  1. Handle nonstandard AbortController/Signal polyfills

    Fix: #239
    
    PR-URL: #243
    Credit: @isaacs
    Close: #243
    Reviewed-by: @isaacs
    isaacs committed Jun 23, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7bbe83c View commit details
  2. 7.10.2

    isaacs committed Jun 23, 2022
    Copy the full SHA
    ea673da View commit details
Showing with 92 additions and 8 deletions.
  1. +6 −1 index.js
  2. +2 −2 package-lock.json
  3. +1 −1 package.json
  4. +82 −3 test/fetch.ts
  5. +1 −1 test/load-check.ts
7 changes: 6 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -22,8 +22,13 @@ const AC = hasAbortController
}
}

const AS = hasAbortController
const hasAbortSignal = typeof AbortSignal === 'function'
// Some polyfills put this on the AC class, not global
const hasACAbortSignal = typeof AC.AbortSignal === 'function'
const AS = hasAbortSignal
? AbortSignal
: hasACAbortSignal
? AC.AbortController
: class AbortSignal {
constructor() {
this.aborted = false
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lru-cache",
"description": "A cache object that deletes the least-recently-used items.",
"version": "7.10.1",
"version": "7.10.2",
"author": "Isaac Z. Schlueter <i@izs.me>",
"keywords": [
"mru",
85 changes: 82 additions & 3 deletions test/fetch.ts
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ let LRU = LRUCache

// if we're on a version that *doesn't* have a native AbortController,
// put the polyfill in there to start with, so LRU covers both cases.
if (!global.AbortController) {
if (!global.AbortController || !global.AbortSignal) {
global.AbortController = exposeStatics(LRU).AbortController
global.AbortSignal = exposeStatics(LRU).AbortSignal
LRU = t.mock('../', {}) as typeof LRUCache
@@ -201,11 +201,90 @@ t.test('fetch options, signal', async t => {
})

t.test('fetch options, signal, with polyfill', async t => {
const { AbortController } = global
const { AbortController, AbortSignal } = global
// @ts-expect-error
t.teardown(() => (global.AbortController = AbortController))
t.teardown(() => Object.assign(global, { AbortController, AbortSignal }))
// @ts-expect-error
global.AbortController = undefined
// @ts-expect-error
global.AbortSignal = undefined
const LRU = t.mock('../', {}) as typeof LRUCache
let aborted = false
const disposed: any[] = []
const disposedAfter: any[] = []
const c = new LRU<number, number>({
max: 3,
ttl: 100,
fetchMethod: async (k, oldVal, { signal, options }) => {
// do something async
await new Promise(res => setImmediate(res))
if (signal.aborted) {
aborted = true
return
}
if (k === 2) {
options.ttl = 25
}
return (oldVal || 0) + 1
},
dispose: (v, k, reason) => {
disposed.push([v, k, reason])
},
disposeAfter: (v, k, reason) => {
disposedAfter.push([v, k, reason])
},
})

const v1 = c.fetch(2)
c.delete(2)
t.equal(await v1, undefined, 'no value returned, aborted by delete')
t.equal(aborted, true)
t.same(disposed, [], 'no disposals for aborted promises')
t.same(disposedAfter, [], 'no disposals for aborted promises')

aborted = false
const v2 = c.fetch(2)
c.set(2, 2)
t.equal(await v2, undefined, 'no value returned, aborted by set')
t.equal(aborted, true)
t.same(disposed, [], 'no disposals for aborted promises')
t.same(disposedAfter, [], 'no disposals for aborted promises')
c.delete(2)
disposed.length = 0
disposedAfter.length = 0

aborted = false
const v3 = c.fetch(2)
c.set(3, 3)
c.set(4, 4)
c.set(5, 5)
t.equal(await v3, undefined, 'no value returned, aborted by evict')
t.equal(aborted, true)
t.same(disposed, [], 'no disposals for aborted promises')
t.same(disposedAfter, [], 'no disposals for aborted promises')

aborted = false
await c.fetch(6, { ttl: 1000 })
t.equal(
c.getRemainingTTL(6),
1000,
'overridden ttl in fetch() opts'
)
await c.fetch(2, { ttl: 1 })
t.equal(c.getRemainingTTL(2), 25, 'overridden ttl in fetchMethod')
})

t.test('fetch options, signal, with half polyfill', async t => {
const { AbortController, AbortSignal } = global
t.teardown(() => {
global.AbortSignal = AbortSignal
//@ts-expect-error
delete AbortController.AbortSignal
})
// @ts-expect-error
global.AbortController.AbortSignal = AbortSignal
// @ts-expect-error
global.AbortSignal = undefined
const LRU = t.mock('../', {}) as typeof LRUCache
let aborted = false
const disposed: any[] = []
2 changes: 1 addition & 1 deletion test/load-check.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import { expose } from './fixtures/expose'
const max = 10000
const cache = new LRU<string, number[]>({ max })

import crypto from 'node:crypto'
import crypto from 'crypto'
const getVal = () => [
crypto.randomBytes(12).toString('hex'),
crypto.randomBytes(12).toString('hex'),