async-reactivity 2.0.18 → 2.0.19
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/computed.js +1 -1
- package/lib/listener.js +9 -5
- package/lib/listener.test.js +20 -0
- package/package.json +1 -1
- package/src/computed.ts +4 -4
- package/src/dependency.ts +1 -1
- package/src/listener.test.ts +30 -0
- package/src/listener.ts +11 -6
- package/types/computed.d.ts.map +1 -1
- package/types/dependency.d.ts +1 -1
- package/types/dependency.d.ts.map +1 -1
- package/types/listener.d.ts +2 -1
- package/types/listener.d.ts.map +1 -1
package/lib/computed.js
CHANGED
|
@@ -82,7 +82,7 @@ export default class Computed extends Tracker {
|
|
|
82
82
|
}
|
|
83
83
|
clearDependencies() {
|
|
84
84
|
for (const dependency of this.dependencies.keys()) {
|
|
85
|
-
dependency.removeDependent(this);
|
|
85
|
+
dependency.removeDependent(this, this.computePromise);
|
|
86
86
|
}
|
|
87
87
|
this.dependencies.clear();
|
|
88
88
|
}
|
package/lib/listener.js
CHANGED
|
@@ -4,6 +4,7 @@ export default class Listener extends Ref {
|
|
|
4
4
|
start;
|
|
5
5
|
stop;
|
|
6
6
|
listening = false;
|
|
7
|
+
lastPromise;
|
|
7
8
|
constructor(_value, start, stop, isEqual = (defaultIsEqual)) {
|
|
8
9
|
super(_value, isEqual);
|
|
9
10
|
this.start = start;
|
|
@@ -16,13 +17,16 @@ export default class Listener extends Ref {
|
|
|
16
17
|
this.start();
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
|
-
removeDependent(dependent) {
|
|
20
|
+
removeDependent(dependent, promise = Promise.resolve()) {
|
|
20
21
|
super.removeDependent(dependent);
|
|
21
|
-
Promise.
|
|
22
|
-
if (this.
|
|
23
|
-
this.
|
|
24
|
-
|
|
22
|
+
const currentPromise = Promise.all([promise, this.lastPromise]).finally(() => {
|
|
23
|
+
if (this.lastPromise === currentPromise) {
|
|
24
|
+
if (this.dependents.size === 0) {
|
|
25
|
+
this.listening = false;
|
|
26
|
+
this.stop();
|
|
27
|
+
}
|
|
25
28
|
}
|
|
26
29
|
});
|
|
30
|
+
this.lastPromise = currentPromise;
|
|
27
31
|
}
|
|
28
32
|
}
|
package/lib/listener.test.js
CHANGED
|
@@ -75,4 +75,24 @@ describe('listener', function () {
|
|
|
75
75
|
b.value;
|
|
76
76
|
assert.strictEqual(gate, 1);
|
|
77
77
|
});
|
|
78
|
+
it('keep listening when recomputing async', async function () {
|
|
79
|
+
let gate = 0;
|
|
80
|
+
const listener = new Listener(1, () => {
|
|
81
|
+
gate++;
|
|
82
|
+
}, () => { });
|
|
83
|
+
const a = new Ref(5);
|
|
84
|
+
const b = new Computed(async (value) => {
|
|
85
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
86
|
+
return value(a) + value(listener);
|
|
87
|
+
});
|
|
88
|
+
const c = new Watcher(listener, () => { });
|
|
89
|
+
b.value;
|
|
90
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
91
|
+
assert.strictEqual(gate, 1);
|
|
92
|
+
a.value = 6;
|
|
93
|
+
b.value;
|
|
94
|
+
c.dispose();
|
|
95
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
96
|
+
assert.strictEqual(gate, 1);
|
|
97
|
+
});
|
|
78
98
|
});
|
package/package.json
CHANGED
package/src/computed.ts
CHANGED
|
@@ -21,7 +21,7 @@ export default class Computed<T extends TBase, TBase = T> extends Tracker<T> imp
|
|
|
21
21
|
isEqual: typeof defaultIsEqual<TBase>;
|
|
22
22
|
private state = ComputedState.Invalid;
|
|
23
23
|
private dependencies = new Map<Dependency<any>, boolean>();
|
|
24
|
-
private computePromise?:
|
|
24
|
+
private computePromise?: Promise<any>;
|
|
25
25
|
private computePromiseActions?: { resolve: Function, reject: Function };
|
|
26
26
|
private lastComputeAttemptPromise?: Promise<void>;
|
|
27
27
|
|
|
@@ -38,7 +38,7 @@ export default class Computed<T extends TBase, TBase = T> extends Tracker<T> imp
|
|
|
38
38
|
resolve,
|
|
39
39
|
reject
|
|
40
40
|
};
|
|
41
|
-
})
|
|
41
|
+
});
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
public get value(): T {
|
|
@@ -83,7 +83,7 @@ export default class Computed<T extends TBase, TBase = T> extends Tracker<T> imp
|
|
|
83
83
|
.then(result => this.handlePromiseThen(computeAttemptPromise, result))
|
|
84
84
|
.catch(error => this.handlePromiseCatch(computeAttemptPromise, error)) as Promise<void>;
|
|
85
85
|
this.lastComputeAttemptPromise = computeAttemptPromise;
|
|
86
|
-
this._value = this.computePromise
|
|
86
|
+
this._value = this.computePromise! as T;
|
|
87
87
|
} else {
|
|
88
88
|
this._value = newValue;
|
|
89
89
|
this.handlePromiseThen(this.lastComputeAttemptPromise!, this._value);
|
|
@@ -93,7 +93,7 @@ export default class Computed<T extends TBase, TBase = T> extends Tracker<T> imp
|
|
|
93
93
|
|
|
94
94
|
private clearDependencies() {
|
|
95
95
|
for (const dependency of this.dependencies.keys()) {
|
|
96
|
-
dependency.removeDependent(this);
|
|
96
|
+
dependency.removeDependent(this, this.computePromise);
|
|
97
97
|
}
|
|
98
98
|
this.dependencies.clear();
|
|
99
99
|
}
|
package/src/dependency.ts
CHANGED
package/src/listener.test.ts
CHANGED
|
@@ -120,4 +120,34 @@ describe('listener', function () {
|
|
|
120
120
|
b.value;
|
|
121
121
|
assert.strictEqual(gate, 1);
|
|
122
122
|
});
|
|
123
|
+
|
|
124
|
+
it('keep listening when recomputing async', async function() {
|
|
125
|
+
let gate = 0;
|
|
126
|
+
const listener = new Listener(
|
|
127
|
+
1,
|
|
128
|
+
() => {
|
|
129
|
+
gate++;
|
|
130
|
+
},
|
|
131
|
+
() => {}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const a = new Ref(5);
|
|
135
|
+
|
|
136
|
+
const b = new Computed(async value => {
|
|
137
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
138
|
+
return value(a) + value(listener);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const c = new Watcher(listener, () => {});
|
|
142
|
+
|
|
143
|
+
b.value;
|
|
144
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
145
|
+
assert.strictEqual(gate, 1);
|
|
146
|
+
|
|
147
|
+
a.value = 6;
|
|
148
|
+
b.value;
|
|
149
|
+
c.dispose();
|
|
150
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
151
|
+
assert.strictEqual(gate, 1);
|
|
152
|
+
});
|
|
123
153
|
});
|
package/src/listener.ts
CHANGED
|
@@ -6,6 +6,7 @@ export default class Listener<T extends TBase, TBase = T> extends Ref<T> {
|
|
|
6
6
|
private start: () => void;
|
|
7
7
|
private stop: () => void;
|
|
8
8
|
private listening = false;
|
|
9
|
+
private lastPromise: Promise<any> | undefined;
|
|
9
10
|
|
|
10
11
|
constructor(_value: T, start: () => void, stop: () => void, isEqual = defaultIsEqual<TBase>) {
|
|
11
12
|
super(_value, isEqual);
|
|
@@ -22,13 +23,17 @@ export default class Listener<T extends TBase, TBase = T> extends Ref<T> {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
public removeDependent(dependent: Dependent): void {
|
|
26
|
+
public removeDependent(dependent: Dependent, promise = Promise.resolve()): void {
|
|
26
27
|
super.removeDependent(dependent);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.
|
|
28
|
+
|
|
29
|
+
const currentPromise = Promise.all([promise, this.lastPromise]).finally(() => {
|
|
30
|
+
if (this.lastPromise === currentPromise) {
|
|
31
|
+
if (this.dependents.size === 0) {
|
|
32
|
+
this.listening = false;
|
|
33
|
+
this.stop();
|
|
34
|
+
}
|
|
31
35
|
}
|
|
32
|
-
})
|
|
36
|
+
});
|
|
37
|
+
this.lastPromise = currentPromise;
|
|
33
38
|
}
|
|
34
39
|
}
|
package/types/computed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,cAAc,MAAM,qBAAqB,CAAC;AAEjD,MAAM,CAAC,OAAO,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACrE,MAAM,CAAC,OAAO,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACjF,MAAM,CAAC,OAAO,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;AAWzG,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,GAAG,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAE,YAAW,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAC5G,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,cAAc,MAAM,qBAAqB,CAAC;AAEjD,MAAM,CAAC,OAAO,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACrE,MAAM,CAAC,OAAO,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACjF,MAAM,CAAC,OAAO,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;AAWzG,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,GAAG,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAE,YAAW,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAC5G,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAe;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAA0C;IACxE,OAAO,CAAC,yBAAyB,CAAC,CAAgB;gBAEtC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,oCAAwB;IAOnE,OAAO,CAAC,qBAAqB;IAS7B,IAAW,KAAK,IAAI,CAAC,CAMpB;IAED,OAAO,CAAC,OAAO;IA0Cf,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,eAAe,CAAwC;IAE/D,OAAO,CAAC,iBAAiB;IAMlB,UAAU;IAUV,eAAe;IAKf,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC;IAI3C,OAAO,CAAC,kBAAkB;IAMnB,OAAO;CAOjB"}
|
package/types/dependency.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import Dependent from "./dependent.js";
|
|
|
2
2
|
export default interface Dependency<T> {
|
|
3
3
|
get value(): T;
|
|
4
4
|
addDependent(dependent: Dependent): void;
|
|
5
|
-
removeDependent(dependent: Dependent): void;
|
|
5
|
+
removeDependent(dependent: Dependent, promise?: Promise<any>): void;
|
|
6
6
|
}
|
|
7
7
|
//# sourceMappingURL=dependency.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../src/dependency.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAEvC,MAAM,CAAC,OAAO,WAAW,UAAU,CAAC,CAAC;IACjC,IAAI,KAAK,IAAI,CAAC,CAAC;IACf,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IACzC,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../src/dependency.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAEvC,MAAM,CAAC,OAAO,WAAW,UAAU,CAAC,CAAC;IACjC,IAAI,KAAK,IAAI,CAAC,CAAC;IACf,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IACzC,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;CACvE"}
|
package/types/listener.d.ts
CHANGED
|
@@ -4,8 +4,9 @@ export default class Listener<T extends TBase, TBase = T> extends Ref<T> {
|
|
|
4
4
|
private start;
|
|
5
5
|
private stop;
|
|
6
6
|
private listening;
|
|
7
|
+
private lastPromise;
|
|
7
8
|
constructor(_value: T, start: () => void, stop: () => void, isEqual?: (v1: TBase, v2: TBase) => boolean);
|
|
8
9
|
addDependent(dependent: Dependent): void;
|
|
9
|
-
removeDependent(dependent: Dependent): void;
|
|
10
|
+
removeDependent(dependent: Dependent, promise?: Promise<void>): void;
|
|
10
11
|
}
|
|
11
12
|
//# sourceMappingURL=listener.d.ts.map
|
package/types/listener.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,GAAG,MAAM,UAAU,CAAC;AAG3B,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,GAAG,CAAC,CAAE,SAAQ,GAAG,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAAS;
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,GAAG,MAAM,UAAU,CAAC;AAG3B,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,GAAG,CAAC,CAAE,SAAQ,GAAG,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAA2B;gBAElC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,OAAO,oCAAwB;IAOpF,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAQxC,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,gBAAoB,GAAG,IAAI;CAalF"}
|