evnty 0.7.4 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -27
- package/build/index.d.ts +12 -2
- package/build/index.js +38 -9
- package/build/index.js.map +1 -1
- package/package.json +7 -3
- package/src/index.ts +42 -10
package/README.md
CHANGED
|
@@ -8,32 +8,81 @@
|
|
|
8
8
|
[![Downloads][downloads-image]][npm-url]
|
|
9
9
|
[![Snyk][snyk-image]][snyk-url]
|
|
10
10
|
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Features](#features)
|
|
14
|
+
- [Browser Support](#browser-support)
|
|
15
|
+
- [Installing](#installing)
|
|
16
|
+
- [Examples](#examples)
|
|
17
|
+
- [Roadmap](#roadmap)
|
|
18
|
+
- [License](#license)
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Promises support
|
|
23
|
+
- Full-featured typeScript support
|
|
24
|
+
- Browser & Workers environment compatibility
|
|
25
|
+
- Performance eventemitter3/eventemitter2/event-emitter/events/native node/native browser
|
|
26
|
+
|
|
27
|
+
## Roadmap
|
|
28
|
+
|
|
29
|
+
- Namespaces/Wildcards
|
|
30
|
+
- Times To Listen (TTL)
|
|
31
|
+
- Subscribe/UnSubscribe
|
|
32
|
+
|
|
33
|
+
## Browser Support
|
|
34
|
+
|
|
35
|
+
| ![Chrome][chrome-image] | ![Firefox][firefox-image] | ![Safari][safari-image] | ![Opera][opera-image] | ![Edge][edge-image] |
|
|
36
|
+
| ----------------------- | ------------------------- | ----------------------- | --------------------- | ------------------- |
|
|
37
|
+
| Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ |
|
|
38
|
+
|
|
39
|
+
[chrome-image]: https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png?1
|
|
40
|
+
[firefox-image]: https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png?1
|
|
41
|
+
[safari-image]: https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png?1
|
|
42
|
+
[opera-image]: https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png?1
|
|
43
|
+
[edge-image]: https://raw.github.com/alrra/browser-logos/master/src/edge/edge_48x48.png?1
|
|
44
|
+
|
|
45
|
+
## Installing
|
|
46
|
+
|
|
47
|
+
Using yarn:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yarn add evnty
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Using npm:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install evnty
|
|
57
|
+
```
|
|
58
|
+
|
|
11
59
|
## Interface
|
|
12
60
|
|
|
13
61
|
```typescript
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
62
|
+
type Unsubscribe = () => void;
|
|
63
|
+
type Listener = (...args: any[]) => void;
|
|
64
|
+
type Dispose = () => void;
|
|
65
|
+
type Filter = (...args: any[]) => boolean;
|
|
66
|
+
type Mapper = <T = any>(...args: any[]) => T;
|
|
67
|
+
type Reducer = <T = any>(value: any, ...args: any[]) => T;
|
|
68
|
+
|
|
69
|
+
class Event {
|
|
70
|
+
static merge(...events: Event[]): Event;
|
|
71
|
+
static interval(interval: number): Event;
|
|
72
|
+
|
|
73
|
+
readonly size: Number;
|
|
74
|
+
|
|
75
|
+
constructor(dispose?: Dispose);
|
|
76
|
+
has(listener: Listener): boolean;
|
|
77
|
+
off(listener: Listener): void;
|
|
78
|
+
on(listener: Listener): Unsubscribe;
|
|
79
|
+
once(listener: Listener): Unsubscribe;
|
|
80
|
+
clear(): void;
|
|
81
|
+
toPromise(): Promise<any[]>;
|
|
82
|
+
filter(filter: Filter): Event;
|
|
83
|
+
map(mapper: Mapper): Event;
|
|
84
|
+
reduce(reducer: Reducer, init: any): Event;
|
|
85
|
+
dispose(): Dispose;
|
|
37
86
|
}
|
|
38
87
|
```
|
|
39
88
|
|
|
@@ -50,9 +99,7 @@ const unsubscribe = clickEvent.on(handleClick);
|
|
|
50
99
|
|
|
51
100
|
const keyPressEvent = event();
|
|
52
101
|
|
|
53
|
-
function handleInput({ button, key }) {
|
|
54
|
-
|
|
55
|
-
}
|
|
102
|
+
function handleInput({ button, key }) {}
|
|
56
103
|
|
|
57
104
|
const inputEvent = Event.merge(clickEvent, keyPressEvent);
|
|
58
105
|
inputEvent.on(handleInput);
|
|
@@ -63,7 +110,6 @@ function handleLeftClick() {
|
|
|
63
110
|
const leftClickEvent = clickEvent.filter(({ button }) => button === 'left');
|
|
64
111
|
leftClickEvent.on(handleLeftClick);
|
|
65
112
|
|
|
66
|
-
|
|
67
113
|
clickEvent({ button: 'right' });
|
|
68
114
|
clickEvent({ button: 'left' });
|
|
69
115
|
clickEvent({ button: 'middle' });
|
|
@@ -76,6 +122,7 @@ unsubscribe();
|
|
|
76
122
|
```
|
|
77
123
|
|
|
78
124
|
## License
|
|
125
|
+
|
|
79
126
|
License [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
|
80
127
|
Copyright (c) 2021-present Ivan Zakharchanka
|
|
81
128
|
|
package/build/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
declare type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;
|
|
1
2
|
export interface Unsubscribe {
|
|
2
3
|
(): void;
|
|
3
4
|
}
|
|
@@ -8,7 +9,7 @@ export interface Dispose {
|
|
|
8
9
|
(): void;
|
|
9
10
|
}
|
|
10
11
|
export interface Filter<T extends any[]> {
|
|
11
|
-
(...args: T): boolean
|
|
12
|
+
(...args: T): MaybePromise<boolean>;
|
|
12
13
|
}
|
|
13
14
|
export interface Mapper<T extends any[], R> {
|
|
14
15
|
(...args: T): R;
|
|
@@ -16,10 +17,18 @@ export interface Mapper<T extends any[], R> {
|
|
|
16
17
|
export interface Reducer<T extends any[], R> {
|
|
17
18
|
(value: R, ...args: T): R;
|
|
18
19
|
}
|
|
19
|
-
export declare type Listeners<T extends any[]> =
|
|
20
|
+
export declare type Listeners<T extends any[]> = Listener<T>[];
|
|
20
21
|
declare class FunctionExt extends Function {
|
|
21
22
|
constructor(func: Function);
|
|
22
23
|
}
|
|
24
|
+
export interface Dismiss {
|
|
25
|
+
(): Promise<void> | void;
|
|
26
|
+
}
|
|
27
|
+
export declare class Dismiss extends FunctionExt {
|
|
28
|
+
constructor(dismiss: Unsubscribe);
|
|
29
|
+
while(process: () => MaybePromise<any>): Promise<void>;
|
|
30
|
+
after(count: number): Promise<() => void>;
|
|
31
|
+
}
|
|
23
32
|
export interface Event<T extends any[]> {
|
|
24
33
|
(...args: T): Promise<void> | void;
|
|
25
34
|
}
|
|
@@ -31,6 +40,7 @@ export declare class Event<T extends any[]> extends FunctionExt {
|
|
|
31
40
|
readonly dispose: Dispose;
|
|
32
41
|
constructor(dispose?: Dispose);
|
|
33
42
|
get size(): number;
|
|
43
|
+
lacks(listener: Listener<T>): boolean;
|
|
34
44
|
has(listener: Listener<T>): boolean;
|
|
35
45
|
off(listener: Listener<T>): void;
|
|
36
46
|
on(listener: Listener<T>): Unsubscribe;
|
package/build/index.js
CHANGED
|
@@ -9,19 +9,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.Event = void 0;
|
|
12
|
+
exports.Event = exports.Dismiss = void 0;
|
|
13
13
|
class FunctionExt extends Function {
|
|
14
14
|
constructor(func) {
|
|
15
15
|
super();
|
|
16
16
|
return Object.setPrototypeOf(func, new.target.prototype);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
class Dismiss extends FunctionExt {
|
|
20
|
+
constructor(dismiss) {
|
|
21
|
+
super(dismiss);
|
|
22
|
+
}
|
|
23
|
+
while(process) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
yield process();
|
|
26
|
+
this();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
after(count) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
return () => {
|
|
32
|
+
if (!count--) {
|
|
33
|
+
this();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.Dismiss = Dismiss;
|
|
19
40
|
function eventEmitter(listeners, ...args) {
|
|
20
|
-
return Promise.all(
|
|
41
|
+
return Promise.all(listeners.map((listener) => listener(...args))).then(() => void 0);
|
|
21
42
|
}
|
|
22
43
|
class Event extends FunctionExt {
|
|
23
44
|
constructor(dispose) {
|
|
24
|
-
const listeners =
|
|
45
|
+
const listeners = [];
|
|
25
46
|
const fn = eventEmitter.bind(null, listeners);
|
|
26
47
|
super(fn);
|
|
27
48
|
this.listeners = listeners;
|
|
@@ -43,17 +64,25 @@ class Event extends FunctionExt {
|
|
|
43
64
|
return intervalEvent;
|
|
44
65
|
}
|
|
45
66
|
get size() {
|
|
46
|
-
return this.listeners.
|
|
67
|
+
return this.listeners.length;
|
|
68
|
+
}
|
|
69
|
+
lacks(listener) {
|
|
70
|
+
return this.listeners.indexOf(listener) === -1;
|
|
47
71
|
}
|
|
48
72
|
has(listener) {
|
|
49
|
-
return this.
|
|
73
|
+
return !this.lacks(listener);
|
|
50
74
|
}
|
|
51
75
|
off(listener) {
|
|
52
|
-
this.listeners.
|
|
76
|
+
const index = this.listeners.indexOf(listener);
|
|
77
|
+
if (index !== -1) {
|
|
78
|
+
this.listeners.splice(index, 1);
|
|
79
|
+
}
|
|
53
80
|
}
|
|
54
81
|
on(listener) {
|
|
55
|
-
this.
|
|
56
|
-
|
|
82
|
+
if (this.lacks(listener)) {
|
|
83
|
+
this.listeners.push(listener);
|
|
84
|
+
}
|
|
85
|
+
return new Dismiss(() => this.off(listener));
|
|
57
86
|
}
|
|
58
87
|
once(listener) {
|
|
59
88
|
const oneTimeListener = (...args) => {
|
|
@@ -63,7 +92,7 @@ class Event extends FunctionExt {
|
|
|
63
92
|
return this.on(oneTimeListener);
|
|
64
93
|
}
|
|
65
94
|
clear() {
|
|
66
|
-
this.listeners.
|
|
95
|
+
this.listeners.splice(0);
|
|
67
96
|
}
|
|
68
97
|
toPromise() {
|
|
69
98
|
return new Promise((resolve) => this.once((...args) => resolve(args)));
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "evnty",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "0-Deps, simple, fast, for browser and node js anonymous event library",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"build",
|
|
9
|
+
"src/index.ts"
|
|
10
|
+
],
|
|
7
11
|
"scripts": {
|
|
8
12
|
"build": "rm -rf build && NODE_ENV=production tsc",
|
|
9
13
|
"test": "jest",
|
|
10
14
|
"test:cov": "COVERAGE=true jest",
|
|
11
|
-
"lint": "eslint
|
|
15
|
+
"lint": "eslint src",
|
|
12
16
|
"prepare": "husky install"
|
|
13
17
|
},
|
|
14
18
|
"repository": {
|
|
@@ -38,7 +42,7 @@
|
|
|
38
42
|
"eslint-config-prettier": "^8.5.0",
|
|
39
43
|
"eslint-plugin-import": "^2.26.0",
|
|
40
44
|
"husky": "^7.0.4",
|
|
41
|
-
"jest": "
|
|
45
|
+
"jest": "27",
|
|
42
46
|
"prettier": "^2.6.2",
|
|
43
47
|
"pretty-quick": "^3.1.3",
|
|
44
48
|
"ts-jest": "^27.1.4",
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;
|
|
2
|
+
|
|
1
3
|
export interface Unsubscribe {
|
|
2
4
|
(): void;
|
|
3
5
|
}
|
|
@@ -11,7 +13,7 @@ export interface Dispose {
|
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export interface Filter<T extends any[]> {
|
|
14
|
-
(...args: T): boolean
|
|
16
|
+
(...args: T): MaybePromise<boolean>;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export interface Mapper<T extends any[], R> {
|
|
@@ -22,7 +24,7 @@ export interface Reducer<T extends any[], R> {
|
|
|
22
24
|
(value: R, ...args: T): R;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
export type Listeners<T extends any[]> =
|
|
27
|
+
export type Listeners<T extends any[]> = Listener<T>[];
|
|
26
28
|
|
|
27
29
|
class FunctionExt extends Function {
|
|
28
30
|
constructor(func: Function) {
|
|
@@ -31,8 +33,29 @@ class FunctionExt extends Function {
|
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
export interface Dismiss {
|
|
37
|
+
(): Promise<void> | void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class Dismiss extends FunctionExt {
|
|
41
|
+
constructor(dismiss: Unsubscribe) {
|
|
42
|
+
super(dismiss);
|
|
43
|
+
}
|
|
44
|
+
async while(process: () => MaybePromise<any>) {
|
|
45
|
+
await process();
|
|
46
|
+
this();
|
|
47
|
+
}
|
|
48
|
+
async after(count: number) {
|
|
49
|
+
return () => {
|
|
50
|
+
if (!count--) {
|
|
51
|
+
this();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
function eventEmitter<A extends any[]>(listeners: Listeners<A>, ...args: A) {
|
|
35
|
-
return Promise.all(
|
|
58
|
+
return Promise.all(listeners.map((listener) => listener(...args))).then(() => void 0);
|
|
36
59
|
}
|
|
37
60
|
|
|
38
61
|
export interface Event<T extends any[]> {
|
|
@@ -60,7 +83,7 @@ export class Event<T extends any[]> extends FunctionExt {
|
|
|
60
83
|
readonly dispose: Dispose;
|
|
61
84
|
|
|
62
85
|
constructor(dispose?: Dispose) {
|
|
63
|
-
const listeners =
|
|
86
|
+
const listeners: Listeners<T> = [];
|
|
64
87
|
const fn: (...args: T) => Promise<void> = eventEmitter.bind(null, listeners);
|
|
65
88
|
super(fn);
|
|
66
89
|
this.listeners = listeners;
|
|
@@ -71,20 +94,29 @@ export class Event<T extends any[]> extends FunctionExt {
|
|
|
71
94
|
}
|
|
72
95
|
|
|
73
96
|
get size(): number {
|
|
74
|
-
return this.listeners.
|
|
97
|
+
return this.listeners.length;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
lacks(listener: Listener<T>): boolean {
|
|
101
|
+
return this.listeners.indexOf(listener) === -1;
|
|
75
102
|
}
|
|
76
103
|
|
|
77
104
|
has(listener: Listener<T>): boolean {
|
|
78
|
-
return this.
|
|
105
|
+
return !this.lacks(listener);
|
|
79
106
|
}
|
|
80
107
|
|
|
81
108
|
off(listener: Listener<T>): void {
|
|
82
|
-
this.listeners.
|
|
109
|
+
const index = this.listeners.indexOf(listener);
|
|
110
|
+
if (index !== -1) {
|
|
111
|
+
this.listeners.splice(index, 1);
|
|
112
|
+
}
|
|
83
113
|
}
|
|
84
114
|
|
|
85
115
|
on(listener: Listener<T>): Unsubscribe {
|
|
86
|
-
this.
|
|
87
|
-
|
|
116
|
+
if (this.lacks(listener)) {
|
|
117
|
+
this.listeners.push(listener);
|
|
118
|
+
}
|
|
119
|
+
return new Dismiss(() => this.off(listener));
|
|
88
120
|
}
|
|
89
121
|
|
|
90
122
|
once(listener: Listener<T>): Unsubscribe {
|
|
@@ -96,7 +128,7 @@ export class Event<T extends any[]> extends FunctionExt {
|
|
|
96
128
|
}
|
|
97
129
|
|
|
98
130
|
clear() {
|
|
99
|
-
this.listeners.
|
|
131
|
+
this.listeners.splice(0);
|
|
100
132
|
}
|
|
101
133
|
|
|
102
134
|
toPromise(): Promise<T> {
|