@thednp/event-listener
Advanced tools
Comparing version 2.0.0-alpha3 to 2.0.0-alpha4
@@ -1,69 +0,2 @@ | ||
/*! | ||
* Listener v2.0.0alpha3 (https://thednp.github.io/event-listener) | ||
* Copyright 2022 © thednp | ||
* Licensed under MIT (https://thednp.github.io/event-listener/blob/main/LICENSE) | ||
*/ | ||
// src/index.ts | ||
var EventRegistry = {}; | ||
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); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var addListener = (element, eventType, listener, options) => { | ||
if (!EventRegistry[eventType]) { | ||
EventRegistry[eventType] = /* @__PURE__ */ new Map(); | ||
} | ||
const oneEventMap = EventRegistry[eventType]; | ||
if (!oneEventMap.has(element)) { | ||
oneEventMap.set(element, /* @__PURE__ */ new Map()); | ||
} | ||
const oneElementMap = oneEventMap.get(element); | ||
if (typeof oneElementMap === "undefined") | ||
return; | ||
const { size } = oneElementMap; | ||
oneElementMap.set(listener, options); | ||
if (!size) { | ||
element.addEventListener(eventType, globalListener, options); | ||
} | ||
}; | ||
var removeListener = (element, eventType, listener, options) => { | ||
const oneEventMap = EventRegistry[eventType]; | ||
const oneElementMap = oneEventMap && oneEventMap.get(element); | ||
const savedOptions = oneElementMap && oneElementMap.get(listener); | ||
const eventOptions = savedOptions !== void 0 ? 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); | ||
} | ||
}; | ||
var src_default = { | ||
on: addListener, | ||
off: removeListener, | ||
globalListener, | ||
registry: EventRegistry | ||
}; | ||
export { | ||
EventRegistry, | ||
addListener, | ||
src_default as default, | ||
globalListener, | ||
removeListener | ||
}; | ||
var Listener=function(){"use strict";const e={},f=n=>{const{type:o,target:i,currentTarget:a}=n;[...e[o]].forEach(([t,s])=>{[a,i].includes(t)&&[...s].forEach(([c,r])=>{c.apply(t,[n]),typeof r=="object"&&r.once&&d(t,o,c,r)})})},g=(n,o,i,a)=>{e[o]||(e[o]=new Map);const t=e[o];t.has(n)||t.set(n,new Map);const s=t.get(n),{size:c}=s;s.set(i,a),c||n.addEventListener(o,f,a)},d=(n,o,i,a)=>{const t=e[o],s=t&&t.get(n),c=s&&s.get(i),r=c!==void 0?c:a;s&&s.has(i)&&s.delete(i),t&&(!s||!s.size)&&t.delete(n),(!t||!t.size)&&delete e[o],(!s||!s.size)&&n.removeEventListener(o,f,r)};return{on:g,off:d,globalListener:f,registry:e}}(); | ||
//# sourceMappingURL=event-listener.js.map |
{ | ||
"name": "@thednp/event-listener", | ||
"author": "thednp", | ||
"version": "2.0.0alpha3", | ||
"version": "2.0.0alpha4", | ||
"description": "Modern event listener for efficient web applications based on subscribe-publish pattern.", | ||
"license": "MIT", | ||
"homepage": "https://thednp.github.io/event-listener", | ||
"main": "src/index.ts", | ||
"module": "dist/event-listener.cjs.js", | ||
"esmodule": "dist/event-listener.js", | ||
"esnext": "src/index.js", | ||
"types": "types/index.d.ts", | ||
"source": "src/index.ts", | ||
"main": "dist/event-listener.js", | ||
"module": "dist/event-listener.mjs", | ||
"types": "dist/event-listener.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/event-listener.mjs", | ||
"require": "./dist/event-listener.cjs", | ||
"types": "./dist/event-listener.d.ts" | ||
} | ||
}, | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"repository": { | ||
@@ -30,7 +40,2 @@ "type": "git", | ||
], | ||
"files": [ | ||
"dist", | ||
"src", | ||
"types" | ||
], | ||
"publishConfig": { | ||
@@ -41,17 +46,13 @@ "access": "public", | ||
"scripts": { | ||
"pre-test": "npm run clean-coverage && npx tsc", | ||
"pre-test": "npm run clean-coverage", | ||
"test": "npm run pre-test && cypress run", | ||
"clean": "del-cli --force dist", | ||
"clean-coverage": "del-cli --force coverage .nyc_output", | ||
"clean": "rimraf dist", | ||
"clean-coverage": "rimraf coverage .nyc_output", | ||
"cypress": "npm run pre-test && npx cypress open", | ||
"coverage:report": "nyc report --reporter=lcov --reporter=json --reporter=text --reporter=json-summary", | ||
"fix:ts": "eslint src/ --fix", | ||
"lint:ts": "eslint src/", | ||
"build:ts": "del-cli --force ./types && tsc -d --removeComments --emitDeclarationOnly --declarationMap --outDir ./types", | ||
"build": "del-cli --force dist && npm run fix:ts && npm-run-all --parallel build-*", | ||
"build-docs": "node esbuild.config.js FORMAT:iife OUTPUTFILE:docs/event-listener.js", | ||
"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" | ||
"format": "prettier --write \"src/**/*.ts\"", | ||
"lint:ts": "eslint -c .eslintrc.js --ext .ts src", | ||
"fix:ts": "eslint -c .eslintrc.js --ext .ts src --fix", | ||
"build": "npm run clean && npm run lint:ts && vite build && npm run docs && dts-bundle-generator --config ./dts.config.ts", | ||
"docs": "ncp dist/event-listener.js docs/event-listener.js && ncp dist/event-listener.js.map docs/event-listener.js.map" | ||
}, | ||
@@ -62,15 +63,20 @@ "devDependencies": { | ||
"@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", | ||
"@typescript-eslint/eslint-plugin": "^5.35.1", | ||
"@typescript-eslint/parser": "^5.35.1", | ||
"cypress": "^10.6.0", | ||
"dts-bundle-generator": "^6.12.0", | ||
"esbuild": "^0.14.30", | ||
"eslint": "^8.20.0", | ||
"eslint": "^8.23.0", | ||
"eslint-plugin-jsdoc": "^39.3.6", | ||
"eslint-plugin-prefer-arrow": "^1.2.3", | ||
"eslint-plugin-prettier": "^4.2.1", | ||
"istanbul-lib-coverage": "^3.2.0", | ||
"istanbul-lib-instrument": "^5.2.0", | ||
"ncp": "^2.0.0", | ||
"npm-run-all": "^4.1.5", | ||
"nyc": "^15.1.0", | ||
"typescript": "^4.7.4" | ||
"rimraf": "^3.0.2", | ||
"typescript": "^4.7.4", | ||
"vite": "^3.0.9" | ||
} | ||
} |
@@ -8,5 +8,7 @@ ## EventListener | ||
[![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/) | ||
[![cypress version](https://img.shields.io/badge/cypress-10.6.0-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/) | ||
[![eslint version](https://img.shields.io/badge/eslint-8.23.0-brightgreen)](https://github.com/eslint) | ||
[![vite version](https://img.shields.io/badge/vite-3.0.9-brightgreen)](https://github.com/vitejs) | ||
@@ -32,3 +34,3 @@ 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. | ||
```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/event-listener.js"></script> | ||
``` | ||
@@ -42,9 +44,6 @@ | ||
// execute a listener once | ||
Listener.on( | ||
document, | ||
'DOMContentLoaded', | ||
() => { | ||
Listener.on(document, 'DOMContentLoaded', () => { | ||
console.log('document is now loaded'); | ||
}, | ||
{ once: true } | ||
{ once: true }, | ||
); | ||
@@ -93,3 +92,3 @@ | ||
// get listener options | ||
const myListenerOptions = documentClickListeners && documentClickListeners.get(handleMyClick)); | ||
const myListenerOptions = documentClickListeners && documentClickListeners.get(handleMyClick); | ||
@@ -109,10 +108,2 @@ // returns false, which is the `useCapture` option value added for `handleMyClick` | ||
Same applies to: | ||
```js | ||
import { addListener } from '@thednp/event-listener/src/event-listener'; | ||
addListener(document, handleMyClick, true); | ||
``` | ||
For more advanced use, check out the [demo](https://thednp.github.io/event-listener), showcasing the **EventListener** usage with a demo component. | ||
@@ -119,0 +110,0 @@ |
@@ -1,24 +0,27 @@ | ||
import { EventsRegistry } from './types'; | ||
/** | ||
* Advanced event listener based on subscribe / publish pattern. | ||
* | ||
* @see https://www.patterns.dev/posts/classic-design-patterns/#observerpatternjavascript | ||
* @see https://gist.github.com/shystruk/d16c0ee7ac7d194da9644e5d740c8338#file-subpub-js | ||
* @see https://hackernoon.com/do-you-still-register-window-event-listeners-in-each-component-react-in-example-31a4b1f6f1c8 | ||
*/ | ||
const EventRegistry: EventsRegistry = {}; | ||
type ListenerObject = Map<EventListener, AddEventListenerOptions | undefined | boolean>; | ||
type EventsRegistry = Record<string, Map<EventTarget, ListenerObject>>; | ||
const eventsRegistry: EventsRegistry = {}; | ||
export { EventRegistry }; | ||
/** | ||
* The global event listener. This function must be a Function. | ||
* | ||
* eslint-ignore-next | ||
*/ | ||
export function globalListener(e: Event): void { | ||
const that = this; | ||
const { type } = e; | ||
const globalListener = (e: Event): void => { | ||
const { type, target, currentTarget } = e; | ||
[...EventRegistry[type]].forEach((elementsMap) => { | ||
const [element, listenersMap] = elementsMap; | ||
[...eventsRegistry[type]].forEach(([element, listenersMap]) => { | ||
/* istanbul ignore else */ | ||
if (element === that) { | ||
[...listenersMap].forEach((listenerMap) => { | ||
const [listener, options] = listenerMap; | ||
if ([currentTarget, target].includes(element)) { | ||
[...listenersMap].forEach(([listener, options]) => { | ||
listener.apply(element, [e]); | ||
if (options && options.once) { | ||
if (typeof options === 'object' && options.once) { | ||
removeListener(element, type, listener, options); | ||
@@ -29,3 +32,3 @@ } | ||
}); | ||
} | ||
}; | ||
@@ -36,13 +39,13 @@ /** | ||
*/ | ||
export const addListener = ( | ||
const addListener = ( | ||
element: EventTarget, | ||
eventType: string, | ||
listener: EventListener, | ||
options?: AddEventListenerOptions | ||
options?: AddEventListenerOptions, | ||
): void => { | ||
// get element listeners first | ||
if (!EventRegistry[eventType]) { | ||
EventRegistry[eventType] = new Map(); | ||
if (!eventsRegistry[eventType]) { | ||
eventsRegistry[eventType] = new Map(); | ||
} | ||
const oneEventMap = EventRegistry[eventType]; | ||
const oneEventMap = eventsRegistry[eventType]; | ||
@@ -52,7 +55,5 @@ if (!oneEventMap.has(element)) { | ||
} | ||
const oneElementMap = oneEventMap.get(element); | ||
const oneElementMap = oneEventMap.get(element) as ListenerObject; | ||
// get listeners size | ||
if (typeof oneElementMap === 'undefined') return; | ||
const { size } = oneElementMap; | ||
@@ -74,10 +75,10 @@ | ||
*/ | ||
export const removeListener = ( | ||
const removeListener = ( | ||
element: EventTarget, | ||
eventType: string, | ||
listener: EventListener, | ||
options?: AddEventListenerOptions | ||
options?: AddEventListenerOptions, | ||
): void => { | ||
// get listener first | ||
const oneEventMap = EventRegistry[eventType]; | ||
const oneEventMap = eventsRegistry[eventType]; | ||
const oneElementMap = oneEventMap && oneEventMap.get(element); | ||
@@ -92,3 +93,3 @@ const savedOptions = oneElementMap && oneElementMap.get(listener); | ||
if (oneEventMap && (!oneElementMap || !oneElementMap.size)) oneEventMap.delete(element); | ||
if (!oneEventMap || !oneEventMap.size) delete EventRegistry[eventType]; | ||
if (!oneEventMap || !oneEventMap.size) delete eventsRegistry[eventType]; | ||
@@ -102,8 +103,2 @@ // remove listener last | ||
/** | ||
* Advanced event listener based on subscribe / publish pattern. | ||
* @see https://www.patterns.dev/posts/classic-design-patterns/#observerpatternjavascript | ||
* @see https://gist.github.com/shystruk/d16c0ee7ac7d194da9644e5d740c8338#file-subpub-js | ||
* @see https://hackernoon.com/do-you-still-register-window-event-listeners-in-each-component-react-in-example-31a4b1f6f1c8 | ||
*/ | ||
export default { | ||
@@ -113,5 +108,3 @@ on: addListener, | ||
globalListener, | ||
registry: EventRegistry, | ||
registry: eventsRegistry, | ||
}; | ||
// export default Listener; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
29939
20
11
143
117