Skip to content

Commit

Permalink
Merge pull request #67 from github/polyfill-with-resolvers
Browse files Browse the repository at this point in the history
polyfill for Promise.withResolvers
  • Loading branch information
dgreif authored Oct 17, 2024
2 parents 9c5fd7d + 3a29ef5 commit ed36174
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -47,6 +48,7 @@ export const polyfills = {
elementCheckVisibility,
navigatorClipboard,
requestIdleCallback,
withResolvers,
}

export function isSupported() {
Expand Down
30 changes: 30 additions & 0 deletions src/promise-withResolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*#__PURE__*/
export function withResolvers<T>(this: PromiseConstructor) {
const out = {} as {
promise: Promise<T>
resolve: (value: T | PromiseLike<T>) => void
// eslint-disable-next-line @typescript-eslint/no-explicit-any
reject: (reason?: any) => void
}
out.promise = new Promise<T>((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 (!isSupported()) {
Object.assign(Promise, {withResolvers})
}
}
40 changes: 40 additions & 0 deletions test/promise-withResolvers.js
Original file line number Diff line number Diff line change
@@ -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)
}
})
})

0 comments on commit ed36174

Please sign in to comment.