From 9502102b265945b37ee38b276ec1533fae0f308f Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 20 Sep 2022 14:38:47 +0300 Subject: [PATCH] New Ponyfill package for Event API --- .changeset/famous-rice-hunt.md | 5 + .changeset/poor-baboons-cheer.md | 5 + packages/events/.gitignore | 1 + packages/events/dist/deno-ponyfill.ts | 3 + packages/events/dist/global-ponyfill.js | 3 + packages/events/dist/index.d.ts | 11 +++ packages/events/dist/node-ponyfill.js | 101 ++++++++++++++++++++ packages/events/package.json | 23 +++++ packages/fetch/dist/create-node-ponyfill.js | 7 -- packages/fetch/dist/deno-ponyfill.ts | 6 +- packages/fetch/dist/global-ponyfill.js | 2 - packages/fetch/dist/index.d.ts | 8 +- packages/fetch/dist/node-ponyfill.js | 2 - packages/fetch/package.json | 1 - 14 files changed, 154 insertions(+), 24 deletions(-) create mode 100644 .changeset/famous-rice-hunt.md create mode 100644 .changeset/poor-baboons-cheer.md create mode 100644 packages/events/.gitignore create mode 100644 packages/events/dist/deno-ponyfill.ts create mode 100644 packages/events/dist/global-ponyfill.js create mode 100644 packages/events/dist/index.d.ts create mode 100644 packages/events/dist/node-ponyfill.js create mode 100644 packages/events/package.json diff --git a/.changeset/famous-rice-hunt.md b/.changeset/famous-rice-hunt.md new file mode 100644 index 0000000000..f12d4a888f --- /dev/null +++ b/.changeset/famous-rice-hunt.md @@ -0,0 +1,5 @@ +--- +'@whatwg-node/fetch': patch +--- + +Breaking Change: Event API is no longer available in this ponyfill; use @whatwg-node/events instead. diff --git a/.changeset/poor-baboons-cheer.md b/.changeset/poor-baboons-cheer.md new file mode 100644 index 0000000000..bc6665d730 --- /dev/null +++ b/.changeset/poor-baboons-cheer.md @@ -0,0 +1,5 @@ +--- +'@whatwg-node/events': patch +--- + +New Event API ponyfill diff --git a/packages/events/.gitignore b/packages/events/.gitignore new file mode 100644 index 0000000000..cbdb9611d1 --- /dev/null +++ b/packages/events/.gitignore @@ -0,0 +1 @@ +!dist diff --git a/packages/events/dist/deno-ponyfill.ts b/packages/events/dist/deno-ponyfill.ts new file mode 100644 index 0000000000..ccb92d6a8c --- /dev/null +++ b/packages/events/dist/deno-ponyfill.ts @@ -0,0 +1,3 @@ +export const Event = globalThis.Event; +export const EventTarget = globalThis.EventTarget; +export const CustomEvent = globalThis.CustomEvent; diff --git a/packages/events/dist/global-ponyfill.js b/packages/events/dist/global-ponyfill.js new file mode 100644 index 0000000000..96f3b6b810 --- /dev/null +++ b/packages/events/dist/global-ponyfill.js @@ -0,0 +1,3 @@ +module.exports.Event = globalThis.Event; +module.exports.EventTarget = globalThis.EventTarget; +module.exports.CustomEvent = globalThis.CustomEvent; \ No newline at end of file diff --git a/packages/events/dist/index.d.ts b/packages/events/dist/index.d.ts new file mode 100644 index 0000000000..8db6715e7e --- /dev/null +++ b/packages/events/dist/index.d.ts @@ -0,0 +1,11 @@ +/// + +declare const _Event: typeof Event; +declare const _EventTarget: typeof EventTarget; +declare const _CustomEvent: typeof CustomEvent; + +declare module "@whatwg-node/events" { + export const Event: typeof _Event; + export const EventTarget: typeof _EventTarget; + export const CustomEvent: typeof _CustomEvent; +} diff --git a/packages/events/dist/node-ponyfill.js b/packages/events/dist/node-ponyfill.js new file mode 100644 index 0000000000..5b066d5414 --- /dev/null +++ b/packages/events/dist/node-ponyfill.js @@ -0,0 +1,101 @@ +module.exports.Event = globalThis.Event; +if (!module.exports.Event) { + module.exports.Event = class Event { + constructor(type, options) { + this.bubbles = !!options && !!options.bubbles; + this.cancelable = !!options && !!options.cancelable; + this.composed = !!options && !!options.composed; + this.type = type; + } + } +} + +module.exports.EventTarget = globalThis.EventTarget; +if (!module.exports.EventTarget) { + module.exports.EventTarget = class EventTarget { + constructor() { + this.__listeners = new Map(); + } + addEventListener(type, listener, options) { if (arguments.length < 2) { + throw new TypeError( + `TypeError: Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only ${arguments.length} present.` + ); + } + const __listeners = this.__listeners; + const actualType = type.toString(); + if (!__listeners.has(actualType)) { + __listeners.set(actualType, new Map()); + } + const listenersForType = __listeners.get(actualType); + if (!listenersForType.has(listener)) { + // Any given listener is only registered once + listenersForType.set(listener, options); + } + } + removeEventListener(type, listener, _options) { + if (arguments.length < 2) { + throw new TypeError( + `TypeError: Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only ${arguments.length} present.` + ); + } + const __listeners = this.__listeners; + const actualType = type.toString(); + if (__listeners.has(actualType)) { + const listenersForType = __listeners.get(actualType); + if (listenersForType.has(listener)) { + listenersForType.delete(listener); + } + } + } + dispatchEvent(event) { + if (!(event instanceof Event)) { + throw new TypeError( + `Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'.` + ); + } + const type = event.type; + const __listeners = this.__listeners; + const listenersForType = __listeners.get(type); + if (listenersForType) { + for (const [listener, options] of listenersForType.entries()) { + try { + if (typeof listener === "function") { + // Listener functions must be executed with the EventTarget as the `this` context. + listener.call(this, event); + } else if (listener && typeof listener.handleEvent === "function") { + // Listener objects have their handleEvent method called, if they have one + listener.handleEvent(event); + } + } catch (err) { + // We need to report the error to the global error handling event, + // but we do not want to break the loop that is executing the events. + // Unfortunately, this is the best we can do, which isn't great, because the + // native EventTarget will actually do this synchronously before moving to the next + // event in the loop. + setTimeout(() => { + throw err; + }); + } + if (options && options.once) { + // If this was registered with { once: true }, we need + // to remove it now. + listenersForType.delete(listener); + } + } + } + // Since there are no cancellable events on a base EventTarget, + // this should always return true. + return true; + } + } +} + +module.exports.CustomEvent = globalThis.CustomEvent; +if (!module.exports.CustomEvent) { + module.exports.CustomEvent = class CustomEvent extends module.exports.Event { + constructor(type, options) { + super(type, options); + this.detail = options && options.detail; + } + } +} \ No newline at end of file diff --git a/packages/events/package.json b/packages/events/package.json new file mode 100644 index 0000000000..672b4a6003 --- /dev/null +++ b/packages/events/package.json @@ -0,0 +1,23 @@ +{ + "name": "@whatwg-node/events", + "version": "0.0.0", + "description": "Cross Platform Smart Event API Ponyfill", + "author": "Arda TANRIKULU ", + "repository": { + "type": "git", + "url": "ardatan/whatwg-node", + "directory": "packages/events" + }, + "license": "MIT", + "sideEffects": false, + "main": "dist/node-ponyfill.js", + "browser": "dist/global-ponyfill.js", + "react-native": "dist/global-ponyfill.js", + "types": "dist/index.d.ts", + "denoify": { + "index": "dist/deno-ponyfill.ts" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/fetch/dist/create-node-ponyfill.js b/packages/fetch/dist/create-node-ponyfill.js index a8cefd2009..860e4a1ec3 100644 --- a/packages/fetch/dist/create-node-ponyfill.js +++ b/packages/fetch/dist/create-node-ponyfill.js @@ -25,13 +25,6 @@ module.exports = function createNodePonyfill(opts = {}) { ponyfills.Blob = globalThis.Blob; ponyfills.crypto = globalThis.crypto; - if (!globalThis.Event || !globalThis.EventTarget) { - require('event-target-polyfill'); - } - - ponyfills.Event = globalThis.Event; - ponyfills.EventTarget = globalThis.EventTarget; - if (!ponyfills.AbortController) { const abortControllerModule = require("abort-controller"); ponyfills.AbortController = diff --git a/packages/fetch/dist/deno-ponyfill.ts b/packages/fetch/dist/deno-ponyfill.ts index 6afe65c550..fb3a7ff231 100644 --- a/packages/fetch/dist/deno-ponyfill.ts +++ b/packages/fetch/dist/deno-ponyfill.ts @@ -13,10 +13,8 @@ const crypto = globalThis.crypto; const btoa = globalThis.btoa; const TextDecoder = globalThis.TextDecoder; const TextEncoder = globalThis.TextEncoder; -const Event = globalThis.Event; -const EventTarget = globalThis.EventTarget; -export const create = () => globalThis; +export const createFetch = () => globalThis; export { fetch, Headers, @@ -33,6 +31,4 @@ export { btoa, TextDecoder, TextEncoder, - Event, - EventTarget, }; diff --git a/packages/fetch/dist/global-ponyfill.js b/packages/fetch/dist/global-ponyfill.js index 68845b3c93..ab2097f450 100644 --- a/packages/fetch/dist/global-ponyfill.js +++ b/packages/fetch/dist/global-ponyfill.js @@ -13,6 +13,4 @@ module.exports.crypto = globalThis.crypto; module.exports.btoa = globalThis.btoa; module.exports.TextEncoder = globalThis.TextEncoder; module.exports.TextDecoder = globalThis.TextDecoder; -module.exports.Event = globalThis.Event; -module.exports.EventTarget = globalThis.EventTarget; module.exports.createFetch = () => globalThis; diff --git a/packages/fetch/dist/index.d.ts b/packages/fetch/dist/index.d.ts index a1df4f89ee..fb4bc46869 100644 --- a/packages/fetch/dist/index.d.ts +++ b/packages/fetch/dist/index.d.ts @@ -15,8 +15,6 @@ declare const _crypto: typeof crypto; declare const _btoa: typeof btoa; declare const _TextEncoder: typeof TextEncoder; declare const _TextDecoder: typeof TextDecoder; -declare const _Event: typeof Event; -declare const _EventTarget: typeof EventTarget; declare module "@whatwg-node/fetch" { export const fetch: typeof _fetch; @@ -34,8 +32,6 @@ declare module "@whatwg-node/fetch" { export const btoa: typeof _btoa; export const TextDecoder: typeof _TextDecoder; export const TextEncoder: typeof _TextEncoder; - export const Event: typeof _Event; - export const EventTarget: typeof _EventTarget; export interface FormDataLimits { /* Max field name size (in bytes). Default: 100. */ fieldNameSize?: number; @@ -69,9 +65,7 @@ declare module "@whatwg-node/fetch" { crypto: typeof _crypto, btoa: typeof _btoa, TextEncoder: typeof _TextEncoder, - TextDecoder: typeof _TextDecoder, - Event: typeof _Event, - EventTarget: typeof _EventTarget + TextDecoder: typeof _TextDecoder }); } diff --git a/packages/fetch/dist/node-ponyfill.js b/packages/fetch/dist/node-ponyfill.js index 715c8168c8..33481fe79a 100644 --- a/packages/fetch/dist/node-ponyfill.js +++ b/packages/fetch/dist/node-ponyfill.js @@ -17,7 +17,5 @@ module.exports.crypto = ponyfills.crypto; module.exports.btoa = ponyfills.btoa; module.exports.TextEncoder = ponyfills.TextEncoder; module.exports.TextDecoder = ponyfills.TextDecoder; -module.exports.Event = ponyfills.Event; -module.exports.EventTarget = ponyfills.EventTarget; exports.createFetch = createNodePonyfill; diff --git a/packages/fetch/package.json b/packages/fetch/package.json index 7e45106080..fe7bab263c 100644 --- a/packages/fetch/package.json +++ b/packages/fetch/package.json @@ -21,7 +21,6 @@ "@peculiar/webcrypto": "^1.4.0", "abort-controller": "^3.0.0", "busboy": "^1.6.0", - "event-target-polyfill": "^0.0.3", "form-data-encoder": "^1.7.1", "formdata-node": "^4.3.1", "node-fetch": "^2.6.7",