async-reactivity 2.0.21 → 2.0.23

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 CHANGED
@@ -9,7 +9,6 @@ var ComputedState;
9
9
  ComputedState[ComputedState["Uncertain"] = 2] = "Uncertain";
10
10
  ComputedState[ComputedState["Computing"] = 3] = "Computing";
11
11
  })(ComputedState || (ComputedState = {}));
12
- ;
13
12
  class CircularDependencyError extends Error {
14
13
  }
15
14
  export default class Computed extends Tracker {
@@ -21,6 +20,7 @@ export default class Computed extends Tracker {
21
20
  computePromiseActions;
22
21
  lastComputeAttemptPromise;
23
22
  deferrer;
23
+ abortController;
24
24
  constructor(getter, isEqual = (defaultIsEqual), timeToLive) {
25
25
  super();
26
26
  this.getter = getter;
@@ -70,9 +70,13 @@ export default class Computed extends Tracker {
70
70
  return this._value;
71
71
  }
72
72
  }
73
+ else if (this.state === ComputedState.Computing) {
74
+ this.abortController?.abort();
75
+ }
73
76
  this.state = ComputedState.Computing;
74
77
  this.clearDependencies(true);
75
- const newValue = this.getter(this.trackDependency, this._value);
78
+ this.abortController = new AbortController();
79
+ const newValue = this.getter(this.trackDependency, this._value, this.abortController.signal);
76
80
  if (this.isEqual(newValue, this._value)) {
77
81
  this.handlePromiseThen(this.lastComputeAttemptPromise, this._value);
78
82
  this.validateDependents();
@@ -120,6 +124,7 @@ export default class Computed extends Tracker {
120
124
  finalizeComputing() {
121
125
  this.state = ComputedState.Valid;
122
126
  this.lastComputeAttemptPromise = undefined;
127
+ this.abortController = undefined;
123
128
  this.prepareComputePromise();
124
129
  }
125
130
  invalidate() {
@@ -134,7 +139,9 @@ export default class Computed extends Tracker {
134
139
  }
135
140
  forceInvalidate() {
136
141
  this.invalidate();
137
- this.state = ComputedState.Invalid;
142
+ if (this.state !== ComputedState.Computing) {
143
+ this.state = ComputedState.Invalid;
144
+ }
138
145
  }
139
146
  validate(dependency) {
140
147
  this.dependencies.set(dependency, false);
@@ -130,6 +130,22 @@ describe('computed', function () {
130
130
  assert.strictEqual(c.value, 6);
131
131
  assert.strictEqual(gate, 2);
132
132
  });
133
+ it('compute and abort when forced', async function () {
134
+ let gate = 0;
135
+ const b = new Computed(async (_value, _previousValue, abortSignal) => {
136
+ await new Promise(resolve => setTimeout(resolve, 10));
137
+ if (abortSignal.aborted) {
138
+ gate++;
139
+ throw new Error();
140
+ }
141
+ return 5;
142
+ });
143
+ const v = b.value;
144
+ await new Promise(resolve => setTimeout(resolve, 5));
145
+ b.forceInvalidate();
146
+ assert.strictEqual(await v, 5);
147
+ assert.strictEqual(gate, 1);
148
+ });
133
149
  it('isEqual', function () {
134
150
  const a = new Ref(1);
135
151
  const b = new Computed((value) => {
@@ -186,6 +202,23 @@ describe('async computed', function () {
186
202
  a.value = 8;
187
203
  assert.strictEqual(await b.value, 13);
188
204
  });
205
+ it('dependency changed while computing - abortSignal', async function () {
206
+ const a = new Ref(5);
207
+ let gate = 0;
208
+ const b = new Computed(async (value, _previousValue, abortSignal) => {
209
+ const dep = value(a);
210
+ await new Promise(resolve => setTimeout(resolve, 10));
211
+ if (abortSignal.aborted) {
212
+ throw new Error();
213
+ }
214
+ gate++;
215
+ return dep + 5;
216
+ });
217
+ b.value; // trigger compute
218
+ a.value = 8;
219
+ await b.value;
220
+ assert.strictEqual(gate, 1);
221
+ });
189
222
  it('old dependency changed while computing', async function () {
190
223
  let gate = 0;
191
224
  const a = new Ref(5);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "async-reactivity",
3
- "version": "2.0.21",
3
+ "version": "2.0.23",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "types/index.d.ts",
@@ -153,6 +153,24 @@ describe('computed', function () {
153
153
  assert.strictEqual(gate, 2);
154
154
  });
155
155
 
156
+ it('compute and abort when forced', async function () {
157
+ let gate = 0;
158
+ const b = new Computed(async (_value, _previousValue, abortSignal) => {
159
+ await new Promise(resolve => setTimeout(resolve, 10));
160
+ if (abortSignal.aborted) {
161
+ gate++;
162
+ throw new Error();
163
+ }
164
+ return 5;
165
+ });
166
+
167
+ const v = b.value;
168
+ await new Promise(resolve => setTimeout(resolve, 5));
169
+ b.forceInvalidate();
170
+ assert.strictEqual(await v, 5);
171
+ assert.strictEqual(gate, 1);
172
+ });
173
+
156
174
  it('isEqual', function() {
157
175
  const a = new Ref(1);
158
176
  const b = new Computed((value) => {
@@ -219,6 +237,24 @@ describe('async computed', function () {
219
237
  assert.strictEqual(await b.value, 13);
220
238
  });
221
239
 
240
+ it('dependency changed while computing - abortSignal', async function () {
241
+ const a = new Ref(5);
242
+ let gate = 0;
243
+ const b = new Computed(async (value, _previousValue, abortSignal) => {
244
+ const dep = value(a);
245
+ await new Promise(resolve => setTimeout(resolve, 10));
246
+ if (abortSignal.aborted) {
247
+ throw new Error();
248
+ }
249
+ gate++;
250
+ return dep + 5;
251
+ });
252
+ b.value; // trigger compute
253
+ a.value = 8;
254
+ await b.value;
255
+ assert.strictEqual(gate, 1);
256
+ });
257
+
222
258
  it('old dependency changed while computing', async function () {
223
259
  let gate = 0;
224
260
  const a = new Ref(5);
package/src/computed.ts CHANGED
@@ -6,15 +6,15 @@ import { Deferrer } from "./deferrer.js";
6
6
  import { debounce } from 'lodash-es';
7
7
 
8
8
  export declare type TrackValue = <T>(dependency: Dependency<T>) => T;
9
- export declare type ComputeFunc<T> = (value: TrackValue, previousValue?: T) => T;
10
- export declare type ComputeFuncScoped<T1, T2> = (value: TrackValue, scope: T1, previousValue?: T2) => T2;
9
+ export declare type ComputeFunc<T> = (value: TrackValue, previousValue: T | undefined, abortSignal: AbortSignal) => T;
10
+ export declare type ComputeFuncScoped<T1, T2> = (value: TrackValue, scope: T1, previousValue: T2 | undefined, abortSignal: AbortSignal) => T2;
11
11
 
12
12
  enum ComputedState {
13
13
  Invalid,
14
14
  Valid,
15
15
  Uncertain,
16
16
  Computing
17
- };
17
+ }
18
18
 
19
19
  class CircularDependencyError extends Error { }
20
20
 
@@ -27,6 +27,7 @@ export default class Computed<T> extends Tracker<T> implements Dependent, Depend
27
27
  private computePromiseActions?: { resolve: Function, reject: Function };
28
28
  private lastComputeAttemptPromise?: Promise<void>;
29
29
  private deferrer?: Deferrer;
30
+ private abortController?: AbortController;
30
31
 
31
32
  constructor(getter: ComputeFunc<T>, isEqual = defaultIsEqual<T>, timeToLive?: number) {
32
33
  super();
@@ -80,12 +81,15 @@ export default class Computed<T> extends Tracker<T> implements Dependent, Depend
80
81
  this.validateDependents();
81
82
  return this._value!;
82
83
  }
84
+ } else if (this.state === ComputedState.Computing) {
85
+ this.abortController?.abort();
83
86
  }
84
87
 
85
88
  this.state = ComputedState.Computing;
86
89
  this.clearDependencies(true);
90
+ this.abortController = new AbortController();
87
91
 
88
- const newValue: T = this.getter(this.trackDependency, this._value);
92
+ const newValue: T = this.getter(this.trackDependency, this._value, this.abortController.signal);
89
93
  if (this.isEqual(newValue, this._value!)) {
90
94
  this.handlePromiseThen(this.lastComputeAttemptPromise!, this._value);
91
95
  this.validateDependents();
@@ -137,6 +141,7 @@ export default class Computed<T> extends Tracker<T> implements Dependent, Depend
137
141
  private finalizeComputing() {
138
142
  this.state = ComputedState.Valid;
139
143
  this.lastComputeAttemptPromise = undefined;
144
+ this.abortController = undefined;
140
145
  this.prepareComputePromise();
141
146
  }
142
147
 
@@ -152,7 +157,9 @@ export default class Computed<T> extends Tracker<T> implements Dependent, Depend
152
157
 
153
158
  public forceInvalidate() {
154
159
  this.invalidate();
155
- this.state = ComputedState.Invalid;
160
+ if (this.state !== ComputedState.Computing) {
161
+ this.state = ComputedState.Invalid;
162
+ }
156
163
  }
157
164
 
158
165
  public validate(dependency: Dependency<any>) {
@@ -3,8 +3,8 @@ import Dependent from "./dependent.js";
3
3
  import Tracker from "./tracker.js";
4
4
  import defaultIsEqual from "./defaultIsEqual.js";
5
5
  export declare type TrackValue = <T>(dependency: Dependency<T>) => T;
6
- export declare type ComputeFunc<T> = (value: TrackValue, previousValue?: T) => T;
7
- export declare type ComputeFuncScoped<T1, T2> = (value: TrackValue, scope: T1, previousValue?: T2) => T2;
6
+ export declare type ComputeFunc<T> = (value: TrackValue, previousValue: T | undefined, abortSignal: AbortSignal) => T;
7
+ export declare type ComputeFuncScoped<T1, T2> = (value: TrackValue, scope: T1, previousValue: T2 | undefined, abortSignal: AbortSignal) => T2;
8
8
  export default class Computed<T> extends Tracker<T> implements Dependent, Dependency<T> {
9
9
  getter: ComputeFunc<T>;
10
10
  isEqual: typeof defaultIsEqual<T>;
@@ -14,6 +14,7 @@ export default class Computed<T> extends Tracker<T> implements Dependent, Depend
14
14
  private computePromiseActions?;
15
15
  private lastComputeAttemptPromise?;
16
16
  private deferrer?;
17
+ private abortController?;
17
18
  constructor(getter: ComputeFunc<T>, isEqual?: (v1: T, v2: T) => boolean, timeToLive?: number);
18
19
  private prepareComputePromise;
19
20
  get value(): T;
@@ -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;AAIjD,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,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAE,YAAW,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACnF,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC;IAClC,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;IAClD,OAAO,CAAC,QAAQ,CAAC,CAAW;gBAEhB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,4BAAoB,EAAE,UAAU,CAAC,EAAE,MAAM;IAepF,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,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,gBAAoB,GAAG,IAAI;IAKxE,KAAK;IAQL,OAAO;CAGjB"}
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;AAIjD,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,EAAE,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,WAAW,KAAK,CAAC,CAAC;AACtH,MAAM,CAAC,OAAO,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,GAAG,SAAS,EAAE,WAAW,EAAE,WAAW,KAAK,EAAE,CAAC;AAW9I,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAE,YAAW,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACnF,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC;IAClC,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;IAClD,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,eAAe,CAAC,CAAkB;gBAE9B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,4BAAoB,EAAE,UAAU,CAAC,EAAE,MAAM;IAepF,OAAO,CAAC,qBAAqB;IAS7B,IAAW,KAAK,IAAI,CAAC,CAMpB;IAED,OAAO,CAAC,OAAO;IA6Cf,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;IAOlB,UAAU;IAUV,eAAe;IAOf,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC;IAI3C,OAAO,CAAC,kBAAkB;IAMnB,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,gBAAoB,GAAG,IAAI;IAKxE,KAAK;IAQL,OAAO;CAGjB"}