Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@thednp/event-listener

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@thednp/event-listener - npm Package Compare versions

Comparing version 1.0.4 to 2.0.0-alpha1

dist/index.cjs.js

62

package.json
{
"name": "@thednp/event-listener",
"author": "thednp",
"version": "1.0.4",
"version": "2.0.0alpha1",
"description": "Modern event listener for efficient web applications based on subscribe-publish pattern.",
"license": "MIT",
"homepage": "https://thednp.github.io/event-listener",
"main": "dist/event-listener.min.js",
"module": "dist/event-listener.esm.js",
"jsnext": "src/index.js",
"main": "src/index.ts",
"module": "dist/index.cjs.js",
"esnext": "src/index.js",
"types": "types/index.d.ts",

@@ -26,3 +26,4 @@ "repository": {

"listener",
"javascript-events"
"javascript-events",
"typescript"
],

@@ -39,30 +40,31 @@ "files": [

"scripts": {
"test": "cypress run",
"cypress": "npx cypress open",
"pre-test": "npm run clean-coverage && npx tsc",
"test": "npm run pre-test && cypress run",
"clean": "del-cli --force dist",
"clean-coverage": "del-cli --force coverage .nyc_output",
"cypress": "npm run pre-test && npx cypress open",
"coverage:report": "nyc report --reporter=lcov --reporter=json --reporter=text --reporter=json-summary",
"build": "npm run fix:js && npm-run-all --parallel build-*",
"custom-build": "rollup -c --environment",
"fix:js": "eslint src/ --config .eslintrc --fix",
"lint:js": "eslint src/ --config .eslintrc",
"build:ts": "tsc -d",
"build-js": "rollup --environment FORMAT:umd,MIN:false -c",
"build-docs": "rollup --environment FORMAT:umd,MIN:false,OUTPUTFILE:docs/event-listener.js -c",
"build-js-min": "rollup --environment FORMAT:umd,MIN:true -c",
"build-js-es5": "rollup --environment FORMAT:umd,MIN:false,ES5:true,OUTPUTFILE:dist/event-listener-es5.js -c",
"build-js-es5-min": "rollup --environment FORMAT:umd,MIN:true,ES5:true,OUTPUTFILE:dist/event-listener-es5.min.js -c",
"build-esm": "rollup --environment FORMAT:esm,MIN:false -c",
"build-esm-min": "rollup --environment FORMAT:esm,MIN:true -c"
"build": "npm run fix:ts && npm-run-all --parallel build-*",
"fix:ts": "eslint src/ --fix",
"lint:ts": "eslint src/",
"build:ts": "del-cli --force ./types && tsc -d --removeComments --emitDeclarationOnly --declarationMap --outDir ./types",
"build-js": "node esbuild.config.js FORMAT:iife",
"build-docs": "node esbuild.config.js FORMAT:iife OUTPUTFILE:docs/event-listener.js",
"build-minjs": "node esbuild.config.js MIN:true FORMAT:iife",
"build-esm": "node esbuild.config.js",
"build-minesm": "node esbuild.config.js MIN:true",
"build-mod": "node esbuild.config.js FORMAT:cjs",
"build-minmod": "node esbuild.config.js MIN:true FORMAT:cjs"
},
"devDependencies": {
"@bahmutov/cypress-esbuild-preprocessor": "^2.1.3",
"@cypress/code-coverage": "^3.9.12",
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^7.1.0",
"@rollup/plugin-typescript": "^8.3.0",
"cypress": "^9.6.0",
"@cypress/code-coverage": "^3.10.0",
"@types/istanbul-lib-instrument": "^1.7.4",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"cypress": "^10.3.1",
"del-cli": "^5.0.0",
"esbuild": "^0.14.30",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint": "^8.20.0",
"eslint-plugin-prettier": "^4.2.1",
"istanbul-lib-coverage": "^3.2.0",

@@ -72,6 +74,4 @@ "istanbul-lib-instrument": "^5.2.0",

"nyc": "^15.1.0",
"rollup": "^2.38.5",
"rollup-plugin-terser": "^5.3.1",
"typescript": "^4.5.2"
"typescript": "^4.7.4"
}
}

@@ -1,21 +0,24 @@

# EventListener [![Coverage Status](https://coveralls.io/repos/github/thednp/event-listener/badge.svg?branch=main)](https://coveralls.io/github/thednp/event-listener?branch=main) ![cypress version](https://img.shields.io/badge/cypress-9.6.0-brightgreen) ![typescript version](https://img.shields.io/badge/typescript-4.5.2-brightgreen) [![ci](https://github.com/thednp/event-listener/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/thednp/event-listener/actions/workflows/ci.yml)
## EventListener
Modern event listener for efficient applications based on the [subscribe-publish](https://hackernoon.com/do-you-still-register-window-event-listeners-in-each-component-react-in-example-31a4b1f6f1c8) pattern.
[![Coverage Status](https://coveralls.io/repos/github/thednp/event-listener/badge.svg)](https://coveralls.io/github/thednp/event-listener)
[![ci](https://github.com/thednp/event-listener/actions/workflows/ci.yml/badge.svg)](https://github.com/thednp/event-listener/actions/workflows/ci.yml)
[![NPM Version](https://img.shields.io/npm/v/@thednp/event-listener.svg)](https://www.npmjs.com/package/@thednp/event-listener)
[![NPM Downloads](https://img.shields.io/npm/dm/@thednp/event-listener.svg)](http://npm-stat.com/charts.html?package=@thednp/event-listener)
[![jsDeliver](https://img.shields.io/jsdelivr/npm/hw/@thednp/event-listener)](https://www.jsdelivr.com/package/npm/@thednp/event-listener)
[![cypress version](https://img.shields.io/badge/cypress-10.3.1-brightgreen)](https://cypress.io/)
[![typescript version](https://img.shields.io/badge/typescript-4.7.4-brightgreen)](https://www.typescriptlang.org/)
[![esbuild version](https://img.shields.io/badge/esbuild-0.14.30-brightgreen)](https://esbuild.github.io/)
**EventListener** is less than 900 bytes when minified, but packs a surprising amount of power.
A TypeScript sourced event listener for efficient applications based on the [subscribe-publish](https://hackernoon.com/do-you-still-register-window-event-listeners-in-each-component-react-in-example-31a4b1f6f1c8) pattern, less than 900 bytes when minified and packs a surprising amount of power.
[![NPM Version](https://img.shields.io/npm/v/@thednp/event-listener.svg?style=flat-square)](https://www.npmjs.com/package/@thednp/event-listener)
[![NPM Downloads](https://img.shields.io/npm/dm/@thednp/event-listener.svg?style=flat-square)](http://npm-stat.com/charts.html?package=@thednp/event-listener)
[![jsDeliver](https://data.jsdelivr.com/v1/package/npm/@thednp/event-listener/badge)](https://www.jsdelivr.com/package/npm/@thednp/event-listener)
## Features
- **EventListener** is TypeScript sourced;
- **EventListener** makes use of the native [Map](https://caniuse.com/mdn-javascript_builtins_map) to subscribe/register or unsubscribe/remove listeners, which is perfect since we need to make sure the exact listeners are added/removed; this completely invalidates the need to [deconstruct function objects](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) for comparison's sake to make sure event listeners are properly handled;
- **EventListener** allows you to register multiple listeners for the same target, even of the same type, but always uses a single `globalListener` to call them all at once when event is triggered;
- **EventListener** "should" be able to manage event options, especially `once`, meaning that when the option is `true`, the listener is automatically un-subscribed and detached from target;
- **EventListener** will unsubscribe and detach listeners with the same options used when attached, which means you can "lazy" remove listeners on the fly.
# Features
* **EventListener** is ES6+ sourced with TypeScript definitions;
* **EventListener** comes with ES6, ES5 and ESM packaging, all in `/dist` folder;
* **EventListener** makes use of the native [Map](https://caniuse.com/mdn-javascript_builtins_map) to subscribe/register or unsubscribe/remove listeners, which is perfect since we need to make sure the exact listeners are added/removed; this completely invalidates the need to [deconstruct function objects](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) for comparison's sake to make sure event listeners are properly handled;
* **EventListener** allows you to register multiple listeners for the same target, even of the same type, but always uses a single `globalListener` to call them all at once when event is triggered;
* **EventListener** "should" be able to manage event options, especially `once`, meaning that when the option is `true`, the listener is automatically un-subscribed and detached from target;
* **EventListener** will unsubscribe and detach listeners with the same options used when attached, which means you can "lazy" remove listeners on the fly.
# NPM
# NPM
```

@@ -25,38 +28,45 @@ npm install @thednp/event-listener

# CDN
## CDN
```html
<script src="https://cdn.jsdelivr.net/npm/@thednp/event-listener/dist/event-listener.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@thednp/event-listener/dist/index.min.js"></script>
```
# Use
## Use
```js
import EventListener from '@thednp/event-listener';
import Listener from "@thednp/event-listener";
// execute a listener once
EventListener.on(document, 'DOMContentLoaded', () => {
console.log('document is now loaded');
}, { once: true });
Listener.on(
document,
"DOMContentLoaded",
() => {
console.log("document is now loaded");
},
{ once: true }
);
// add a listener with `useCapture: false`
function handleMyClick(e) {
if (e.target.tagName === 'button') {
if (e.target.tagName === "button") {
e.preventDefault();
e.stopImmediatePropagation();
}
console.log('do something else instead');
console.log("do something else instead");
}
EventListener.on(document, 'click', handleMyClick, false);
Listener.on(document, "click", handleMyClick, false);
// remove a listener, `EventListener` will get listener options from registry
EventListener.off(document, 'click', handleMyClick);
Listener.off(document, "click", handleMyClick);
// add listener to `window`, this listener has no name and cannot be removed
EventListener.on(window, 'scroll', () => console.log(window.scrollY));
Listener.on(window, "scroll", () => console.log(window.scrollY));
```
Since we're implementing `Map`, you can make use of its prototype to access registry:
```js
// get element listener registry
const documentClickListeners = EventListener.registry['click'].get(document);
const documentClickListeners = Listener.registry['click'].get(document);

@@ -86,7 +96,8 @@ // returns

# Advanced Use
## Advanced Use
You can also make use of "tree shaking" to import only the module you want, for instance:
```js
import { on } from '@thednp/event-listener';
import { on } from "@thednp/event-listener";

@@ -99,3 +110,3 @@ on(document, handleMyClick, true);

```js
import { addListener } from '@thednp/event-listener/src/event-listener';
import { addListener } from "@thednp/event-listener/src/event-listener";

@@ -107,3 +118,12 @@ addListener(document, handleMyClick, true);

# License
**EventListener** is released under the [MIT License](https://github.com/thednp/event-listener/blob/main/LICENSE).
## Run the tests suite (new)
- [Download](https://github.com/thednp/event-listener/archive/refs/heads/master.zip) the package from Github;
- unpack/unzip and open the folder with your editor;
- open your terminal and navigate to the root of the unpacked folder;
- run `npm install` or `npm update`, takes a few minutes to download the Electron browser;
- run `npm run cypress` to open the Cypress console OR `npm run test` to run the tests in headless mode.
## License
**EventListener** is released under the [MIT License](https://github.com/thednp/event-listener/blob/main/LICENSE).

@@ -1,3 +0,56 @@

import Listener from './event-listener';
const EventRegistry = {};
export { EventRegistry };
export function globalListener(e) {
const that = this;
const { type } = e;
[...EventRegistry[type]].forEach((elementsMap) => {
const [element, listenersMap] = elementsMap;
if (element === that) {
[...listenersMap].forEach((listenerMap) => {
const [listener, options] = listenerMap;
listener.apply(element, [e]);
if (options && options.once) {
removeListener(element, type, listener, options);
}
});
}
});
}
export const addListener = (element, eventType, listener, options) => {
if (!EventRegistry[eventType]) {
EventRegistry[eventType] = new Map();
}
const oneEventMap = EventRegistry[eventType];
if (!oneEventMap.has(element)) {
oneEventMap.set(element, new Map());
}
const oneElementMap = oneEventMap.get(element);
const { size } = oneElementMap;
oneElementMap.set(listener, options);
if (!size) {
element.addEventListener(eventType, globalListener, options);
}
};
export const removeListener = (element, eventType, listener, options) => {
const oneEventMap = EventRegistry[eventType];
const oneElementMap = oneEventMap && oneEventMap.get(element);
const savedOptions = oneElementMap && oneElementMap.get(listener);
const eventOptions = savedOptions !== undefined ? savedOptions : options;
if (oneElementMap && oneElementMap.has(listener))
oneElementMap.delete(listener);
if (oneEventMap && (!oneElementMap || !oneElementMap.size))
oneEventMap.delete(element);
if (!oneEventMap || !oneEventMap.size)
delete EventRegistry[eventType];
if (!oneElementMap || !oneElementMap.size) {
element.removeEventListener(eventType, globalListener, eventOptions);
}
};
const Listener = {
on: addListener,
off: removeListener,
globalListener,
registry: EventRegistry,
};
export default Listener;
//# sourceMappingURL=index.js.map

@@ -1,18 +0,14 @@

export as namespace Listener;
import { EventsRegistry } from "./types";
declare const EventRegistry: EventsRegistry;
export { EventRegistry };
export declare function globalListener(e: Event): void;
export declare const addListener: (element: EventTarget, eventType: string, listener: EventListenerObject["handleEvent"], options?: AddEventListenerOptions) => void;
export declare const removeListener: (element: EventTarget, eventType: string, listener: EventListenerObject["handleEvent"], options?: AddEventListenerOptions) => void;
declare const Listener: {
on: (element: EventTarget, eventType: string, listener: EventListenerObject["handleEvent"], options?: AddEventListenerOptions) => void;
off: (element: EventTarget, eventType: string, listener: EventListenerObject["handleEvent"], options?: AddEventListenerOptions) => void;
globalListener: typeof globalListener;
registry: EventsRegistry;
};
export default Listener;
import './event-listener';
export type ListenerAction<T> = (
element: T,
eventType: string,
listener: EventListenerObject['handleEvent'],
options?: AddEventListenerOptions
) => void;
import { default as Listener } from 'event-listener/src/event-listener';
export { EventRegistry, globalListener, addListener, removeListener } from "event-listener/src/event-listener";
declare module "@thednp/event-listener" {
export default Listener;
}
//# sourceMappingURL=index.d.ts.map
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc