From 8b354be7d19eedbc6229a345d73377edfb1841ec Mon Sep 17 00:00:00 2001 From: Matthew Costabile Date: Thu, 17 Oct 2024 12:54:43 +0000 Subject: [PATCH 1/4] polyfill for Promise.withResolvers --- src/index.ts | 2 ++ src/promise-withResolvers.ts | 30 ++++++++++++++++++++++++++ test/promise-withResolvers.js | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 src/promise-withResolvers.ts create mode 100644 test/promise-withResolvers.js diff --git a/src/index.ts b/src/index.ts index ac1003d..4c14a1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import * as clipboardItem from './clipboarditem.js' import * as elementCheckVisibility from './element-checkvisibility.js' import * as navigatorClipboard from './navigator-clipboard.js' +import * as withResolvers from './promise-withResolvers.js' import * as requestIdleCallback from './requestidlecallback.js' let supportsModalPseudo = false @@ -47,6 +48,7 @@ export const polyfills = { elementCheckVisibility, navigatorClipboard, requestIdleCallback, + withResolvers, } export function isSupported() { diff --git a/src/promise-withResolvers.ts b/src/promise-withResolvers.ts new file mode 100644 index 0000000..62d4252 --- /dev/null +++ b/src/promise-withResolvers.ts @@ -0,0 +1,30 @@ +/*#__PURE__*/ +export function withResolvers(this: PromiseConstructor) { + const out = {} as { + promise: Promise + resolve: (value: T | PromiseLike) => void + // eslint-disable-next-line @typescript-eslint/no-explicit-any + reject: (reason?: any) => void + } + out.promise = new Promise((resolve, reject) => { + out.resolve = resolve + out.reject = reject + }) + return out +} + +/*#__PURE__*/ +export function isSupported(): boolean { + return 'withResolvers' in Promise && typeof Promise.withResolvers === 'function' +} + +/*#__PURE__*/ +export function isPolyfilled(): boolean { + return 'withResolvers' in Promise && Promise.withResolvers === withResolvers +} + +export function apply(): void { + if (!('withResolvers' in Promise)) { + Object.assign(Promise, {withResolvers}) + } +} diff --git a/test/promise-withResolvers.js b/test/promise-withResolvers.js new file mode 100644 index 0000000..a817cf9 --- /dev/null +++ b/test/promise-withResolvers.js @@ -0,0 +1,40 @@ +import {apply, isPolyfilled, isSupported, withResolvers} from '../lib/promise-withResolvers.js' + +describe('withResolvers', () => { + it('has standard isSupported, isPolyfilled, apply API', () => { + expect(isSupported).to.be.a('function') + expect(isPolyfilled).to.be.a('function') + expect(apply).to.be.a('function') + expect(isSupported()).to.be.a('boolean') + expect(isPolyfilled()).to.equal(false) + }) + + it('resolves to first resolving value', async () => { + const arg = withResolvers() + expect(Object.keys(arg).sort()).to.eql(['promise', 'reject', 'resolve']) + expect(arg).to.have.property('promise').to.be.a('promise') + expect(arg).to.have.property('resolve').to.be.a('function') + expect(arg).to.have.property('reject').to.be.a('function') + + arg.resolve(1) + expect(await arg.promise).to.be.eql(1) + }) + + it('rejects to first rejecting reason', async () => { + const arg = withResolvers() + expect(Object.keys(arg).sort()).to.eql(['promise', 'reject', 'resolve']) + expect(arg).to.have.property('promise').to.be.a('promise') + expect(arg).to.have.property('resolve').to.be.a('function') + expect(arg).to.have.property('reject').to.be.a('function') + + const err = new Error('rejected') + + try { + arg.reject(err) + await arg.promise + expect.fail('should fail') + } catch (e) { + expect(e).to.be.eql(err) + } + }) +}) From 1524c1d65805ae8bdc8b78210194204dc7888f3f Mon Sep 17 00:00:00 2001 From: Matthew Costabile Date: Thu, 17 Oct 2024 12:59:54 +0000 Subject: [PATCH 2/4] requestIdleTimer might be 50 --- test/requestidlecallback.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/requestidlecallback.js b/test/requestidlecallback.js index dd78f8c..07769a4 100644 --- a/test/requestidlecallback.js +++ b/test/requestidlecallback.js @@ -14,6 +14,6 @@ describe('requestIdleCallback', () => { expect(Object.keys(arg)).to.eql(['didTimeout', 'timeRemaining']) expect(arg).to.have.property('didTimeout').to.be.a('boolean') expect(arg).to.have.property('timeRemaining').to.be.a('function') - expect(arg.timeRemaining()).to.be.a('number').lessThan(50).greaterThanOrEqual(0) + expect(arg.timeRemaining()).to.be.a('number').lessThanOrEqual(50).greaterThanOrEqual(0) }) }) From 8e1691f2de5f3e74f93f5d404c2eaf20aa35ec87 Mon Sep 17 00:00:00 2001 From: Matthew Costabile Date: Thu, 17 Oct 2024 13:02:40 +0000 Subject: [PATCH 3/4] fix clipboard test --- test/navigator-clipboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/navigator-clipboard.js b/test/navigator-clipboard.js index e20754e..82641c1 100644 --- a/test/navigator-clipboard.js +++ b/test/navigator-clipboard.js @@ -16,7 +16,7 @@ describe('navigator clipboard', () => { expect(arr).to.have.lengthOf(1) expect(arr[0]).to.be.an.instanceof(globalThis.ClipboardItem) expect(arr[0].types).to.eql(['text/plain']) - expect(await arr[0].getType('text/plain')).to.eql('foo') + expect(await (await arr[0].getType('text/plain')).text()).to.eql('foo') }) }) From 3a29ef565943ed01aff0ffa7d3c64426c067d122 Mon Sep 17 00:00:00 2001 From: Matthew Costabile Date: Thu, 17 Oct 2024 13:21:06 +0000 Subject: [PATCH 4/4] use is supported check --- src/promise-withResolvers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/promise-withResolvers.ts b/src/promise-withResolvers.ts index 62d4252..04be228 100644 --- a/src/promise-withResolvers.ts +++ b/src/promise-withResolvers.ts @@ -24,7 +24,7 @@ export function isPolyfilled(): boolean { } export function apply(): void { - if (!('withResolvers' in Promise)) { + if (!isSupported()) { Object.assign(Promise, {withResolvers}) } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy