feat: tiny event dispatcher
This commit is contained in:
parent
0af06e63d9
commit
bbddec8ead
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
.parcel-cache
|
.parcel-cache
|
||||||
|
|
||||||
|
*.iml
|
4
.npmignore
Normal file
4
.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
*.iml
|
3
bin/cloc
Executable file
3
bin/cloc
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
git shortlog -sne
|
||||||
|
cloc src/
|
97
package-lock.json
generated
97
package-lock.json
generated
@ -1,14 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "typescript-parcel-base",
|
"name": "@pinmenote/tiny-dispatcher",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "typescript-parcel-base",
|
"name": "@pinmenote/tiny-dispatcher",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^4.0.2"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@parcel/packager-ts": "^2.8.3",
|
||||||
"@parcel/transformer-typescript-tsc": "^2.8.3",
|
"@parcel/transformer-typescript-tsc": "^2.8.3",
|
||||||
|
"@parcel/transformer-typescript-types": "^2.8.3",
|
||||||
"@types/node": "^18.11.18",
|
"@types/node": "^18.11.18",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||||
"@typescript-eslint/parser": "^5.48.2",
|
"@typescript-eslint/parser": "^5.48.2",
|
||||||
@ -1018,6 +1024,23 @@
|
|||||||
"url": "https://opencollective.com/parcel"
|
"url": "https://opencollective.com/parcel"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@parcel/packager-ts": {
|
||||||
|
"version": "2.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/packager-ts/-/packager-ts-2.8.3.tgz",
|
||||||
|
"integrity": "sha512-8JooYHjKntHnQywLT7LAnfoGiAQ1fUu0N2DtuM0PxpgQqYJ4KE9TZS+SZq7hpe24cZkD0A4A+1kBlYAyvuanrg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@parcel/plugin": "2.8.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0",
|
||||||
|
"parcel": "^2.8.3"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@parcel/plugin": {
|
"node_modules/@parcel/plugin": {
|
||||||
"version": "2.8.3",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.3.tgz",
|
||||||
@ -1447,6 +1470,31 @@
|
|||||||
"typescript": ">=3.0.0"
|
"typescript": ">=3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@parcel/transformer-typescript-types": {
|
||||||
|
"version": "2.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/transformer-typescript-types/-/transformer-typescript-types-2.8.3.tgz",
|
||||||
|
"integrity": "sha512-zjsJsgecjw4X1nt5R7A61uWwzwCce0usKKPqnE5tQpYtF4FfK5X69r0l5JLovlyaT2uwoe+hvhu2AELA0kKRQA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@parcel/diagnostic": "2.8.3",
|
||||||
|
"@parcel/plugin": "2.8.3",
|
||||||
|
"@parcel/source-map": "^2.1.1",
|
||||||
|
"@parcel/ts-utils": "2.8.3",
|
||||||
|
"@parcel/utils": "2.8.3",
|
||||||
|
"nullthrows": "^1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0",
|
||||||
|
"parcel": "^2.8.3"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@parcel/ts-utils": {
|
"node_modules/@parcel/ts-utils": {
|
||||||
"version": "2.8.3",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@parcel/ts-utils/-/ts-utils-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@parcel/ts-utils/-/ts-utils-2.8.3.tgz",
|
||||||
@ -3387,6 +3435,23 @@
|
|||||||
"@msgpackr-extract/msgpackr-extract-win32-x64": "2.2.0"
|
"@msgpackr-extract/msgpackr-extract-win32-x64": "2.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14 || ^16 || >=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/natural-compare": {
|
"node_modules/natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@ -5050,6 +5115,15 @@
|
|||||||
"posthtml": "^0.16.4"
|
"posthtml": "^0.16.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@parcel/packager-ts": {
|
||||||
|
"version": "2.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/packager-ts/-/packager-ts-2.8.3.tgz",
|
||||||
|
"integrity": "sha512-8JooYHjKntHnQywLT7LAnfoGiAQ1fUu0N2DtuM0PxpgQqYJ4KE9TZS+SZq7hpe24cZkD0A4A+1kBlYAyvuanrg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@parcel/plugin": "2.8.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@parcel/plugin": {
|
"@parcel/plugin": {
|
||||||
"version": "2.8.3",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.3.tgz",
|
||||||
@ -5312,6 +5386,20 @@
|
|||||||
"@parcel/ts-utils": "2.8.3"
|
"@parcel/ts-utils": "2.8.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@parcel/transformer-typescript-types": {
|
||||||
|
"version": "2.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/transformer-typescript-types/-/transformer-typescript-types-2.8.3.tgz",
|
||||||
|
"integrity": "sha512-zjsJsgecjw4X1nt5R7A61uWwzwCce0usKKPqnE5tQpYtF4FfK5X69r0l5JLovlyaT2uwoe+hvhu2AELA0kKRQA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@parcel/diagnostic": "2.8.3",
|
||||||
|
"@parcel/plugin": "2.8.3",
|
||||||
|
"@parcel/source-map": "^2.1.1",
|
||||||
|
"@parcel/ts-utils": "2.8.3",
|
||||||
|
"@parcel/utils": "2.8.3",
|
||||||
|
"nullthrows": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@parcel/ts-utils": {
|
"@parcel/ts-utils": {
|
||||||
"version": "2.8.3",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@parcel/ts-utils/-/ts-utils-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@parcel/ts-utils/-/ts-utils-2.8.3.tgz",
|
||||||
@ -6624,6 +6712,11 @@
|
|||||||
"node-gyp-build-optional-packages": "5.0.3"
|
"node-gyp-build-optional-packages": "5.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nanoid": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw=="
|
||||||
|
},
|
||||||
"natural-compare": {
|
"natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
|
21
package.json
21
package.json
@ -1,9 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "typescript-parcel-base",
|
"name": "@pinmenote/tiny-dispatcher",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
"author": "Michal Szczepanski",
|
||||||
|
"license": "MIT",
|
||||||
|
"description": "tiny event dispatcher",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/pinmenote/tiny-dispatcher/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/pinmenote/tiny-dispatcher#readme",
|
||||||
|
"source": "src/tiny.dispatcher.ts",
|
||||||
|
"module": "dist/module.js",
|
||||||
|
"types": "dist/types.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "parcel src/index.html",
|
"build": "parcel build",
|
||||||
"prod": "parcel build src/index.html",
|
"dev": "NODE_ENV=development parcel build",
|
||||||
"lint": "eslint --ext .ts src/",
|
"lint": "eslint --ext .ts src/",
|
||||||
"lint:fix": "eslint --ext .ts,.tsx src/ --fix"
|
"lint:fix": "eslint --ext .ts,.tsx src/ --fix"
|
||||||
},
|
},
|
||||||
@ -11,7 +21,9 @@
|
|||||||
"lint"
|
"lint"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@parcel/packager-ts": "^2.8.3",
|
||||||
"@parcel/transformer-typescript-tsc": "^2.8.3",
|
"@parcel/transformer-typescript-tsc": "^2.8.3",
|
||||||
|
"@parcel/transformer-typescript-types": "^2.8.3",
|
||||||
"@types/node": "^18.11.18",
|
"@types/node": "^18.11.18",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||||
"@typescript-eslint/parser": "^5.48.2",
|
"@typescript-eslint/parser": "^5.48.2",
|
||||||
@ -21,5 +33,8 @@
|
|||||||
"parcel": "^2.8.3",
|
"parcel": "^2.8.3",
|
||||||
"pre-commit": "^1.2.2",
|
"pre-commit": "^1.2.2",
|
||||||
"typescript": "^4.9.4"
|
"typescript": "^4.9.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^4.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
53
src/tiny.dispatcher.ts
Normal file
53
src/tiny.dispatcher.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { customAlphabet } from 'nanoid';
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment
|
||||||
|
const alphabet: (size: number) => string = customAlphabet('abcdefghijklmnopqrstuwxyz0123456789');
|
||||||
|
|
||||||
|
const uid = (size = 10): string => {
|
||||||
|
return alphabet(size);
|
||||||
|
};
|
||||||
|
|
||||||
|
export class TinyDispatcher {
|
||||||
|
private static listeners: { [key: string]: { [key: string]: any } } = {};
|
||||||
|
private static once: { [key: string]: string } = {};
|
||||||
|
|
||||||
|
static addListener<T>(event: string, handler: (event: string, key: string, value: T) => void, once = false): string {
|
||||||
|
if (!this.listeners[event]) {
|
||||||
|
this.listeners[event] = {};
|
||||||
|
}
|
||||||
|
const key = uid();
|
||||||
|
if (once) this.once[key] = event;
|
||||||
|
this.listeners[event][key] = handler;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dispatch<T>(event: string, value?: T): void {
|
||||||
|
if (this.listeners[event]) {
|
||||||
|
for (const key in this.listeners[event]) {
|
||||||
|
this.listeners[event][key](event, key, value); // eslint-disable-line @typescript-eslint/no-unsafe-call
|
||||||
|
if (this.once[key]) {
|
||||||
|
this.removeListener(event, key);
|
||||||
|
delete this.once[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static removeListener(event: string, key: string): boolean {
|
||||||
|
if (!this.listeners[event]) return false;
|
||||||
|
if (this.listeners[event][key]) {
|
||||||
|
delete this.listeners[event][key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static removeAllListener(event: string): boolean {
|
||||||
|
if (!this.listeners[event]) return false;
|
||||||
|
delete this.listeners[event];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cleanup() {
|
||||||
|
this.listeners = {};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user