diff --git a/src/index.ts b/src/index.ts index 414748e..8f1e950 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import * as cryptoRandomUUID from './crypto-randomuuid.js' import * as elementReplaceChildren from './element-replacechildren.js' import * as eventAbortSignal from './event-abortsignal.js' import * as objectHasOwn from './object-hasown.js' +import * as promiseAllSettled from './promise-allsettled.js' import * as promiseAny from './promise-any.js' import * as requestIdleCallback from './requestidlecallback.js' @@ -32,7 +33,7 @@ const baseSupport = 'flatMap' in Array.prototype && 'trimEnd' in String.prototype && // ES2020 - 'allSettled' in Promise && + //'allSettled' in Promise && // Polyfilled 'matchAll' in String.prototype && // ES2021 'replaceAll' in String.prototype && @@ -51,6 +52,7 @@ const polyfills = [ elementReplaceChildren, eventAbortSignal, objectHasOwn, + promiseAllSettled, promiseAny, requestIdleCallback ] diff --git a/src/promise-allsettled.ts b/src/promise-allsettled.ts new file mode 100644 index 0000000..ce05766 --- /dev/null +++ b/src/promise-allsettled.ts @@ -0,0 +1,29 @@ +export function promiseAllSettled( + values: T +): Promise<{-readonly [P in keyof T]: PromiseSettledResult>}> { + return Promise.all( + values.map(p => + // eslint-disable-next-line github/no-then + Promise.resolve(p).then( + (value: unknown) => ({status: 'fulfilled', value}), + (reason: unknown) => ({status: 'rejected', reason}) + ) + ) + ) as unknown as Promise<{-readonly [P in keyof T]: PromiseSettledResult>}> +} + +/*#__PURE__*/ +export function isSupported(): boolean { + return 'allSettled' in Promise && typeof Promise.allSettled === 'function' +} + +/*#__PURE__*/ +export function isPolyfilled(): boolean { + return Promise.all === promiseAllSettled +} + +export function apply(): void { + if (!isSupported()) { + Promise.allSettled = promiseAllSettled + } +} diff --git a/test/promise-allsettled.js b/test/promise-allsettled.js new file mode 100644 index 0000000..1e51b3f --- /dev/null +++ b/test/promise-allsettled.js @@ -0,0 +1,23 @@ +import {apply, isPolyfilled, isSupported, promiseAllSettled} from '../lib/promise-allsettled.js' + +describe('Promise.allSettled', () => { + 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('returns list of Promise value/rejections', async () => { + expect( + // eslint-disable-next-line prefer-promise-reject-errors + await promiseAllSettled([Promise.resolve(1), Promise.reject(2), Promise.resolve(3), Promise.reject(4)]) + ).to.eql([ + {status: 'fulfilled', value: 1}, + {status: 'rejected', reason: 2}, + {status: 'fulfilled', value: 3}, + {status: 'rejected', reason: 4} + ]) + }) +})