@fbltd/async 1.0.18 → 1.0.21

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 (29) hide show
  1. package/README.md +12 -7
  2. package/dist/bin/dependency-stream/index.js +1 -1
  3. package/dist/bin/dependency-stream/integrations/react/index.js +1 -17
  4. package/dist/bin/dependency-stream/integrations/react/race-stream.controller.js +34 -0
  5. package/dist/bin/dependency-stream/integrations/react/use-race.stream.js +17 -0
  6. package/dist/bin/dependency-stream/integrations/react/utils.js +7 -0
  7. package/dist/bin/dependency-stream/stream-utils/contracts.js +1 -0
  8. package/dist/bin/dependency-stream/{utils → stream-utils}/index.js +1 -0
  9. package/dist/bin/dependency-stream/stream-utils/race.stream.js +36 -0
  10. package/dist/types/dependency-stream/dependency.d.ts +2 -13
  11. package/dist/types/dependency-stream/index.d.ts +1 -1
  12. package/dist/types/dependency-stream/integrations/react/index.d.ts +1 -1
  13. package/dist/types/dependency-stream/integrations/react/race-stream.controller.d.ts +13 -0
  14. package/dist/types/dependency-stream/integrations/react/use-race.stream.d.ts +5 -0
  15. package/dist/types/dependency-stream/integrations/react/utils.d.ts +1 -0
  16. package/dist/types/dependency-stream/stream-utils/contracts.d.ts +7 -0
  17. package/dist/types/dependency-stream/{utils → stream-utils}/index.d.ts +1 -0
  18. package/dist/types/dependency-stream/stream-utils/race.stream.d.ts +3 -0
  19. package/package.json +7 -3
  20. package/dist/bin/dependency-stream/integrations/react/src/index.js +0 -17
  21. package/dist/bin/dependency-stream/integrations/react/src/use-stream.js +0 -39
  22. package/dist/bin/dependency-stream/utils/race.stream.js +0 -25
  23. package/dist/types/dependency-stream/integrations/react/src/index.d.ts +0 -1
  24. package/dist/types/dependency-stream/integrations/react/src/use-stream.d.ts +0 -5
  25. package/dist/types/dependency-stream/utils/race.stream.d.ts +0 -12
  26. /package/dist/bin/dependency-stream/{utils → stream-utils}/next.js +0 -0
  27. /package/dist/bin/dependency-stream/{utils → stream-utils}/once.stream.js +0 -0
  28. /package/dist/types/dependency-stream/{utils → stream-utils}/next.d.ts +0 -0
  29. /package/dist/types/dependency-stream/{utils → stream-utils}/once.stream.d.ts +0 -0
package/README.md CHANGED
@@ -67,20 +67,25 @@ setInterval(() => {
67
67
  }, 1000)
68
68
  ```
69
69
 
70
+ #### Stream utils
71
+ ##### onceStream
72
+ ##### raceStream
73
+ ##### next
74
+
70
75
  #### Framework integrations
71
76
  ##### React
72
- Of course, there is a React integration via useStream hook:
77
+ Of course, there is a React integration via stream hooks.
78
+ For example, here is classic react counter implementation via useRaceStream hook.
73
79
 
74
80
  ```typescript jsx
75
81
  type IController = {
76
- controller: SomeController,
82
+ dependecy: Dependency,
77
83
  }
78
84
  export const Counter: React.FC<ITest> = React.memo(({
79
- controller,
85
+ dependency,
80
86
  }) => {
81
87
  // num is an instance of DependencyStream
82
- const num = controller.num;
83
- const {value, dispose} = useStream(num);
88
+ const {value, dispose} = useRaceStream({dependency});
84
89
 
85
90
  // resolving promises on component unmounting
86
91
  // This is won't cause of rerender
@@ -91,7 +96,7 @@ export const Counter: React.FC<ITest> = React.memo(({
91
96
  <button className={"incrementer"}
92
97
  // Now result is array of streams values
93
98
  // It should be object
94
- onClick={() => num.set(value![0] + 1)}>
99
+ onClick={() => dependency.value++}>
95
100
  +
96
101
  </button>
97
102
 
@@ -100,7 +105,7 @@ export const Counter: React.FC<ITest> = React.memo(({
100
105
  // Now result is array of streams values
101
106
  // It should be object
102
107
  }
103
- {value![0]}
108
+ {value.dependency}
104
109
  </div>
105
110
  </div>
106
111
  )
@@ -1,4 +1,4 @@
1
1
  export * from "./dependency.js";
2
2
  export * from "./dependency.stream.js";
3
- export * from "./utils/index.js";
3
+ export * from "./stream-utils/index.js";
4
4
  export * from "./integrations/index.js";
@@ -1,17 +1 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./src/index.js"), exports);
1
+ export * from "./use-race.stream.js";
@@ -0,0 +1,34 @@
1
+ import { isObjectsContentEqual } from "./utils.js";
2
+ import { raceStream } from "../../stream-utils/index.js";
3
+ export class RaceStreamController {
4
+ _value;
5
+ isFirstWas = false;
6
+ rerenderTrigger;
7
+ deps;
8
+ iterator;
9
+ constructor(streams) {
10
+ this.deps = streams;
11
+ this.init();
12
+ }
13
+ get value() {
14
+ return this._value;
15
+ }
16
+ async init() {
17
+ this.iterator = raceStream(this.deps);
18
+ this._value = Object.entries(this.deps)
19
+ .reduce((acc, [key, dep]) => {
20
+ acc[key] = dep.value;
21
+ return acc;
22
+ }, {});
23
+ for await (let value of this.iterator) {
24
+ this.rerenderTrigger?.(prev => !prev);
25
+ if (!this.isFirstWas && !isObjectsContentEqual(this._value, value)) {
26
+ this._value = value;
27
+ }
28
+ this.isFirstWas = true;
29
+ }
30
+ }
31
+ dispose = () => {
32
+ this.iterator.dispose();
33
+ };
34
+ }
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from "react";
2
+ import { RaceStreamController } from "./race-stream.controller.js";
3
+ export function useRaceStream(deps) {
4
+ const [obj] = useState(() => ({ controller: new RaceStreamController(deps) }));
5
+ const [, setValue] = useState(false);
6
+ obj.controller.rerenderTrigger = setValue;
7
+ useEffect(() => {
8
+ return () => {
9
+ obj.controller.dispose();
10
+ obj.controller = undefined;
11
+ };
12
+ }, []);
13
+ return {
14
+ value: obj.controller.value,
15
+ dispose: obj.controller.dispose,
16
+ };
17
+ }
@@ -0,0 +1,7 @@
1
+ export function isObjectsContentEqual(obj1, obj2) {
2
+ for (let key in obj1) {
3
+ if (obj1[key] !== obj2[key])
4
+ return false;
5
+ }
6
+ return true;
7
+ }
@@ -1,3 +1,4 @@
1
1
  export * from "./once.stream.js";
2
2
  export * from "./race.stream.js";
3
3
  export * from "./next.js";
4
+ export * from "./contracts.js";
@@ -0,0 +1,36 @@
1
+ import { symAI } from "../../constants.js";
2
+ import { PromiseConfiguration } from "../../promise-configuration.js";
3
+ export function raceStream(deps) {
4
+ let externalDispose = new PromiseConfiguration();
5
+ const [keys, streams] = Object
6
+ .entries(deps)
7
+ .reduce((acc, [key, dep]) => {
8
+ acc[0].push(key);
9
+ acc[1].push(dep[symAI]({ externalDispose }));
10
+ return acc;
11
+ }, [[], []]);
12
+ function isDisposed() {
13
+ return streams.some((s) => s.isDisposed);
14
+ }
15
+ return {
16
+ dispose: () => !isDisposed() && externalDispose.resolve({ done: true, value: void 0 }),
17
+ get isDisposed() {
18
+ return isDisposed();
19
+ },
20
+ [symAI]() {
21
+ return {
22
+ next: async () => {
23
+ const res = await Promise.race(streams.map(s => s.next()));
24
+ if (res.done) {
25
+ return res;
26
+ }
27
+ const value = keys.reduce((acc, key) => {
28
+ acc[key] = deps[key].value;
29
+ return acc;
30
+ }, {});
31
+ return { done: false, value };
32
+ }
33
+ };
34
+ }
35
+ };
36
+ }
@@ -1,4 +1,4 @@
1
- import { IAllStreamConfig, IThisStreamConfig } from "./contracts.ts";
1
+ import { IAllStreamConfig, IStreamIterator, IThisStreamConfig } from "./contracts.ts";
2
2
  import { DependencyStream } from "./dependency.stream.ts";
3
3
  export declare class Dependency<T = any> {
4
4
  private _value;
@@ -10,17 +10,6 @@ export declare class Dependency<T = any> {
10
10
  set value(v: T);
11
11
  get value(): T;
12
12
  getStream(this: Dependency<T>): DependencyStream<T>;
13
- [Symbol.asyncIterator](this: Dependency<T>, thisStreamConfig?: IThisStreamConfig): {
14
- owner: Dependency<T>;
15
- dispose: () => void;
16
- readonly isDisposed: boolean;
17
- next: () => Promise<{
18
- done: true;
19
- value: void;
20
- } | {
21
- done: boolean;
22
- readonly value: T;
23
- }>;
24
- };
13
+ [Symbol.asyncIterator](this: Dependency<T>, thisStreamConfig?: IThisStreamConfig): IStreamIterator<T>;
25
14
  dispose(this: Dependency<T>): void;
26
15
  }
@@ -1,4 +1,4 @@
1
1
  export * from './dependency.ts';
2
2
  export * from './dependency.stream.ts';
3
- export * from './utils/index.ts';
3
+ export * from './stream-utils/index.ts';
4
4
  export * from './integrations/index.ts';
@@ -1 +1 @@
1
- export * from './src/index.ts';
1
+ export * from './use-race.stream.ts';
@@ -0,0 +1,13 @@
1
+ import { Dispatch, SetStateAction } from "react";
2
+ import { IDepObjectArgument, IDepObjectReturn, raceStream } from "../../stream-utils/index.ts";
3
+ export declare class RaceStreamController<T extends IDepObjectArgument> {
4
+ private _value;
5
+ private isFirstWas;
6
+ rerenderTrigger?: Dispatch<SetStateAction<boolean>>;
7
+ deps: T;
8
+ iterator: ReturnType<typeof raceStream<T>>;
9
+ constructor(streams: T);
10
+ get value(): IDepObjectReturn<T>;
11
+ init(): Promise<void>;
12
+ dispose: () => void;
13
+ }
@@ -0,0 +1,5 @@
1
+ import { IDepObjectArgument, IDepObjectReturn } from "../../index.ts";
2
+ export declare function useRaceStream<T extends IDepObjectArgument>(deps: T): {
3
+ value: IDepObjectReturn<T>;
4
+ dispose: Function;
5
+ };
@@ -0,0 +1 @@
1
+ export declare function isObjectsContentEqual<T extends {}>(obj1: T, obj2: T): boolean;
@@ -0,0 +1,7 @@
1
+ import { Dependency } from "../dependency.js";
2
+ export type IDepObjectArgument = {
3
+ [key: string]: Dependency;
4
+ };
5
+ export type IDepObjectReturn<T extends IDepObjectArgument> = {
6
+ [Key in keyof T]: T[Key]['value'];
7
+ };
@@ -1,3 +1,4 @@
1
1
  export * from "./once.stream.ts";
2
2
  export * from "./race.stream.ts";
3
3
  export * from "./next.ts";
4
+ export * from "./contracts.ts";
@@ -0,0 +1,3 @@
1
+ import { IDependencyStream } from "../contracts.js";
2
+ import { IDepObjectArgument, IDepObjectReturn } from "./contracts.js";
3
+ export declare function raceStream<T extends IDepObjectArgument>(deps: T): IDependencyStream<IDepObjectReturn<T>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fbltd/async",
3
- "version": "1.0.18",
3
+ "version": "1.0.21",
4
4
  "description": "Miscellaneous async utils",
5
5
  "homepage": "https://github.com/GlennMiller1991/async",
6
6
  "type": "module",
@@ -24,8 +24,8 @@
24
24
  "clearDist": "rm dist -rf || true",
25
25
  "clearModules": "rm node_modules -rf || true",
26
26
  "clearAll": "npm run clearDist && npm run clearModules",
27
- "build": "cd src/dependency-stream/integrations/react && npm run build && cd ../../../../ && npm run clearAll && npm i && mkdir dist && tsc",
28
- "test": "jest --config=./__tests__/jest.config.cjs",
27
+ "build": "npm run clearAll && npm i && mkdir dist && tsc",
28
+ "test": "node --expose-gc node_modules/.bin/jest --config=./__tests__/jest.config.cjs",
29
29
  "postVersionCommit": "git commit -m='post version commit' || true",
30
30
  "postVersionPush": "git push || true",
31
31
  "patch": "npm version patch && npm run postVersionCommit && npm run postVersionPush",
@@ -33,7 +33,11 @@
33
33
  },
34
34
  "author": "",
35
35
  "license": "ISC",
36
+ "dependencies": {
37
+ "react": "^19.x.x"
38
+ },
36
39
  "devDependencies": {
40
+ "@types/react": "^19.x.x",
37
41
  "@types/jest": "^30.0.0",
38
42
  "jest": "^30.0.4",
39
43
  "ts-jest": "^29.4.0",
@@ -1,17 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./use-stream.js"), exports);
@@ -1,39 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useStream = useStream;
4
- const index_1 = require("../../../index");
5
- const react_1 = require("react");
6
- class StreamController {
7
- setValue;
8
- streams;
9
- iterator;
10
- constructor(...streams) {
11
- this.streams = streams;
12
- this.init();
13
- }
14
- async init() {
15
- this.iterator = (0, index_1.raceStream)(...this.streams);
16
- for await (let chunk of this.iterator) {
17
- console.log(chunk);
18
- this.setValue?.(chunk);
19
- }
20
- }
21
- dispose = () => {
22
- this.iterator?.dispose();
23
- };
24
- }
25
- function useStream(...streams) {
26
- const [value, setValue] = (0, react_1.useState)(streams.map(s => s.value));
27
- const [obj] = (0, react_1.useState)(() => ({ controller: new StreamController(...streams) }));
28
- obj.controller.setValue = setValue;
29
- (0, react_1.useEffect)(() => {
30
- return () => {
31
- obj.controller.dispose();
32
- obj.controller = undefined;
33
- };
34
- }, []);
35
- return {
36
- value,
37
- dispose: obj.controller.dispose,
38
- };
39
- }
@@ -1,25 +0,0 @@
1
- import { symAI } from "../../constants.js";
2
- import { PromiseConfiguration } from "../../promise-configuration.js";
3
- export function raceStream(...deps) {
4
- let selfDisposePromise = new PromiseConfiguration();
5
- let isDisposed = false;
6
- const streams = deps.map((dep) => dep[symAI]({
7
- externalDispose: selfDisposePromise
8
- }));
9
- return {
10
- dispose: () => selfDisposePromise.resolve({ done: true, value: void 0 }),
11
- get isDisposed() {
12
- return isDisposed;
13
- },
14
- [symAI]() {
15
- return {
16
- next: async () => {
17
- const res = await Promise.race([selfDisposePromise.promise, ...streams.map(s => s.next())]);
18
- if (res.done)
19
- return res;
20
- return { done: false, value: streams.map(s => s.owner.value) };
21
- }
22
- };
23
- }
24
- };
25
- }
@@ -1 +0,0 @@
1
- export * from './use-stream.ts';
@@ -1,5 +0,0 @@
1
- import { Dependency } from "../../../index";
2
- export declare function useStream(...streams: Dependency[]): {
3
- value: Array<any> | undefined;
4
- dispose: () => void;
5
- };
@@ -1,12 +0,0 @@
1
- import { Dependency } from "../dependency.ts";
2
- import { symAI } from "../../constants.ts";
3
- export declare function raceStream<TArray extends Dependency[]>(...deps: NoInfer<TArray>): {
4
- dispose: () => void;
5
- readonly isDisposed: boolean;
6
- [Symbol.asyncIterator](): {
7
- next: () => Promise<{
8
- done: boolean;
9
- readonly value: any;
10
- }>;
11
- };
12
- };