@fbltd/async 1.0.39 → 1.0.40

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.
@@ -1,5 +1,6 @@
1
1
  import { Dependency } from "./dependency.js";
2
2
  import { reaction } from "./vanilla/index.js";
3
+ import { getStream } from "./vanilla/get.stream.js";
3
4
  export class DepFactory {
4
5
  static ofValue(value, config) {
5
6
  return new Dependency(value, config);
@@ -7,4 +8,7 @@ export class DepFactory {
7
8
  static ofReaction(fn, config) {
8
9
  return reaction(fn, config);
9
10
  }
11
+ static ofDependency(dep) {
12
+ return getStream(dep);
13
+ }
10
14
  }
@@ -45,29 +45,28 @@ export class Dependency {
45
45
  let firstPromise;
46
46
  const withReactionOnSubscribe = this.config.withReactionOnSubscribe || thisStreamConfig.withReactionOnSubscribe;
47
47
  if (withReactionOnSubscribe) {
48
- firstPromise = new PromiseConfiguration();
49
- firstPromise.resolve();
50
- externalPromises.push(firstPromise.promise);
48
+ firstPromise = Promise.resolve();
49
+ externalPromises.push(firstPromise);
51
50
  }
52
51
  const owner = this;
53
52
  return {
54
53
  owner,
55
- dispose: () => { },
54
+ dispose: owner.dispose.bind(owner),
56
55
  get isDisposed() {
57
- return false;
56
+ return owner.done;
58
57
  },
59
58
  next: async () => {
60
59
  await Promise.race([
61
60
  owner.next(),
62
61
  ...externalPromises,
63
62
  ]);
64
- if (this.done) {
65
- return { done: true };
66
- }
67
63
  if (firstPromise) {
68
64
  firstPromise = undefined;
69
65
  externalPromises.pop();
70
66
  }
67
+ if (this.done) {
68
+ return { done: true };
69
+ }
71
70
  return {
72
71
  done: false,
73
72
  get value() {
@@ -112,6 +111,9 @@ export class Dependency {
112
111
  }
113
112
  };
114
113
  }
114
+ get disposePromise() {
115
+ return this.abortPromise?.promise ?? Promise.resolve();
116
+ }
115
117
  dispose() {
116
118
  this.abortPromise?.resolve();
117
119
  this.abortPromise = this.reactionPromise = undefined;
@@ -2,37 +2,50 @@ import { PromiseConfiguration } from "../promise-configuration.js";
2
2
  import { symAI } from "../constants.js";
3
3
  export class DependencyStream {
4
4
  owner;
5
- selfDispose = new PromiseConfiguration();
5
+ abortPromise = new PromiseConfiguration();
6
6
  iterator;
7
7
  get isDisposed() {
8
8
  return this.iterator.isDisposed;
9
9
  }
10
+ get done() {
11
+ return this.owner.done || !this.abortPromise?.isPending;
12
+ }
10
13
  constructor(owner) {
11
14
  this.owner = owner;
12
- this.selfDispose = new PromiseConfiguration();
15
+ this.abortPromise = new PromiseConfiguration();
13
16
  this.iterator = owner[symAI]();
14
17
  }
15
18
  [symAI]() {
16
19
  const done = { done: true };
17
20
  return {
18
21
  next: async () => {
19
- if (this.selfDispose.isFulfilled)
22
+ if (this.done) {
23
+ this.abort();
20
24
  return done;
25
+ }
21
26
  const nextRes = this.iterator.next();
22
27
  await Promise.race([
23
- this.selfDispose.promise,
28
+ this.abortPromise.promise,
24
29
  nextRes,
25
30
  ]);
26
- if (this.selfDispose.isFulfilled)
31
+ if (this.done) {
32
+ this.abort();
27
33
  return done;
28
- this.selfDispose = new PromiseConfiguration();
34
+ }
35
+ this.abortPromise = new PromiseConfiguration();
29
36
  return nextRes;
30
37
  }
31
38
  };
32
39
  }
40
+ abort() {
41
+ if (this.abortPromise?.isPending) {
42
+ this.abortPromise.resolve();
43
+ this.abortPromise = undefined;
44
+ }
45
+ }
33
46
  dispose() {
34
- if (this.isDisposed)
47
+ if (this.done)
35
48
  return;
36
- this.selfDispose.resolve();
49
+ this.abort();
37
50
  }
38
51
  }
@@ -13,8 +13,8 @@ export function reaction(fn, config) {
13
13
  depsArray = Array.from(deps);
14
14
  beforeValues = depsArray.map(dep => dep.value_unsafe);
15
15
  const promises = depsArray.map(dep => dep.next());
16
- // promises.push(dep.disposePromise as Promise<any>);
17
- await Promise.race(depsArray.map(dep => dep.next()));
16
+ promises.push(dep.disposePromise);
17
+ await Promise.race(promises);
18
18
  if (dep.done)
19
19
  return { done: true };
20
20
  let shouldRun = depsArray.some((dep, i) => dep.value_unsafe !== beforeValues[i]);
@@ -3,4 +3,5 @@ import { IAllStreamConfig } from "./contracts.ts";
3
3
  export declare abstract class DepFactory {
4
4
  static ofValue<T>(value: T, config?: Partial<IAllStreamConfig<T>>): Dependency<T>;
5
5
  static ofReaction<T>(fn: () => T, config?: Partial<IAllStreamConfig<T>>): Dependency<T>;
6
+ static ofDependency<T>(dep: Dependency<T>): import("./dependency.stream.ts").DependencyStream<T>;
6
7
  }
@@ -28,5 +28,6 @@ export declare class Dependency<T = any> {
28
28
  done: boolean;
29
29
  readonly value: T;
30
30
  }>;
31
+ get disposePromise(): Promise<void>;
31
32
  dispose(this: Dependency<T>): void;
32
33
  }
@@ -3,12 +3,14 @@ import { symAI } from "../constants.ts";
3
3
  import { Dependency } from "./dependency.ts";
4
4
  export declare class DependencyStream<T = any> implements IDependencyStream {
5
5
  readonly owner: Dependency;
6
- private selfDispose;
6
+ private abortPromise;
7
7
  private readonly iterator;
8
8
  get isDisposed(): boolean;
9
+ get done(): boolean;
9
10
  constructor(owner: Dependency);
10
11
  [symAI](): {
11
12
  next: () => Promise<IteratorResult<T, void>>;
12
13
  };
14
+ protected abort(): void;
13
15
  dispose(): void;
14
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fbltd/async",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "description": "Miscellaneous async utils",
5
5
  "homepage": "https://github.com/GlennMiller1991/async",
6
6
  "type": "module",