@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.
Files changed (31) hide show
  1. package/README.md +32 -12
  2. package/dist/bin/dependency/dependency.js +2 -2
  3. package/dist/bin/dependency/integrations/react/index.js +2 -1
  4. package/dist/bin/dependency/integrations/react/reactive/index.js +26 -0
  5. package/dist/bin/dependency/integrations/react/reactive/utils.js +6 -0
  6. package/dist/bin/dependency/integrations/react/use-race-stream/index.js +1 -0
  7. package/dist/bin/dependency/integrations/react/{race-stream.controller.js → use-race-stream/race-stream.controller.js} +2 -2
  8. package/dist/bin/dependency/observe.state.js +33 -0
  9. package/dist/bin/dependency/stream-utils/index.js +1 -1
  10. package/dist/bin/dependency/stream-utils/reaction/index.js +1 -0
  11. package/dist/bin/dependency/stream-utils/{reaction.js → reaction/reaction.js} +3 -3
  12. package/dist/bin/dependency/stream-utils/reaction/utils.js +10 -0
  13. package/dist/bin/index.js +0 -1
  14. package/dist/types/dependency/integrations/react/index.d.ts +2 -1
  15. package/dist/types/dependency/integrations/react/reactive/index.d.ts +1 -0
  16. package/dist/types/dependency/integrations/react/reactive/utils.d.ts +2 -0
  17. package/dist/types/dependency/integrations/react/use-race-stream/index.d.ts +1 -0
  18. package/dist/types/dependency/integrations/react/{race-stream.controller.d.ts → use-race-stream/race-stream.controller.d.ts} +1 -1
  19. package/dist/types/dependency/integrations/react/{use-race.stream.d.ts → use-race-stream/use-race.stream.d.ts} +1 -1
  20. package/dist/types/dependency/observe.state.d.ts +14 -0
  21. package/dist/types/dependency/stream-utils/index.d.ts +1 -1
  22. package/dist/types/dependency/stream-utils/reaction/index.d.ts +1 -0
  23. package/dist/types/dependency/stream-utils/reaction/reaction.d.ts +3 -0
  24. package/dist/types/dependency/stream-utils/reaction/utils.d.ts +4 -0
  25. package/dist/types/index.d.ts +0 -1
  26. package/dist/types/promise-configuration.d.ts +3 -3
  27. package/package.json +1 -1
  28. package/dist/bin/dependency/global.js +0 -26
  29. package/dist/types/dependency/global.d.ts +0 -11
  30. package/dist/types/dependency/stream-utils/reaction.d.ts +0 -3
  31. /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
- ### DependencyStream
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 DependencyStream<number>(0);
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 IController = {
108
+ type ICounter = {
109
109
  dependecy: Dependency,
110
110
  }
111
- export const Counter: React.FC<ITest> = React.memo(({
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 { collectDep } from "./global.js";
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
- collectDep(this);
34
+ observationState.setDep(this);
35
35
  return this._value;
36
36
  }
37
37
  get done() {
@@ -1 +1,2 @@
1
- export * from "./use-race.stream.js";
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,6 @@
1
+ import { useState } from "react";
2
+ import { PromiseConfiguration } from "../../../../promise-configuration.js";
3
+ export function usePromise() {
4
+ const [promise] = useState(() => new PromiseConfiguration());
5
+ return promise;
6
+ }
@@ -0,0 +1 @@
1
+ export { useRaceStream } from "./use-race.stream.js";
@@ -1,5 +1,5 @@
1
- import { isObjectsContentEqual } from "./utils.js";
2
- import { raceStream } from "../../stream-utils/index.js";
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();
@@ -2,4 +2,4 @@ export * from "./once.stream.js";
2
2
  export * from "./race.stream.js";
3
3
  export * from "./next.js";
4
4
  export * from "./contracts.js";
5
- export * from "./reaction.js";
5
+ export * from "./reaction/index.js";
@@ -0,0 +1 @@
1
+ export * from "./reaction.js";
@@ -1,6 +1,6 @@
1
- import { runFnWithDepCollection } from "../global.js";
2
- import { Dependency } from "../dependency.js";
3
- import { symAI } from "../../constants.js";
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,4 +1,3 @@
1
1
  export * from "./dependency/index.js";
2
- export * from "./dependency/integrations/react/index.js";
3
2
  export * from "./delay.js";
4
3
  export * from "./promise-configuration.js";
@@ -1 +1,2 @@
1
- export * from './use-race.stream.ts';
1
+ export * from './use-race-stream/index.ts';
2
+ export * from './reactive/index.ts';
@@ -0,0 +1,2 @@
1
+ import { PromiseConfiguration } from "../../../../promise-configuration.ts";
2
+ export declare function usePromise<T = void>(): PromiseConfiguration<T>;
@@ -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 "../../stream-utils/index.ts";
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 "../../index.ts";
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 {};
@@ -2,4 +2,4 @@ export * from "./once.stream.ts";
2
2
  export * from "./race.stream.ts";
3
3
  export * from "./next.ts";
4
4
  export * from "./contracts.ts";
5
- export * from "./reaction.ts";
5
+ export * from "./reaction/index.ts";
@@ -0,0 +1 @@
1
+ export * from './reaction.ts';
@@ -0,0 +1,3 @@
1
+ import { Dependency } from "../../dependency.ts";
2
+ import { IAllStreamConfig } from "../../contracts.ts";
3
+ export declare function reaction<T>(fn: () => T, config?: Partial<IAllStreamConfig<T>>): Dependency<T>;
@@ -0,0 +1,4 @@
1
+ export declare function runFnWithDepCollection<T>(fn: () => T): {
2
+ result: T;
3
+ deps: Set<import("../../dependency.ts").Dependency<any>>;
4
+ };
@@ -1,4 +1,3 @@
1
1
  export * from './dependency/index.ts';
2
- export * from './dependency/integrations/react/index.ts';
3
2
  export * from './delay.ts';
4
3
  export * from './promise-configuration.ts';
@@ -1,8 +1,8 @@
1
1
  export declare class PromiseConfiguration<TReturn = void> {
2
2
  readonly promise: Promise<TReturn>;
3
- _resolve: (value: TReturn) => void;
4
- _reject: (value: Error) => void;
5
- _isFulfilled: boolean;
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@fbltd/async",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "Miscellaneous async utils",
5
5
  "homepage": "https://github.com/GlennMiller1991/async",
6
6
  "type": "module",
@@ -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 {};
@@ -1,3 +0,0 @@
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>;