async-reactivity 1.1.2 → 1.1.3

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/ref.js CHANGED
@@ -1,23 +1,23 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const tracker_js_1 = __importDefault(require("./tracker.js"));
7
- class Ref extends tracker_js_1.default {
8
- constructor(_value) {
9
- super();
10
- this._value = _value;
11
- }
12
- set value(_value) {
13
- const lastValue = this._value;
14
- this._value = _value;
15
- if (lastValue !== _value) {
16
- this.invalidate();
17
- }
18
- }
19
- get value() {
20
- return super.value;
21
- }
22
- }
23
- exports.default = Ref;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const tracker_js_1 = __importDefault(require("./tracker.js"));
7
+ class Ref extends tracker_js_1.default {
8
+ constructor(_value) {
9
+ super();
10
+ this._value = _value;
11
+ }
12
+ set value(_value) {
13
+ const lastValue = this._value;
14
+ this._value = _value;
15
+ if (lastValue !== _value) {
16
+ this.invalidate();
17
+ }
18
+ }
19
+ get value() {
20
+ return super.value;
21
+ }
22
+ }
23
+ exports.default = Ref;
package/lib/tracker.js CHANGED
@@ -1,22 +1,22 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class Tracker {
4
- constructor() {
5
- this.dependents = new Set();
6
- }
7
- addDependent(dependent) {
8
- this.dependents.add(dependent);
9
- }
10
- removeDependent(dependent) {
11
- this.dependents.delete(dependent);
12
- }
13
- invalidate() {
14
- for (const dependent of [...this.dependents.keys()]) {
15
- dependent.invalidate();
16
- }
17
- }
18
- get value() {
19
- return this._value;
20
- }
21
- }
22
- exports.default = Tracker;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Tracker {
4
+ constructor() {
5
+ this.dependents = new Set();
6
+ }
7
+ addDependent(dependent) {
8
+ this.dependents.add(dependent);
9
+ }
10
+ removeDependent(dependent) {
11
+ this.dependents.delete(dependent);
12
+ }
13
+ invalidate() {
14
+ for (const dependent of [...this.dependents.keys()]) {
15
+ dependent.invalidate();
16
+ }
17
+ }
18
+ get value() {
19
+ return this._value;
20
+ }
21
+ }
22
+ exports.default = Tracker;
package/lib/watcher.js CHANGED
@@ -1,41 +1,41 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const tracker_js_1 = __importDefault(require("./tracker.js"));
7
- var WatchState;
8
- (function (WatchState) {
9
- WatchState[WatchState["Uncertain"] = 0] = "Uncertain";
10
- WatchState[WatchState["Valid"] = 1] = "Valid";
11
- })(WatchState || (WatchState = {}));
12
- ;
13
- class Watcher extends tracker_js_1.default {
14
- constructor(dependency, onChange, immediate = true) {
15
- super();
16
- this.state = WatchState.Valid;
17
- this.onChange = onChange;
18
- this.dependency = dependency;
19
- dependency.addDependent(this);
20
- this._value = dependency.value;
21
- if (immediate) {
22
- onChange(this._value);
23
- }
24
- }
25
- invalidate() {
26
- this.state = WatchState.Uncertain;
27
- const oldValue = this._value;
28
- this._value = this.dependency.value;
29
- if (this.state === WatchState.Uncertain) {
30
- this.onChange(this._value, oldValue);
31
- this.state = WatchState.Valid;
32
- }
33
- }
34
- validate() {
35
- this.state = WatchState.Valid;
36
- }
37
- dispose() {
38
- this.dependency.removeDependent(this);
39
- }
40
- }
41
- exports.default = Watcher;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const tracker_js_1 = __importDefault(require("./tracker.js"));
7
+ var WatchState;
8
+ (function (WatchState) {
9
+ WatchState[WatchState["Uncertain"] = 0] = "Uncertain";
10
+ WatchState[WatchState["Valid"] = 1] = "Valid";
11
+ })(WatchState || (WatchState = {}));
12
+ ;
13
+ class Watcher extends tracker_js_1.default {
14
+ constructor(dependency, onChange, immediate = true) {
15
+ super();
16
+ this.state = WatchState.Valid;
17
+ this.onChange = onChange;
18
+ this.dependency = dependency;
19
+ dependency.addDependent(this);
20
+ this._value = dependency.value;
21
+ if (immediate) {
22
+ onChange(this._value);
23
+ }
24
+ }
25
+ invalidate() {
26
+ this.state = WatchState.Uncertain;
27
+ const oldValue = this._value;
28
+ this._value = this.dependency.value;
29
+ if (this.state === WatchState.Uncertain) {
30
+ this.onChange(this._value, oldValue);
31
+ this.state = WatchState.Valid;
32
+ }
33
+ }
34
+ validate() {
35
+ this.state = WatchState.Valid;
36
+ }
37
+ dispose() {
38
+ this.dependency.removeDependent(this);
39
+ }
40
+ }
41
+ exports.default = Watcher;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "async-reactivity",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "types/index.d.ts",
@@ -17,9 +17,9 @@
17
17
  "author": "Donatas Lučiūnas",
18
18
  "license": "ISC",
19
19
  "devDependencies": {
20
- "@types/mocha": "^9.1.1",
21
- "@types/node": "^17.0.41",
22
- "mocha": "^10.0.0",
23
- "typescript": "^4.7.3"
20
+ "@types/mocha": "^10.0.6",
21
+ "@types/node": "^20.10.5",
22
+ "mocha": "^10.2.0",
23
+ "typescript": "^5.3.3"
24
24
  }
25
25
  }
package/src/computed.ts CHANGED
@@ -121,7 +121,8 @@ export default class Computed<T> extends Tracker<T> implements Dependent, Depend
121
121
 
122
122
  public invalidate() {
123
123
  if (this.state === ComputedState.Computing) {
124
- setTimeout(this.compute.bind(this));
124
+ this.lastComputeAttemptPromise = undefined; // prevent finalizeComputing if it is in the event loop already
125
+ Promise.resolve().then(this.compute.bind(this));
125
126
  } else if (this.state === ComputedState.Valid) {
126
127
  this.state = ComputedState.Uncertain;
127
128
  super.invalidate();
package/src/index.test.ts CHANGED
@@ -173,6 +173,14 @@ describe('async reactivity', function () {
173
173
  assert.rejects(async () => await a.value);
174
174
  });
175
175
 
176
+ it('dependency changed while computing', async function () {
177
+ const a = new Ref(5);
178
+ const b = new Computed(async (value) => value(a) + 5);
179
+ b.value; // trigger compute
180
+ a.value = 8;
181
+ assert.strictEqual(await b.value, 13);
182
+ });
183
+
176
184
  it('old dependency changed while computing', async function () {
177
185
  let gate = 0;
178
186
  const a = new Ref(5);
@@ -1,30 +1,30 @@
1
- import Dependency from "./dependency.js";
2
- import Dependent from "./dependent.js";
3
- import Tracker from "./tracker.js";
4
- declare type TrackValue = <T>(dependency: Dependency<T>) => T;
5
- export declare type ComputeFunc<T> = (value: TrackValue) => T;
6
- export declare type ComputeFuncScoped<T1, T2> = (value: TrackValue, scope: T1) => T2;
7
- export default class Computed<T> extends Tracker<T> implements Dependent, Dependency<T> {
8
- getter: ComputeFunc<T>;
9
- private state;
10
- private dependencies;
11
- private computePromise?;
12
- private computePromiseActions?;
13
- private lastComputeAttemptPromise?;
14
- constructor(getter: ComputeFunc<T>);
15
- private prepareComputePromise;
16
- get value(): T;
17
- private compute;
18
- private clearDependencies;
19
- private handlePromiseThen;
20
- private handlePromiseCatch;
21
- private innerTrackDependency;
22
- private trackDependency;
23
- private finalizeComputing;
24
- invalidate(): void;
25
- validate(dependency: Dependency<any>): void;
26
- private validateDependents;
27
- dispose(): void;
28
- }
29
- export {};
1
+ import Dependency from "./dependency.js";
2
+ import Dependent from "./dependent.js";
3
+ import Tracker from "./tracker.js";
4
+ declare type TrackValue = <T>(dependency: Dependency<T>) => T;
5
+ export declare type ComputeFunc<T> = (value: TrackValue) => T;
6
+ export declare type ComputeFuncScoped<T1, T2> = (value: TrackValue, scope: T1) => T2;
7
+ export default class Computed<T> extends Tracker<T> implements Dependent, Dependency<T> {
8
+ getter: ComputeFunc<T>;
9
+ private state;
10
+ private dependencies;
11
+ private computePromise?;
12
+ private computePromiseActions?;
13
+ private lastComputeAttemptPromise?;
14
+ constructor(getter: ComputeFunc<T>);
15
+ private prepareComputePromise;
16
+ get value(): T;
17
+ private compute;
18
+ private clearDependencies;
19
+ private handlePromiseThen;
20
+ private handlePromiseCatch;
21
+ private innerTrackDependency;
22
+ private trackDependency;
23
+ private finalizeComputing;
24
+ invalidate(): void;
25
+ validate(dependency: Dependency<any>): void;
26
+ private validateDependents;
27
+ dispose(): void;
28
+ }
29
+ export {};
30
30
  //# sourceMappingURL=computed.d.ts.map
@@ -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;AAEnC,OAAO,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC9D,MAAM,CAAC,OAAO,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,CAAC,CAAC;AAC9D,MAAM,CAAC,OAAO,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC;AAWrF,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,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAI;IAC3B,OAAO,CAAC,qBAAqB,CAAC,CAA0C;IACxE,OAAO,CAAC,yBAAyB,CAAC,CAAgB;gBAEtC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAMlC,OAAO,CAAC,qBAAqB;IAS7B,IAAW,KAAK,IAAI,CAAC,CAMpB;IAED,OAAO,CAAC,OAAO;IAmCf,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;IASV,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC;IAI3C,OAAO,CAAC,kBAAkB;IAMnB,OAAO;CAOjB"}
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;AAEnC,OAAO,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC9D,MAAM,CAAC,OAAO,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,CAAC,CAAC;AAC9D,MAAM,CAAC,OAAO,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC;AAWrF,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,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAI;IAC3B,OAAO,CAAC,qBAAqB,CAAC,CAA0C;IACxE,OAAO,CAAC,yBAAyB,CAAC,CAAgB;gBAEtC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAMlC,OAAO,CAAC,qBAAqB;IAS7B,IAAW,KAAK,IAAI,CAAC,CAMpB;IAED,OAAO,CAAC,OAAO;IAmCf,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,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC;IAI3C,OAAO,CAAC,kBAAkB;IAMnB,OAAO;CAOjB"}
@@ -1,7 +1,7 @@
1
- import Dependent from "./dependent.js";
2
- export default interface Dependency<T> {
3
- get value(): T;
4
- addDependent(dependent: Dependent): void;
5
- removeDependent(dependent: Dependent): void;
6
- }
1
+ import Dependent from "./dependent.js";
2
+ export default interface Dependency<T> {
3
+ get value(): T;
4
+ addDependent(dependent: Dependent): void;
5
+ removeDependent(dependent: Dependent): void;
6
+ }
7
7
  //# sourceMappingURL=dependency.d.ts.map
@@ -1,7 +1,7 @@
1
- import Dependency from "./dependency.js";
2
- export default interface Dependent {
3
- invalidate(): void;
4
- validate(dependency: Dependency<any>): void;
5
- dispose(): void;
6
- }
1
+ import Dependency from "./dependency.js";
2
+ export default interface Dependent {
3
+ invalidate(): void;
4
+ validate(dependency: Dependency<any>): void;
5
+ dispose(): void;
6
+ }
7
7
  //# sourceMappingURL=dependent.d.ts.map
package/types/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { default as Computed, ComputeFunc, ComputeFuncScoped } from './computed.js';
2
- export { default as Ref } from './ref.js';
3
- export { default as Watcher } from './watcher.js';
4
- export { default as Dependency } from './dependency.js';
5
- export { default as Dependent } from './dependent.js';
1
+ export { default as Computed, ComputeFunc, ComputeFuncScoped } from './computed.js';
2
+ export { default as Ref } from './ref.js';
3
+ export { default as Watcher } from './watcher.js';
4
+ export { default as Dependency } from './dependency.js';
5
+ export { default as Dependent } from './dependent.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,2 @@
1
- import 'mocha';
1
+ import 'mocha';
2
2
  //# sourceMappingURL=index.test.d.ts.map
package/types/ref.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import Dependency from "./dependency.js";
2
- import Tracker from "./tracker.js";
3
- export default class Ref<T> extends Tracker<T> implements Dependency<T> {
4
- constructor(_value: T);
5
- set value(_value: T);
6
- get value(): T;
7
- }
1
+ import Dependency from "./dependency.js";
2
+ import Tracker from "./tracker.js";
3
+ export default class Ref<T> extends Tracker<T> implements Dependency<T> {
4
+ constructor(_value: T);
5
+ set value(_value: T);
6
+ get value(): T;
7
+ }
8
8
  //# sourceMappingURL=ref.d.ts.map
@@ -1,13 +1,13 @@
1
- import Computed from "./computed.js";
2
- import Watcher from "./watcher.js";
3
- type Dependent = Computed<any> | Watcher<any>;
4
- export default class Tracker<T> {
5
- protected dependents: Set<Dependent>;
6
- protected _value?: T;
7
- addDependent(dependent: Dependent): void;
8
- removeDependent(dependent: Dependent): void;
9
- invalidate(): void;
10
- get value(): T | undefined;
11
- }
12
- export {};
1
+ import Computed from "./computed.js";
2
+ import Watcher from "./watcher.js";
3
+ type Dependent = Computed<any> | Watcher<any>;
4
+ export default class Tracker<T> {
5
+ protected dependents: Set<Dependent>;
6
+ protected _value?: T;
7
+ addDependent(dependent: Dependent): void;
8
+ removeDependent(dependent: Dependent): void;
9
+ invalidate(): void;
10
+ get value(): T | undefined;
11
+ }
12
+ export {};
13
13
  //# sourceMappingURL=tracker.d.ts.map
@@ -1,15 +1,15 @@
1
- import Dependency from "./dependency.js";
2
- import Dependent from "./dependent.js";
3
- import Tracker from "./tracker.js";
4
- type onChangeFunc<T> = (newValue: T, oldValue?: T) => void;
5
- export default class Watcher<T> extends Tracker<T> implements Dependent {
6
- private onChange;
7
- private dependency;
8
- private state;
9
- constructor(dependency: Dependency<T>, onChange: onChangeFunc<T>, immediate?: boolean);
10
- invalidate(): void;
11
- validate(): void;
12
- dispose(): void;
13
- }
14
- export {};
1
+ import Dependency from "./dependency.js";
2
+ import Dependent from "./dependent.js";
3
+ import Tracker from "./tracker.js";
4
+ type onChangeFunc<T> = (newValue: T, oldValue?: T) => void;
5
+ export default class Watcher<T> extends Tracker<T> implements Dependent {
6
+ private onChange;
7
+ private dependency;
8
+ private state;
9
+ constructor(dependency: Dependency<T>, onChange: onChangeFunc<T>, immediate?: boolean);
10
+ invalidate(): void;
11
+ validate(): void;
12
+ dispose(): void;
13
+ }
14
+ export {};
15
15
  //# sourceMappingURL=watcher.d.ts.map