@idlebox/common 1.4.1 → 1.4.2
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/lib/cjs/lifecycle/event/event.cjs +61 -6
- package/lib/cjs/lifecycle/event/event.cjs.map +1 -1
- package/lib/esm/lifecycle/event/event.d.ts +12 -0
- package/lib/esm/lifecycle/event/event.d.ts.map +1 -1
- package/lib/esm/lifecycle/event/event.js +61 -6
- package/lib/esm/lifecycle/event/event.js.map +1 -1
- package/package.json +4 -4
- package/src/lifecycle/event/event.ts +63 -6
|
@@ -7,6 +7,7 @@ exports.Emitter = void 0;
|
|
|
7
7
|
*/
|
|
8
8
|
class Emitter {
|
|
9
9
|
_callbacks = [];
|
|
10
|
+
executing = false;
|
|
10
11
|
constructor() {
|
|
11
12
|
this.handle = this.handle.bind(this);
|
|
12
13
|
}
|
|
@@ -21,14 +22,24 @@ class Emitter {
|
|
|
21
22
|
* @param data 回调数据
|
|
22
23
|
*/
|
|
23
24
|
fire(data) {
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
this.requireNotExecuting();
|
|
26
|
+
this.executing = true;
|
|
27
|
+
try {
|
|
28
|
+
for (const callback of this._callbacks) {
|
|
29
|
+
callback(data);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
this.doDefer();
|
|
34
|
+
this.executing = false;
|
|
26
35
|
}
|
|
27
36
|
}
|
|
28
37
|
/**
|
|
29
38
|
* 与 `fire()`相同,但是忽略任何错误,并且即便出错也继续执行全部callback
|
|
30
39
|
*/
|
|
31
40
|
fireNoError(data) {
|
|
41
|
+
this.requireNotExecuting();
|
|
42
|
+
this.executing = true;
|
|
32
43
|
for (const callback of this._callbacks) {
|
|
33
44
|
try {
|
|
34
45
|
callback(data);
|
|
@@ -37,6 +48,8 @@ class Emitter {
|
|
|
37
48
|
console.error('Error ignored: ', e);
|
|
38
49
|
}
|
|
39
50
|
}
|
|
51
|
+
this.doDefer();
|
|
52
|
+
this.executing = false;
|
|
40
53
|
}
|
|
41
54
|
/**
|
|
42
55
|
* 获取handle()方法的引用
|
|
@@ -49,17 +62,54 @@ class Emitter {
|
|
|
49
62
|
* @param callback 回调函数
|
|
50
63
|
*/
|
|
51
64
|
handle(callback) {
|
|
52
|
-
this.
|
|
65
|
+
this.requireNotExecuting();
|
|
66
|
+
let disposed = false;
|
|
67
|
+
this._callbacks.unshift((e) => {
|
|
68
|
+
if (!disposed)
|
|
69
|
+
callback(e);
|
|
70
|
+
});
|
|
71
|
+
const realDispose = () => {
|
|
72
|
+
const index = this._callbacks.indexOf(callback);
|
|
73
|
+
if (index !== -1) {
|
|
74
|
+
this._callbacks.splice(index, 1);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
53
77
|
return {
|
|
54
78
|
dispose: () => {
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
this.
|
|
79
|
+
disposed = true;
|
|
80
|
+
if (this.executing) {
|
|
81
|
+
this.defer(realDispose);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
realDispose();
|
|
58
85
|
}
|
|
59
86
|
},
|
|
60
87
|
};
|
|
61
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* 注册一次性回调
|
|
91
|
+
* @param callback 回调函数
|
|
92
|
+
*/
|
|
93
|
+
once(callback) {
|
|
94
|
+
this.requireNotExecuting();
|
|
95
|
+
const disposable = this.handle((data) => {
|
|
96
|
+
callback(data);
|
|
97
|
+
disposable.dispose();
|
|
98
|
+
});
|
|
99
|
+
return disposable;
|
|
100
|
+
}
|
|
101
|
+
defers = [];
|
|
102
|
+
defer(fn) {
|
|
103
|
+
this.defers.push(fn);
|
|
104
|
+
}
|
|
105
|
+
doDefer() {
|
|
106
|
+
for (const fn of this.defers) {
|
|
107
|
+
fn();
|
|
108
|
+
}
|
|
109
|
+
this.defers.length = 0;
|
|
110
|
+
}
|
|
62
111
|
dispose() {
|
|
112
|
+
this.requireNotExecuting();
|
|
63
113
|
this._callbacks.length = 0;
|
|
64
114
|
this.fireNoError =
|
|
65
115
|
this.fire =
|
|
@@ -68,6 +118,11 @@ class Emitter {
|
|
|
68
118
|
throw new Error('Event is disposed');
|
|
69
119
|
};
|
|
70
120
|
}
|
|
121
|
+
requireNotExecuting() {
|
|
122
|
+
if (this.executing) {
|
|
123
|
+
throw new Error('conflict state, emitter is firing');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
71
126
|
}
|
|
72
127
|
exports.Emitter = Emitter;
|
|
73
128
|
//# sourceMappingURL=event.cjs.map
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
"../../../../src/lifecycle/event/event.ts"
|
|
7
7
|
],
|
|
8
8
|
"names": [],
|
|
9
|
-
"mappings": ";;;
|
|
9
|
+
"mappings": "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"
|
|
10
10
|
}
|
|
@@ -5,12 +5,14 @@ export interface EventHandler<T> {
|
|
|
5
5
|
export interface EventRegister<T> {
|
|
6
6
|
(callback: EventHandler<T>): IDisposable;
|
|
7
7
|
}
|
|
8
|
+
type DeferFn = () => void;
|
|
8
9
|
/**
|
|
9
10
|
* 事件注册对象
|
|
10
11
|
* @public
|
|
11
12
|
*/
|
|
12
13
|
export declare class Emitter<T> implements IDisposable {
|
|
13
14
|
protected readonly _callbacks: EventHandler<T>[];
|
|
15
|
+
private executing;
|
|
14
16
|
constructor();
|
|
15
17
|
/**
|
|
16
18
|
* @returns 当前注册回调数量
|
|
@@ -34,6 +36,16 @@ export declare class Emitter<T> implements IDisposable {
|
|
|
34
36
|
* @param callback 回调函数
|
|
35
37
|
*/
|
|
36
38
|
handle(callback: EventHandler<T>): IDisposable;
|
|
39
|
+
/**
|
|
40
|
+
* 注册一次性回调
|
|
41
|
+
* @param callback 回调函数
|
|
42
|
+
*/
|
|
43
|
+
once(callback: EventHandler<T>): IDisposable;
|
|
44
|
+
private defers;
|
|
45
|
+
defer(fn: DeferFn): void;
|
|
46
|
+
private doDefer;
|
|
37
47
|
dispose(): void;
|
|
48
|
+
private requireNotExecuting;
|
|
38
49
|
}
|
|
50
|
+
export {};
|
|
39
51
|
//# sourceMappingURL=event.d.ts.map
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
"../../../../src/lifecycle/event/event.ts"
|
|
7
7
|
],
|
|
8
8
|
"names": [],
|
|
9
|
-
"mappings": "AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC/B,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CACzC;AAED;;;GAGG;AACH,qBAAa,OAAO,CAAC,CAAC,CAAE,YAAW,WAAW;IAC7C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAM;;
|
|
9
|
+
"mappings": "AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC/B,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CACzC;AAED,KAAK,OAAO,GAAG,MAAM,IAAI,CAAC;AAE1B;;;GAGG;AACH,qBAAa,OAAO,CAAC,CAAC,CAAE,YAAW,WAAW;IAC7C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAM;IACtD,OAAO,CAAC,SAAS,CAAkB;;IAMnC;;OAEG;IACI,aAAa;IAIpB;;;OAGG;IACI,IAAI,CAAC,IAAI,EAAE,CAAC;IAanB;;OAEG;IACI,WAAW,CAAC,IAAI,EAAE,CAAC;IAc1B;;OAEG;IACH,IAAI,QAAQ,IAAI,aAAa,CAAC,CAAC,CAAC,CAE/B;IAED;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW;IAwB9C;;;OAGG;IACH,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW;IAS5C,OAAO,CAAC,MAAM,CAAiB;IACxB,KAAK,CAAC,EAAE,EAAE,OAAO;IAGxB,OAAO,CAAC,OAAO;IAOf,OAAO;IAWP,OAAO,CAAC,mBAAmB;CAK3B"
|
|
10
10
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export class Emitter {
|
|
6
6
|
_callbacks = [];
|
|
7
|
+
executing = false;
|
|
7
8
|
constructor() {
|
|
8
9
|
this.handle = this.handle.bind(this);
|
|
9
10
|
}
|
|
@@ -18,14 +19,24 @@ export class Emitter {
|
|
|
18
19
|
* @param data 回调数据
|
|
19
20
|
*/
|
|
20
21
|
fire(data) {
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
this.requireNotExecuting();
|
|
23
|
+
this.executing = true;
|
|
24
|
+
try {
|
|
25
|
+
for (const callback of this._callbacks) {
|
|
26
|
+
callback(data);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
this.doDefer();
|
|
31
|
+
this.executing = false;
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
/**
|
|
26
35
|
* 与 `fire()`相同,但是忽略任何错误,并且即便出错也继续执行全部callback
|
|
27
36
|
*/
|
|
28
37
|
fireNoError(data) {
|
|
38
|
+
this.requireNotExecuting();
|
|
39
|
+
this.executing = true;
|
|
29
40
|
for (const callback of this._callbacks) {
|
|
30
41
|
try {
|
|
31
42
|
callback(data);
|
|
@@ -34,6 +45,8 @@ export class Emitter {
|
|
|
34
45
|
console.error('Error ignored: ', e);
|
|
35
46
|
}
|
|
36
47
|
}
|
|
48
|
+
this.doDefer();
|
|
49
|
+
this.executing = false;
|
|
37
50
|
}
|
|
38
51
|
/**
|
|
39
52
|
* 获取handle()方法的引用
|
|
@@ -46,17 +59,54 @@ export class Emitter {
|
|
|
46
59
|
* @param callback 回调函数
|
|
47
60
|
*/
|
|
48
61
|
handle(callback) {
|
|
49
|
-
this.
|
|
62
|
+
this.requireNotExecuting();
|
|
63
|
+
let disposed = false;
|
|
64
|
+
this._callbacks.unshift((e) => {
|
|
65
|
+
if (!disposed)
|
|
66
|
+
callback(e);
|
|
67
|
+
});
|
|
68
|
+
const realDispose = () => {
|
|
69
|
+
const index = this._callbacks.indexOf(callback);
|
|
70
|
+
if (index !== -1) {
|
|
71
|
+
this._callbacks.splice(index, 1);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
50
74
|
return {
|
|
51
75
|
dispose: () => {
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
this.
|
|
76
|
+
disposed = true;
|
|
77
|
+
if (this.executing) {
|
|
78
|
+
this.defer(realDispose);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
realDispose();
|
|
55
82
|
}
|
|
56
83
|
},
|
|
57
84
|
};
|
|
58
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* 注册一次性回调
|
|
88
|
+
* @param callback 回调函数
|
|
89
|
+
*/
|
|
90
|
+
once(callback) {
|
|
91
|
+
this.requireNotExecuting();
|
|
92
|
+
const disposable = this.handle((data) => {
|
|
93
|
+
callback(data);
|
|
94
|
+
disposable.dispose();
|
|
95
|
+
});
|
|
96
|
+
return disposable;
|
|
97
|
+
}
|
|
98
|
+
defers = [];
|
|
99
|
+
defer(fn) {
|
|
100
|
+
this.defers.push(fn);
|
|
101
|
+
}
|
|
102
|
+
doDefer() {
|
|
103
|
+
for (const fn of this.defers) {
|
|
104
|
+
fn();
|
|
105
|
+
}
|
|
106
|
+
this.defers.length = 0;
|
|
107
|
+
}
|
|
59
108
|
dispose() {
|
|
109
|
+
this.requireNotExecuting();
|
|
60
110
|
this._callbacks.length = 0;
|
|
61
111
|
this.fireNoError =
|
|
62
112
|
this.fire =
|
|
@@ -65,5 +115,10 @@ export class Emitter {
|
|
|
65
115
|
throw new Error('Event is disposed');
|
|
66
116
|
};
|
|
67
117
|
}
|
|
118
|
+
requireNotExecuting() {
|
|
119
|
+
if (this.executing) {
|
|
120
|
+
throw new Error('conflict state, emitter is firing');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
68
123
|
}
|
|
69
124
|
//# sourceMappingURL=event.js.map
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
"../../../../src/lifecycle/event/event.ts"
|
|
7
7
|
],
|
|
8
8
|
"names": [],
|
|
9
|
-
"mappings": "
|
|
9
|
+
"mappings": "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"
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idlebox/common",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./lib/cjs/__create_index.generated.cjs",
|
|
7
7
|
"module": "./lib/esm/__create_index.generated.js",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"repository": "https://github.com/GongT/baobao",
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@rushstack/heft": "^0.68.2",
|
|
21
|
-
"@build-script/single-dog-asset": "^1.0.
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
21
|
+
"@build-script/single-dog-asset": "^1.0.33",
|
|
22
|
+
"@internal/local-rig": "^1.0.1",
|
|
23
|
+
"@idlebox/itypes": "^1.0.5"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"test": "heft test",
|
|
@@ -8,12 +8,15 @@ export interface EventRegister<T> {
|
|
|
8
8
|
(callback: EventHandler<T>): IDisposable;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
type DeferFn = () => void;
|
|
12
|
+
|
|
11
13
|
/**
|
|
12
14
|
* 事件注册对象
|
|
13
15
|
* @public
|
|
14
16
|
*/
|
|
15
17
|
export class Emitter<T> implements IDisposable {
|
|
16
18
|
protected readonly _callbacks: EventHandler<T>[] = [];
|
|
19
|
+
private executing: boolean = false;
|
|
17
20
|
|
|
18
21
|
constructor() {
|
|
19
22
|
this.handle = this.handle.bind(this);
|
|
@@ -31,8 +34,15 @@ export class Emitter<T> implements IDisposable {
|
|
|
31
34
|
* @param data 回调数据
|
|
32
35
|
*/
|
|
33
36
|
public fire(data: T) {
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
this.requireNotExecuting();
|
|
38
|
+
this.executing = true;
|
|
39
|
+
try {
|
|
40
|
+
for (const callback of this._callbacks) {
|
|
41
|
+
callback(data);
|
|
42
|
+
}
|
|
43
|
+
} finally {
|
|
44
|
+
this.doDefer();
|
|
45
|
+
this.executing = false;
|
|
36
46
|
}
|
|
37
47
|
}
|
|
38
48
|
|
|
@@ -40,6 +50,8 @@ export class Emitter<T> implements IDisposable {
|
|
|
40
50
|
* 与 `fire()`相同,但是忽略任何错误,并且即便出错也继续执行全部callback
|
|
41
51
|
*/
|
|
42
52
|
public fireNoError(data: T) {
|
|
53
|
+
this.requireNotExecuting();
|
|
54
|
+
this.executing = true;
|
|
43
55
|
for (const callback of this._callbacks) {
|
|
44
56
|
try {
|
|
45
57
|
callback(data);
|
|
@@ -47,6 +59,8 @@ export class Emitter<T> implements IDisposable {
|
|
|
47
59
|
console.error('Error ignored: ', e);
|
|
48
60
|
}
|
|
49
61
|
}
|
|
62
|
+
this.doDefer();
|
|
63
|
+
this.executing = false;
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
/**
|
|
@@ -61,18 +75,55 @@ export class Emitter<T> implements IDisposable {
|
|
|
61
75
|
* @param callback 回调函数
|
|
62
76
|
*/
|
|
63
77
|
handle(callback: EventHandler<T>): IDisposable {
|
|
64
|
-
this.
|
|
78
|
+
this.requireNotExecuting();
|
|
79
|
+
let disposed = false;
|
|
80
|
+
this._callbacks.unshift((e) => {
|
|
81
|
+
if (!disposed) callback(e);
|
|
82
|
+
});
|
|
83
|
+
const realDispose = () => {
|
|
84
|
+
const index = this._callbacks.indexOf(callback);
|
|
85
|
+
if (index !== -1) {
|
|
86
|
+
this._callbacks.splice(index, 1);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
65
89
|
return {
|
|
66
90
|
dispose: () => {
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
this.
|
|
91
|
+
disposed = true;
|
|
92
|
+
if (this.executing) {
|
|
93
|
+
this.defer(realDispose);
|
|
94
|
+
} else {
|
|
95
|
+
realDispose();
|
|
70
96
|
}
|
|
71
97
|
},
|
|
72
98
|
};
|
|
73
99
|
}
|
|
74
100
|
|
|
101
|
+
/**
|
|
102
|
+
* 注册一次性回调
|
|
103
|
+
* @param callback 回调函数
|
|
104
|
+
*/
|
|
105
|
+
once(callback: EventHandler<T>): IDisposable {
|
|
106
|
+
this.requireNotExecuting();
|
|
107
|
+
const disposable = this.handle((data) => {
|
|
108
|
+
callback(data);
|
|
109
|
+
disposable.dispose();
|
|
110
|
+
});
|
|
111
|
+
return disposable;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private defers: DeferFn[] = [];
|
|
115
|
+
public defer(fn: DeferFn) {
|
|
116
|
+
this.defers.push(fn);
|
|
117
|
+
}
|
|
118
|
+
private doDefer() {
|
|
119
|
+
for (const fn of this.defers) {
|
|
120
|
+
fn();
|
|
121
|
+
}
|
|
122
|
+
this.defers.length = 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
75
125
|
dispose() {
|
|
126
|
+
this.requireNotExecuting();
|
|
76
127
|
this._callbacks.length = 0;
|
|
77
128
|
this.fireNoError =
|
|
78
129
|
this.fire =
|
|
@@ -81,4 +132,10 @@ export class Emitter<T> implements IDisposable {
|
|
|
81
132
|
throw new Error('Event is disposed');
|
|
82
133
|
};
|
|
83
134
|
}
|
|
135
|
+
|
|
136
|
+
private requireNotExecuting() {
|
|
137
|
+
if (this.executing) {
|
|
138
|
+
throw new Error('conflict state, emitter is firing');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
84
141
|
}
|