@fbltd/async 1.0.27 → 1.0.29
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 +32 -12
- package/dist/bin/dependency/dependency.js +2 -2
- package/dist/bin/dependency/integrations/react/index.js +2 -1
- package/dist/bin/dependency/integrations/react/reactive/index.js +26 -0
- package/dist/bin/dependency/integrations/react/reactive/utils.js +6 -0
- package/dist/bin/dependency/integrations/react/use-race-stream/index.js +1 -0
- package/dist/bin/dependency/integrations/react/{race-stream.controller.js → use-race-stream/race-stream.controller.js} +2 -2
- package/dist/bin/dependency/observe.state.js +33 -0
- package/dist/bin/dependency/stream-utils/index.js +1 -1
- package/dist/bin/dependency/stream-utils/reaction/index.js +1 -0
- package/dist/bin/dependency/stream-utils/{reaction.js → reaction/reaction.js} +3 -3
- package/dist/bin/dependency/stream-utils/reaction/utils.js +10 -0
- package/dist/bin/index.js +0 -1
- package/dist/types/dependency/integrations/react/index.d.ts +2 -1
- package/dist/types/dependency/integrations/react/reactive/index.d.ts +1 -0
- package/dist/types/dependency/integrations/react/reactive/utils.d.ts +2 -0
- package/dist/types/dependency/integrations/react/use-race-stream/index.d.ts +1 -0
- package/dist/types/dependency/integrations/react/{race-stream.controller.d.ts → use-race-stream/race-stream.controller.d.ts} +1 -1
- package/dist/types/dependency/integrations/react/{use-race.stream.d.ts → use-race-stream/use-race.stream.d.ts} +1 -1
- package/dist/types/dependency/observe.state.d.ts +14 -0
- package/dist/types/dependency/stream-utils/index.d.ts +1 -1
- package/dist/types/dependency/stream-utils/reaction/index.d.ts +1 -0
- package/dist/types/dependency/stream-utils/reaction/reaction.d.ts +3 -0
- package/dist/types/dependency/stream-utils/reaction/utils.d.ts +4 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/promise-configuration.d.ts +3 -3
- package/package.json +1 -1
- package/dist/bin/dependency/global.js +0 -26
- package/dist/types/dependency/global.d.ts +0 -11
- package/dist/types/dependency/stream-utils/reaction.d.ts +0 -3
- /package/dist/bin/dependency/integrations/react/{use-race.stream.js → use-race-stream/use-race.stream.js} +0 -0
package/README.md
CHANGED
|
@@ -35,13 +35,13 @@ type IPromiseConfiguration<T> = {
|
|
|
35
35
|
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
|
+
### Dependency
|
|
39
39
|
Implementation of reactive model leveraging native JavaScript async features like
|
|
40
40
|
Promises, (async) iterators and generators.
|
|
41
41
|
The version is 0.0.x so keep it in mind
|
|
42
42
|
|
|
43
43
|
```typescript
|
|
44
|
-
const counter = new
|
|
44
|
+
const counter = new Dependency<number>(0);
|
|
45
45
|
|
|
46
46
|
async function onCounterChange() {
|
|
47
47
|
for await (let value of counter) {
|
|
@@ -101,14 +101,14 @@ async function subscribe() {
|
|
|
101
101
|
|
|
102
102
|
#### Framework integrations
|
|
103
103
|
##### React
|
|
104
|
-
Of course, there is a React integration via stream hooks.
|
|
104
|
+
Of course, there is a React integration via stream hooks and HOCs.
|
|
105
105
|
For example, here is classic react counter implementation via useRaceStream hook.
|
|
106
106
|
|
|
107
107
|
```typescript jsx
|
|
108
|
-
type
|
|
108
|
+
type ICounter = {
|
|
109
109
|
dependecy: Dependency,
|
|
110
110
|
}
|
|
111
|
-
export const Counter: React.FC<
|
|
111
|
+
export const Counter: React.FC<ICounter> = React.memo(({
|
|
112
112
|
dependency,
|
|
113
113
|
}) => {
|
|
114
114
|
// num is an instance of DependencyStream
|
|
@@ -121,20 +121,40 @@ export const Counter: React.FC<ITest> = React.memo(({
|
|
|
121
121
|
return (
|
|
122
122
|
<div className={"container"}>
|
|
123
123
|
<button className={"incrementer"}
|
|
124
|
-
// Now result is array of streams values
|
|
125
|
-
// It should be object
|
|
126
124
|
onClick={() => dependency.value++}>
|
|
127
125
|
+
|
|
128
126
|
</button>
|
|
129
127
|
|
|
130
128
|
<div className={cn("display")}>
|
|
131
|
-
{
|
|
132
|
-
// Now result is array of streams values
|
|
133
|
-
// It should be object
|
|
134
|
-
}
|
|
135
129
|
{value.dependency}
|
|
136
130
|
</div>
|
|
137
131
|
</div>
|
|
138
132
|
)
|
|
139
133
|
})
|
|
140
|
-
```
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Or you can use Reaction HOC:
|
|
137
|
+
```typescript jsx
|
|
138
|
+
type ICounter = {
|
|
139
|
+
dependecy: Dependency,
|
|
140
|
+
}
|
|
141
|
+
export const Counter: React.FC<ICounter> = Reactive(({
|
|
142
|
+
dependency,
|
|
143
|
+
}) => {
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<div className={"container"}>
|
|
147
|
+
<button className={"incrementer"}
|
|
148
|
+
onClick={() => dependency.value++}>
|
|
149
|
+
+
|
|
150
|
+
</button>
|
|
151
|
+
|
|
152
|
+
<div className={cn("display")}>
|
|
153
|
+
{value.dependency}
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
)
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
######
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PromiseConfiguration } from "../promise-configuration.js";
|
|
2
2
|
import { baseComparer } from "./utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { observationState } from "./observe.state.js";
|
|
4
4
|
import { symAI } from "../constants.js";
|
|
5
5
|
export class Dependency {
|
|
6
6
|
_value;
|
|
@@ -31,7 +31,7 @@ export class Dependency {
|
|
|
31
31
|
this._set(v);
|
|
32
32
|
}
|
|
33
33
|
get value() {
|
|
34
|
-
|
|
34
|
+
observationState.setDep(this);
|
|
35
35
|
return this._value;
|
|
36
36
|
}
|
|
37
37
|
get done() {
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./use-race
|
|
1
|
+
export * from "./use-race-stream/index.js";
|
|
2
|
+
export * from "./reactive/index.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { createElement, useEffect, useState } from "react";
|
|
2
|
+
import { observationState } from "../../../observe.state.js";
|
|
3
|
+
import { usePromise } from "./utils.js";
|
|
4
|
+
function Reactive(fn) {
|
|
5
|
+
return React.memo((props) => {
|
|
6
|
+
const [key, setKey] = useState(Math.random());
|
|
7
|
+
const abortPromise = usePromise();
|
|
8
|
+
useEffect(() => abortPromise.resolve, []);
|
|
9
|
+
observationState.isObserved = true;
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const deps = observationState.getDeps();
|
|
12
|
+
observationState.isObserved = false;
|
|
13
|
+
if (!deps.size)
|
|
14
|
+
return;
|
|
15
|
+
let prom = [abortPromise.promise];
|
|
16
|
+
deps.forEach(d => prom.push(d.next()));
|
|
17
|
+
Promise.race(prom)
|
|
18
|
+
.then(() => {
|
|
19
|
+
if (abortPromise.isFulfilled)
|
|
20
|
+
return;
|
|
21
|
+
setKey(Math.random());
|
|
22
|
+
});
|
|
23
|
+
}, [key, props]);
|
|
24
|
+
return createElement(fn, props);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useRaceStream } from "./use-race.stream.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isObjectsContentEqual } from "
|
|
2
|
-
import { raceStream } from "
|
|
1
|
+
import { isObjectsContentEqual } from "../utils.js";
|
|
2
|
+
import { raceStream } from "../../../stream-utils/index.js";
|
|
3
3
|
export class RaceStreamController {
|
|
4
4
|
_value;
|
|
5
5
|
isFirstWas = false;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class ObservationState {
|
|
2
|
+
_isObserved = false;
|
|
3
|
+
dependencies = undefined;
|
|
4
|
+
stack = [];
|
|
5
|
+
get isObserved() {
|
|
6
|
+
return this._isObserved;
|
|
7
|
+
}
|
|
8
|
+
set isObserved(value) {
|
|
9
|
+
if (value) {
|
|
10
|
+
this.push();
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
this.pop();
|
|
14
|
+
}
|
|
15
|
+
this._isObserved = !!this.dependencies;
|
|
16
|
+
}
|
|
17
|
+
setDep(dep) {
|
|
18
|
+
if (!this.isObserved)
|
|
19
|
+
return;
|
|
20
|
+
this.dependencies.add(dep);
|
|
21
|
+
}
|
|
22
|
+
getDeps() {
|
|
23
|
+
return this.dependencies;
|
|
24
|
+
}
|
|
25
|
+
push() {
|
|
26
|
+
this.stack.push(this.dependencies);
|
|
27
|
+
this.dependencies = new Set();
|
|
28
|
+
}
|
|
29
|
+
pop() {
|
|
30
|
+
this.dependencies = this.stack.pop();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export const observationState = new ObservationState();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./reaction.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Dependency } from "../../dependency.js";
|
|
2
|
+
import { symAI } from "../../../constants.js";
|
|
3
|
+
import { runFnWithDepCollection } from "./utils.js";
|
|
4
4
|
export function reaction(fn, config) {
|
|
5
5
|
let { result, deps } = runFnWithDepCollection(fn);
|
|
6
6
|
const dep = new Dependency(result, config);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { observationState } from "../../observe.state.js";
|
|
2
|
+
export function runFnWithDepCollection(fn) {
|
|
3
|
+
observationState.isObserved = true;
|
|
4
|
+
const result = fn();
|
|
5
|
+
const deps = observationState.getDeps();
|
|
6
|
+
observationState.isObserved = false;
|
|
7
|
+
return {
|
|
8
|
+
result, deps
|
|
9
|
+
};
|
|
10
|
+
}
|
package/dist/bin/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './use-race
|
|
1
|
+
export * from './use-race-stream/index.ts';
|
|
2
|
+
export * from './reactive/index.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useRaceStream } from './use-race.stream.ts';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dispatch, SetStateAction } from "react";
|
|
2
|
-
import { IDepObjectArgument, IDepObjectReturn, raceStream } from "
|
|
2
|
+
import { IDepObjectArgument, IDepObjectReturn, raceStream } from "../../../stream-utils/index.ts";
|
|
3
3
|
export declare class RaceStreamController<T extends IDepObjectArgument> {
|
|
4
4
|
private _value;
|
|
5
5
|
private isFirstWas;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IDepObjectArgument, IDepObjectReturn } from "
|
|
1
|
+
import { IDepObjectArgument, IDepObjectReturn } from "../../../index.ts";
|
|
2
2
|
export declare function useRaceStream<T extends IDepObjectArgument>(deps: T): {
|
|
3
3
|
value: IDepObjectReturn<T>;
|
|
4
4
|
dispose: Function;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Dependency } from "./dependency.ts";
|
|
2
|
+
declare class ObservationState {
|
|
3
|
+
private _isObserved;
|
|
4
|
+
dependencies: Set<Dependency> | undefined;
|
|
5
|
+
private stack;
|
|
6
|
+
get isObserved(): boolean;
|
|
7
|
+
set isObserved(value: boolean);
|
|
8
|
+
setDep(dep: Dependency): void;
|
|
9
|
+
getDeps(): Set<Dependency<any>> | undefined;
|
|
10
|
+
private push;
|
|
11
|
+
private pop;
|
|
12
|
+
}
|
|
13
|
+
export declare const observationState: ObservationState;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './reaction.ts';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare class PromiseConfiguration<TReturn = void> {
|
|
2
2
|
readonly promise: Promise<TReturn>;
|
|
3
|
-
_resolve
|
|
4
|
-
_reject
|
|
5
|
-
_isFulfilled
|
|
3
|
+
private _resolve;
|
|
4
|
+
private _reject;
|
|
5
|
+
private _isFulfilled;
|
|
6
6
|
constructor();
|
|
7
7
|
get reject(): (value: Error) => void;
|
|
8
8
|
get resolve(): (value: TReturn) => void;
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const global = {
|
|
2
|
-
watchFlag: false,
|
|
3
|
-
dependencies: null
|
|
4
|
-
};
|
|
5
|
-
const notImplemented = new Error('Watching while watching is not implemented');
|
|
6
|
-
export function runFnWithDepCollection(fn) {
|
|
7
|
-
if (global.watchFlag) {
|
|
8
|
-
throw notImplemented;
|
|
9
|
-
}
|
|
10
|
-
global.watchFlag = true;
|
|
11
|
-
global.dependencies = new Set();
|
|
12
|
-
let result = fn();
|
|
13
|
-
let deps = global.dependencies;
|
|
14
|
-
global.dependencies = null;
|
|
15
|
-
global.watchFlag = false;
|
|
16
|
-
return {
|
|
17
|
-
result, deps
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export function collectDep(dep) {
|
|
21
|
-
if (!global.watchFlag)
|
|
22
|
-
return;
|
|
23
|
-
if (dep.done)
|
|
24
|
-
return;
|
|
25
|
-
global.dependencies.add(dep);
|
|
26
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Dependency } from "./dependency.js";
|
|
2
|
-
declare const global: {
|
|
3
|
-
watchFlag: boolean;
|
|
4
|
-
dependencies: Set<Dependency>;
|
|
5
|
-
};
|
|
6
|
-
export declare function runFnWithDepCollection<T>(fn: () => T): {
|
|
7
|
-
result: T;
|
|
8
|
-
deps: typeof global.dependencies;
|
|
9
|
-
};
|
|
10
|
-
export declare function collectDep(dep: Dependency): void;
|
|
11
|
-
export {};
|
|
File without changes
|