From ca767681450f0b179145481a6cea1f1eb4c5fe6f Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 14 Apr 2023 14:01:10 -0700 Subject: [PATCH] only print the 'no abort controller' warning if actually used --- src/index.ts | 38 ++++++++++++++++++++++---------------- test/warn-missing-ac.ts | 29 +++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index b73bc03..9cd61f1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -37,22 +37,7 @@ let AC = globalThis.AbortController let AS = globalThis.AbortSignal /* c8 ignore start */ -if ( - typeof AC === 'undefined' && - PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1' -) { - emitWarning( - 'AbortController is not defined. If using lru-cache in ' + - 'node 14, load an AbortController polyfill from the ' + - '`node-abort-controller` package. A minimal polyfill is ' + - 'provided for use by LRUCache.fetch(), but it should not be ' + - 'relied upon in other contexts (eg, passing it to other APIs that ' + - 'use AbortController/AbortSignal might have undesirable effects). ' + - 'You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.', - 'NO_ABORT_CONTROLLER', - 'ENOTSUP', - () => {} - ) +if (typeof AC === 'undefined') { //@ts-ignore AS = class AbortSignal { onabort?: (...a: any[]) => any @@ -65,6 +50,9 @@ if ( } //@ts-ignore AC = class AbortController { + constructor() { + warnACPolyfill() + } signal = new AS() abort(reason: any) { if (this.signal.aborted) return @@ -79,6 +67,24 @@ if ( this.signal.onabort?.(reason) } } + let printACPolyfillWarning = + PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1' + const warnACPolyfill = () => { + if (!printACPolyfillWarning) return + printACPolyfillWarning = false + emitWarning( + 'AbortController is not defined. If using lru-cache in ' + + 'node 14, load an AbortController polyfill from the ' + + '`node-abort-controller` package. A minimal polyfill is ' + + 'provided for use by LRUCache.fetch(), but it should not be ' + + 'relied upon in other contexts (eg, passing it to other APIs that ' + + 'use AbortController/AbortSignal might have undesirable effects). ' + + 'You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.', + 'NO_ABORT_CONTROLLER', + 'ENOTSUP', + warnACPolyfill + ) + } } /* c8 ignore stop */ diff --git a/test/warn-missing-ac.ts b/test/warn-missing-ac.ts index 3944a41..c4d3e1d 100644 --- a/test/warn-missing-ac.ts +++ b/test/warn-missing-ac.ts @@ -4,9 +4,10 @@ const main = async () => { const { spawn } = await import('child_process') // need to run both tests in parallel so we don't miss the close event - t.jobs = 2 + t.jobs = 3 - const tsNode = process.platform === 'win32' ? 'ts-node.cmd' : 'ts-node' + const tsNode = + process.platform === 'win32' ? 'ts-node.cmd' : 'ts-node' const warn = spawn(tsNode, [__filename, 'child']) const warnErr: Buffer[] = [] @@ -21,6 +22,10 @@ const main = async () => { const noWarnErr: Buffer[] = [] noWarn.stderr.on('data', c => noWarnErr.push(c)) + const noFetch = spawn(tsNode, [__filename, 'child-no-fetch']) + const noFetchErr: Buffer[] = [] + noFetch.stderr.on('data', c => noFetchErr.push(c)) + t.test('no warning', async t => { await new Promise(r => noWarn.on('close', (code, signal) => { @@ -32,6 +37,17 @@ const main = async () => { t.equal(Buffer.concat(noWarnErr).toString().trim(), '') }) + t.test('no warning (because no fetch)', async t => { + await new Promise(r => + noFetch.on('close', (code, signal) => { + t.equal(code, 0) + t.equal(signal, null) + r() + }) + ) + t.equal(Buffer.concat(noFetchErr).toString().trim(), '') + }) + t.test('warning', async t => { await new Promise(r => warn.on('close', (code, signal) => { @@ -46,6 +62,15 @@ const main = async () => { switch (process.argv[2]) { case 'child': + //@ts-ignore + globalThis.AbortController = undefined + //@ts-ignore + globalThis.AbortSignal = undefined + import('../').then(({ LRUCache }) => { + new LRUCache({ max: 1, fetchMethod: async () => 1 }).fetch(1) + }) + break + case 'child-no-fetch': //@ts-ignore globalThis.AbortController = undefined //@ts-ignore