@fbltd/async 1.0.25 → 1.0.26
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/README.md +7 -9
- package/dist/bin/dependency/dep.factory.js +10 -0
- package/dist/bin/dependency/dependency.js +5 -1
- package/dist/bin/dependency/index.js +1 -0
- package/dist/bin/dependency/stream-utils/reaction.js +39 -30
- package/dist/types/dependency/dep.factory.d.ts +6 -0
- package/dist/types/dependency/dependency.d.ts +3 -1
- package/dist/types/dependency/index.d.ts +1 -0
- package/dist/types/dependency/stream-utils/reaction.d.ts +3 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,6 @@ There is no any management of passed data for resolving.
|
|
|
36
36
|
Returned promise is usual ES promise so it is impossible to fulfill promise twice.
|
|
37
37
|
|
|
38
38
|
### DependencyStream
|
|
39
|
-
#### core
|
|
40
39
|
Implementation of reactive model leveraging native JavaScript async features like
|
|
41
40
|
Promises, (async) iterators and generators.
|
|
42
41
|
The version is 0.0.x so keep it in mind
|
|
@@ -75,14 +74,17 @@ setInterval(() => {
|
|
|
75
74
|
##### reaction
|
|
76
75
|
The most powerful util among all stream utils.
|
|
77
76
|
Function is watching only for actual dependencies and does not react
|
|
78
|
-
for dependencies that do not affect result value
|
|
77
|
+
for dependencies that do not affect result value. Since the reaction
|
|
78
|
+
provides dependency instance, of course, there is a function result caching:
|
|
79
79
|
```typescript
|
|
80
80
|
let isDep1Ready = new Dependency(false);
|
|
81
81
|
let isDep2Ready = new Dependency(false);
|
|
82
82
|
let counter = new Dependency(0);
|
|
83
83
|
|
|
84
|
-
// function that
|
|
85
|
-
let
|
|
84
|
+
// function that uses dependency instances
|
|
85
|
+
let watchFn = () => {
|
|
86
|
+
// Take a look at IF condition -
|
|
87
|
+
// value can be changed only if dep1 and dep2 is ready
|
|
86
88
|
if (isDep1Ready.value && isDep2Ready.value) {
|
|
87
89
|
return counter.value;
|
|
88
90
|
}
|
|
@@ -90,16 +92,12 @@ let cachedFunction = () => {
|
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
async function subscribe() {
|
|
93
|
-
for await (const value of reaction(
|
|
95
|
+
for await (const value of reaction(watchFn)) {
|
|
94
96
|
reactionFn();
|
|
95
97
|
}
|
|
96
98
|
exitFn();
|
|
97
99
|
}
|
|
98
100
|
```
|
|
99
|
-
The reaction is declared deprecated because a return value caching does not
|
|
100
|
-
use optimal strategy. Moreover, ideally, reaction should give back a
|
|
101
|
-
dependency instance or something like it, that can provide an ability
|
|
102
|
-
to be an observable for another reaction.
|
|
103
101
|
|
|
104
102
|
#### Framework integrations
|
|
105
103
|
##### React
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Dependency } from "./dependency.js";
|
|
2
|
+
import { reaction } from "./stream-utils/index.js";
|
|
3
|
+
export class DepFactory {
|
|
4
|
+
static ofValue(value, config) {
|
|
5
|
+
return new Dependency(value, config);
|
|
6
|
+
}
|
|
7
|
+
static ofReaction(fn, config) {
|
|
8
|
+
return reaction(fn, config);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PromiseConfiguration } from "../promise-configuration.js";
|
|
2
2
|
import { baseComparer } from "./utils.js";
|
|
3
3
|
import { collectDep } from "./global.js";
|
|
4
|
+
import { symAI } from "../constants.js";
|
|
4
5
|
export class Dependency {
|
|
5
6
|
_value;
|
|
6
7
|
reactionPromise;
|
|
@@ -36,7 +37,7 @@ export class Dependency {
|
|
|
36
37
|
get done() {
|
|
37
38
|
return this.abortPromise.isFulfilled;
|
|
38
39
|
}
|
|
39
|
-
[
|
|
40
|
+
[symAI](thisStreamConfig = {}) {
|
|
40
41
|
const externalPromises = [];
|
|
41
42
|
let firstPromise;
|
|
42
43
|
const withReactionOnSubscribe = this.config.withReactionOnSubscribe || thisStreamConfig.withReactionOnSubscribe;
|
|
@@ -110,6 +111,9 @@ export class Dependency {
|
|
|
110
111
|
}
|
|
111
112
|
};
|
|
112
113
|
}
|
|
114
|
+
get disposePromise() {
|
|
115
|
+
return this.abortPromise.promise;
|
|
116
|
+
}
|
|
113
117
|
dispose() {
|
|
114
118
|
this.abortPromise.resolve();
|
|
115
119
|
this.reactionPromise = undefined;
|
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import { runFnWithDepCollection } from "../global.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return { done: false, value: result };
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
for (let dep of deps) {
|
|
23
|
-
if (dep.done)
|
|
24
|
-
deps.delete(dep);
|
|
25
|
-
}
|
|
26
|
-
if (!deps.size)
|
|
2
|
+
import { Dependency } from "../dependency.js";
|
|
3
|
+
import { symAI } from "../../constants.js";
|
|
4
|
+
export function reaction(fn, config) {
|
|
5
|
+
let { result, deps } = runFnWithDepCollection(fn);
|
|
6
|
+
const dep = new Dependency(result, config);
|
|
7
|
+
async function subscribe() {
|
|
8
|
+
const stream = { [symAI]: () => {
|
|
9
|
+
let depsArray;
|
|
10
|
+
let beforeValues;
|
|
11
|
+
let obj = {
|
|
12
|
+
next: async () => {
|
|
13
|
+
depsArray = Array.from(deps);
|
|
14
|
+
beforeValues = depsArray.map(dep => dep.value);
|
|
15
|
+
const promises = depsArray.map(dep => dep.next());
|
|
16
|
+
promises.push(dep.disposePromise);
|
|
17
|
+
await Promise.race(depsArray.map(dep => dep.next()));
|
|
18
|
+
if (dep.done)
|
|
27
19
|
return { done: true };
|
|
28
|
-
|
|
20
|
+
let shouldRun = depsArray.some((dep, i) => dep.value !== beforeValues[i]);
|
|
21
|
+
if (shouldRun) {
|
|
22
|
+
({ result, deps } = runFnWithDepCollection(fn));
|
|
23
|
+
return { done: false, value: result };
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
for (let dep of deps) {
|
|
27
|
+
if (dep.done)
|
|
28
|
+
deps.delete(dep);
|
|
29
|
+
}
|
|
30
|
+
if (!deps.size)
|
|
31
|
+
return { done: true };
|
|
32
|
+
return obj.next();
|
|
33
|
+
}
|
|
29
34
|
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
};
|
|
36
|
+
return obj;
|
|
37
|
+
} };
|
|
38
|
+
for await (let value of stream) {
|
|
39
|
+
dep.value = value;
|
|
33
40
|
}
|
|
34
|
-
}
|
|
41
|
+
}
|
|
42
|
+
subscribe().then(() => dep.dispose());
|
|
43
|
+
return dep;
|
|
35
44
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Dependency } from "./dependency.ts";
|
|
2
|
+
import { IAllStreamConfig } from "./contracts.ts";
|
|
3
|
+
export declare abstract class DepFactory {
|
|
4
|
+
static ofValue<T>(value: T, config?: Partial<IAllStreamConfig<T>>): Dependency<T>;
|
|
5
|
+
static ofReaction<T>(fn: () => T, config?: Partial<IAllStreamConfig<T>>): Dependency<T>;
|
|
6
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IAllStreamConfig, IStreamIterator, IThisStreamConfig } from "./contracts.ts";
|
|
2
|
+
import { symAI } from "../constants.ts";
|
|
2
3
|
export declare class Dependency<T = any> {
|
|
3
4
|
private _value;
|
|
4
5
|
private reactionPromise;
|
|
@@ -9,7 +10,7 @@ export declare class Dependency<T = any> {
|
|
|
9
10
|
set value(v: T);
|
|
10
11
|
get value(): T;
|
|
11
12
|
get done(): boolean;
|
|
12
|
-
[
|
|
13
|
+
[symAI](this: Dependency<T>, thisStreamConfig?: IThisStreamConfig): IStreamIterator<T>;
|
|
13
14
|
/**
|
|
14
15
|
* One race of value change and dependency dispose
|
|
15
16
|
* for all subscribers
|
|
@@ -26,5 +27,6 @@ export declare class Dependency<T = any> {
|
|
|
26
27
|
done: boolean;
|
|
27
28
|
readonly value: T;
|
|
28
29
|
}>;
|
|
30
|
+
get disposePromise(): Promise<void>;
|
|
29
31
|
dispose(this: Dependency<T>): void;
|
|
30
32
|
}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare function reaction<T>(fn: () => T): {
|
|
5
|
-
[Symbol.asyncIterator]: () => {
|
|
6
|
-
next: () => Promise<{
|
|
7
|
-
done: true;
|
|
8
|
-
value?: never;
|
|
9
|
-
} | {
|
|
10
|
-
done: false;
|
|
11
|
-
value: T;
|
|
12
|
-
}>;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
1
|
+
import { Dependency } from "../dependency.ts";
|
|
2
|
+
import { IAllStreamConfig } from "../contracts.js";
|
|
3
|
+
export declare function reaction<T>(fn: () => T, config?: Partial<IAllStreamConfig<T>>): Dependency<T>;
|