Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
dom-events-wintercg
Advanced tools
An polyfill for DOM Events and related APIs, extracted from Node.js, for use in WinterCG runtimes
A polyfill for DOM Events and related APIs:
Implementation extracted from the Node.js codebase as of 10th March 2024 (version 21.7.1
, I believe). Some simplified internals extracted from readable-stream.
To clarify, this project is not affiliated with WinterCG (i.e. is not an official work). It merely implements part of the WinterCG Common Minimum API proposal.
Install this npm package as follows, depending on which package manager you're using.
npm:
npm install --save dom-events-wintercg
Yarn:
yarn add dom-events-wintercg
pnpm:
pnpm add dom-events-wintercg
Bun:
bun add dom-events-wintercg
Deno: No need to install. Just add the npm: specifier when importing.
Run this polyfill in your app's entrypoint file so that it fills in the APIs as early as possible in the app lifecycle.
import { polyfill } from 'dom-events-wintercg';
polyfill(globalThis);
// All implemented APIs will now be available in global scope
const eventTarget = new EventTarget();
const event = new Event('click', {});
eventTarget.addEventListener('click', (event) => {
console.log(`Fired "${event.type}" event!`, event);
});
eventTarget.dispatchEvent(event, 'abc');
And for TypeScript typings, add the DOM
lib in tsconfig.json
:
{
"compilerOptions": {
"lib": ["DOM"],
// ...
}
}
Here, we import from the npm package each time we want to use an API, rather than polyfilling globally.
import { Event, EventTarget } from 'dom-events-wintercg';
const eventTarget = new EventTarget();
const event = new Event('click', {});
eventTarget.addEventListener('click', (event) => {
console.log(`Fired "${event.type}" event!`, event);
});
eventTarget.dispatchEvent(event, 'abc');
Some limited TypeScript typings will be inferred from the library's JavaScript source code, but if you'd rather use the lib.dom.d.ts
typings built into TypeScript (which I would recommend), then:
Add the DOM
lib in tsconfig.json
:
{
"compilerOptions": {
"lib": ["DOM"],
// ...
}
}
Do this little dance:
import {
Event as EventImpl,
EventTarget as EventTargetImpl,
} from 'dom-events-wintercg';
// Redeclare the implementation using the types from lib.dom.d.ts
const Event = EventImpl as unknown as Event;
const EventTarget = EventTargetImpl as unknown as EventTarget;
const eventTarget = new EventTarget();
const event = new Event('click', {});
eventTarget.addEventListener('click', (event) => {
console.log(`Fired "${event.type}" event!`, event);
});
eventTarget.dispatchEvent(event, 'abc');
This is my best-effort attempt to document usage with a bundler. These instructions are untested, so please open a PR if you find they need tweaking!
In all cases, you can set up TypeScript typings via adding the DOM
lib to your tsconfig.json
:
{
"compilerOptions": {
"lib": ["DOM"],
// ...
}
}
Below, I'll describe for each bundler how to integrate this package into your bundle.
This configuration ensures that all the implemented APIs are available from global scope:
const webpackConfig = {
plugins: [
new webpack.ProvidePlugin({
AbortController: ['dom-events-wintercg', 'AbortController'],
AbortSignal: ['dom-events-wintercg', 'AbortSignal'],
CustomEvent: ['dom-events-wintercg', 'CustomEvent'],
DOMException: ['dom-events-wintercg', 'DOMException'],
Event: ['dom-events-wintercg', 'Event'],
EventTarget: ['dom-events-wintercg', 'EventTarget'],
}),
],
};
Additionally, you can polyfill some of the Node.js events module (e.g. to use a Node.js library in a browser app) as follows. ⚠️ Be warned that while this package implements CustomEvent
, Event
, and EventTarget
, it does not implement all the APIs in the Node.js events
module. For example, it does not implement EventEmitter
.
const webpackConfig = {
+ resolve: {
+ fallback: {
+ events: require.resolve('dom-events-wintercg'),
+ },
+ },
plugins: [
new webpack.ProvidePlugin({
AbortController: ['dom-events-wintercg', 'AbortController'],
AbortSignal: ['dom-events-wintercg', 'AbortSignal'],
CustomEvent: ['dom-events-wintercg', 'CustomEvent'],
DOMException: ['dom-events-wintercg', 'DOMException'],
Event: ['dom-events-wintercg', 'Event'],
EventTarget: ['dom-events-wintercg', 'EventTarget'],
}),
],
};
This polyfill relies on a few language features.
Your JS engine/runtime must support the following APIs (this is a non-exhaustive list):
import
and export
)Some of the features of this polyfill are optional, and will fail gracefully if your JS engine/runtime lacks support for the underlying APIs.
AbortSignal.timeout()
AbortSignal.timeout() support requires the following APIs:
If missing, AbortSignal.timeout()
will throw an Error with code ERR_METHOD_NOT_IMPLEMENTED
when called.
Beyond the differences explained in the Node.js SDK docs, see this excellent article from NearForm about how they first brought EventTarget to Node.js, which covers some of the compromises they had to make in the implementation. In particular, there is no concept of bubbling or capturing, and event.preventDefault()
is a bit useless, as it never has a "default action" to prevent.
This library, being runtime-agnostic, does nothing to keep the event loop alive for Worker event listeners. See the Node.js internals for how they implemented that.
FAQs
An polyfill for DOM Events and related APIs, extracted from Node.js, for use in WinterCG runtimes
We found that dom-events-wintercg demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.