react-flow-z 1.0.1 → 1.0.2
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 +2 -2
- package/build/flow-system/Flow.d.ts +14 -2
- package/build/index.cjs.js +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.esm.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,8 +22,8 @@ It focuses on **how async logic runs**, not:
|
|
|
22
22
|
- Typed async execution pipeline
|
|
23
23
|
- Immutable flow composition
|
|
24
24
|
- Abort & cancellation via `AbortController`
|
|
25
|
-
- Async orchestration operators: `debounce` · `retry` · `timeout` · `switchMap` ·` parallel
|
|
26
|
-
- Control flow: `filter` · `take` · `conditional execution
|
|
25
|
+
- Async orchestration operators: `debounce` · `retry` · `timeout` · `switchMap` ·` parallel`...
|
|
26
|
+
- Control flow: `filter` · `take` · `conditional execution`...
|
|
27
27
|
- Pause / resume execution
|
|
28
28
|
- Framework-agnostic core
|
|
29
29
|
- Optional React hook (`useFlow`)
|
|
@@ -9,14 +9,19 @@ export type TypedFlow<I, O, Context> = Flow<Context> & {
|
|
|
9
9
|
debounce(ms: number): TypedFlow<I, O, Context>;
|
|
10
10
|
throttle(ms: number): TypedFlow<I, O, Context>;
|
|
11
11
|
leading(ms: number): TypedFlow<I, O, Context>;
|
|
12
|
+
map<N>(fn: (v: O, context: Context) => N): TypedFlow<I, N, Context>;
|
|
12
13
|
switchMap<N>(fn: Step<O, N, Context>): TypedFlow<I, N, Context>;
|
|
13
14
|
exhaustMap<N>(fn: Step<O, N, Context>): TypedFlow<I, N, Context>;
|
|
15
|
+
distinct(compare?: (prev: O, next: O) => boolean): TypedFlow<I, O, Context>;
|
|
14
16
|
retry(times: number | {
|
|
15
17
|
times: number;
|
|
16
18
|
delay?: number;
|
|
17
19
|
backoff?: "linear" | "exponential";
|
|
18
20
|
}): TypedFlow<I, O, Context>;
|
|
19
|
-
poll(
|
|
21
|
+
poll(ms: number, options?: {
|
|
22
|
+
until?: (v: any) => boolean;
|
|
23
|
+
max?: number;
|
|
24
|
+
}): TypedFlow<I, O, Context>;
|
|
20
25
|
timeout(ms: number): TypedFlow<I, O, Context>;
|
|
21
26
|
catch(fn: (e: any, context: Context) => O | Promise<O>): TypedFlow<I, O, Context>;
|
|
22
27
|
take(n: number): TypedFlow<I, O, Context>;
|
|
@@ -32,6 +37,7 @@ export declare class Flow<Context = {}> {
|
|
|
32
37
|
private onStartHandlers;
|
|
33
38
|
private onDoneHandlers;
|
|
34
39
|
private onErrorHandlers;
|
|
40
|
+
private finallyHandlers;
|
|
35
41
|
private initialInput?;
|
|
36
42
|
constructor(ctx?: Context);
|
|
37
43
|
static from<I, Context = {}>(input: I, context?: Context): TypedFlow<I, I, Context>;
|
|
@@ -52,14 +58,20 @@ export declare class Flow<Context = {}> {
|
|
|
52
58
|
leading(ms: number): any;
|
|
53
59
|
throttle(ms: number): any;
|
|
54
60
|
take(n: number): any;
|
|
61
|
+
map(fn: (v: any, context: Context) => any): any;
|
|
55
62
|
switchMap(fn: Step<any, any, Context>): any;
|
|
56
63
|
exhaustMap(fn: Step<any, any, Context>): any;
|
|
64
|
+
distinct(compare?: (prev: any, next: any) => boolean): any;
|
|
57
65
|
retry(timesOrOptions: number | {
|
|
58
66
|
times: number;
|
|
59
67
|
delay?: number;
|
|
60
68
|
backoff?: "linear" | "exponential";
|
|
61
69
|
}): this;
|
|
62
|
-
poll(
|
|
70
|
+
poll(ms: number, options?: {
|
|
71
|
+
until?: (v: any) => boolean;
|
|
72
|
+
max?: number;
|
|
73
|
+
}): this;
|
|
63
74
|
timeout(ms: number): this;
|
|
64
75
|
catch(fn: (e: any, context: Context) => any): this;
|
|
76
|
+
finally(fn: () => void): this;
|
|
65
77
|
}
|
package/build/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("react");const r=(t,r)=>new Promise((e,s)=>{const n=setTimeout(e,t);r.addEventListener("abort",()=>{clearTimeout(n),s("aborted")})});class e{constructor(t={}){this.ctx=t,this.ops=[],this.controller=null,this.cancelHandlers=[],this.onStartHandlers=[],this.onDoneHandlers=[],this.onErrorHandlers=[]}static from(t,r){const s=new e(r);return s.initialInput=t,s}async run(t){var r;const s=void 0!==t?t:this.initialInput;if(void 0===s)throw Error("Flow.run: missing input");null===(r=this.controller)||void 0===r||r.abort(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let n=s;try{for(const t of this.ops){if(this.controller.signal.aborted)return;await this.waitIfPaused(),n=await t(n,this.ctx,this.controller.signal)}return this.onDoneHandlers.forEach(t=>t()),n}catch(t){if(t===e.SKIP)return;throw this.onErrorHandlers.forEach(r=>r(t)),t}}onStart(t){return this.onStartHandlers.push(t),this}onDone(t){return this.onDoneHandlers.push(t),this}onError(t){return this.onErrorHandlers.push(t),this}onCancel(t){return this.cancelHandlers.push(t),this}cancel(){var t;null===(t=this.controller)||void 0===t||t.abort(),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>this.resume=t)),this}resumeFlow(){return this.paused&&(this.resume(),this.paused=void 0),this}async waitIfPaused(){this.paused&&await this.paused}context(){return this.ctx}step(t){return this.ops.push(t),this}tap(t){return this.step((r,e)=>(t(r,e),r))}filter(t){return this.step(r=>{if(!t(r))throw e.SKIP;return r})}debounce(t){return this.step(async(e,s,n)=>(await r(t,n),e))}leading(t){let r=!1;return this.step(async s=>{if(r)throw e.SKIP;return r=!0,setTimeout(()=>r=!1,t),s})}throttle(t){return this.leading(t)}take(t){let r=0;return this.step(s=>{if(++r>t)throw e.SKIP;return s})}switchMap(t){let r=null;return this.step(async(e,s,n)=>(null==r||r.abort(),r=new AbortController,n.addEventListener("abort",()=>null==r?void 0:r.abort()),t(e,s,r.signal)))}exhaustMap(t){let r=!1;return this.step(async(s,n,i)=>{if(r)throw e.SKIP;r=!0;try{return await t(s,n,i)}finally{r=!1}})}retry(t){const e=this.ops.pop();if(!e)return this;const s="number"==typeof t?{times:t}:t,{times:n,delay:i=0,backoff:o}=s;return this.ops.push(async(t,s,a)=>{let
|
|
1
|
+
"use strict";var t=require("react");const r=(t,r)=>new Promise((e,s)=>{const n=setTimeout(e,t);r.addEventListener("abort",()=>{clearTimeout(n),s("aborted")})});class e{constructor(t={}){this.ctx=t,this.ops=[],this.controller=null,this.cancelHandlers=[],this.onStartHandlers=[],this.onDoneHandlers=[],this.onErrorHandlers=[],this.finallyHandlers=[]}static from(t,r){const s=new e(r);return s.initialInput=t,s}async run(t){var r;const s=void 0!==t?t:this.initialInput;if(void 0===s)throw Error("Flow.run: missing input");null===(r=this.controller)||void 0===r||r.abort(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let n=s;try{for(const t of this.ops){if(this.controller.signal.aborted)return;await this.waitIfPaused(),n=await t(n,this.ctx,this.controller.signal)}return this.onDoneHandlers.forEach(t=>t()),n}catch(t){if(t===e.SKIP)return;throw this.onErrorHandlers.forEach(r=>r(t)),t}finally{this.finallyHandlers.forEach(t=>t())}}onStart(t){return this.onStartHandlers.push(t),this}onDone(t){return this.onDoneHandlers.push(t),this}onError(t){return this.onErrorHandlers.push(t),this}onCancel(t){return this.cancelHandlers.push(t),this}cancel(){var t;null===(t=this.controller)||void 0===t||t.abort(),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>this.resume=t)),this}resumeFlow(){return this.paused&&(this.resume(),this.paused=void 0),this}async waitIfPaused(){this.paused&&await this.paused}context(){return this.ctx}step(t){return this.ops.push(t),this}tap(t){return this.step((r,e)=>(t(r,e),r))}filter(t){return this.step(r=>{if(!t(r))throw e.SKIP;return r})}debounce(t){return this.step(async(e,s,n)=>(await r(t,n),e))}leading(t){let r=!1;return this.step(async s=>{if(r)throw e.SKIP;return r=!0,setTimeout(()=>r=!1,t),s})}throttle(t){return this.leading(t)}take(t){let r=0;return this.step(s=>{if(++r>t)throw e.SKIP;return s})}map(t){return this.step((r,e)=>t(r,e))}switchMap(t){let r=null;return this.step(async(e,s,n)=>(null==r||r.abort(),r=new AbortController,n.addEventListener("abort",()=>null==r?void 0:r.abort()),t(e,s,r.signal)))}exhaustMap(t){let r=!1;return this.step(async(s,n,i)=>{if(r)throw e.SKIP;r=!0;try{return await t(s,n,i)}finally{r=!1}})}distinct(t=Object.is){let r,s=!1;return this.step(n=>{if(s&&t(r,n))throw e.SKIP;return s=!0,r=n,n})}retry(t){const e=this.ops.pop();if(!e)return this;const s="number"==typeof t?{times:t}:t,{times:n,delay:i=0,backoff:o}=s;return this.ops.push(async(t,s,a)=>{let l=0;for(;;)try{return await e(t,s,a)}catch(t){if(l++,l>n)throw t;if(i>0){const t="exponential"===o?i*Math.pow(2,l-1):"linear"===o?i*l:i;await r(t,a)}}}),this}poll(t,e){const s=this.ops.pop();if(!s)return this;const{until:n,max:i}=e||{};return this.ops.push(async(e,o,a)=>{let l,u=0;for(;;){if(l=await s(e,o,a),null==n?void 0:n(l))return l;if(i&&++u>=i)throw Error("poll max reached");await r(t,a)}}),this}timeout(t){const e=this.ops.pop();if(!e)return this;return this.ops.push((s,n,i)=>Promise.race([e(s,n,i),r(t,i).then(()=>{throw Error("timeout")})])),this}catch(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(e,s,n)=>{try{return await r(e,s,n)}catch(r){return t(r,s)}}),this}finally(t){return this.finallyHandlers.push(t),this}}e.SKIP=Symbol("FLOW_SKIP"),exports.Flow=e,exports.sleep=r,exports.useFlow=function(r,s,n){const i=t.useRef(null),o=t.useRef(null!=n?n:{});return o.current=null!=n?n:o.current,t.useEffect(()=>{var t;null===(t=i.current)||void 0===t||t.cancel();const n=e.from(r,o.current),a=s(n);return i.current=a,a.run(),()=>a.cancel()},[r,s]),{cancel:t.useCallback(()=>{var t;null===(t=i.current)||void 0===t||t.cancel()},[]),pause:t.useCallback(()=>{var t;null===(t=i.current)||void 0===t||t.pause()},[]),resume:t.useCallback(()=>{var t;null===(t=i.current)||void 0===t||t.resumeFlow()},[]),flow:i.current}};
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Flow } from "./flow-system/Flow";
|
|
2
|
+
export type { TypedFlow } from "./flow-system/Flow";
|
|
2
3
|
export { useFlow } from "./flow-system/useFlow";
|
|
3
4
|
export type { Step, Condition, CancelHandler } from "./flow-system/types";
|
|
4
5
|
export { sleep } from "./flow-system/utils";
|
package/build/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useRef as t,useEffect as r,useCallback as
|
|
1
|
+
import{useRef as t,useEffect as r,useCallback as n}from"react";const s=(t,r)=>new Promise((n,s)=>{const e=setTimeout(n,t);r.addEventListener("abort",()=>{clearTimeout(e),s("aborted")})});class e{constructor(t={}){this.ctx=t,this.ops=[],this.controller=null,this.cancelHandlers=[],this.onStartHandlers=[],this.onDoneHandlers=[],this.onErrorHandlers=[],this.finallyHandlers=[]}static from(t,r){const n=new e(r);return n.initialInput=t,n}async run(t){var r;const n=void 0!==t?t:this.initialInput;if(void 0===n)throw Error("Flow.run: missing input");null===(r=this.controller)||void 0===r||r.abort(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let s=n;try{for(const t of this.ops){if(this.controller.signal.aborted)return;await this.waitIfPaused(),s=await t(s,this.ctx,this.controller.signal)}return this.onDoneHandlers.forEach(t=>t()),s}catch(t){if(t===e.SKIP)return;throw this.onErrorHandlers.forEach(r=>r(t)),t}finally{this.finallyHandlers.forEach(t=>t())}}onStart(t){return this.onStartHandlers.push(t),this}onDone(t){return this.onDoneHandlers.push(t),this}onError(t){return this.onErrorHandlers.push(t),this}onCancel(t){return this.cancelHandlers.push(t),this}cancel(){var t;null===(t=this.controller)||void 0===t||t.abort(),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>this.resume=t)),this}resumeFlow(){return this.paused&&(this.resume(),this.paused=void 0),this}async waitIfPaused(){this.paused&&await this.paused}context(){return this.ctx}step(t){return this.ops.push(t),this}tap(t){return this.step((r,n)=>(t(r,n),r))}filter(t){return this.step(r=>{if(!t(r))throw e.SKIP;return r})}debounce(t){return this.step(async(r,n,e)=>(await s(t,e),r))}leading(t){let r=!1;return this.step(async n=>{if(r)throw e.SKIP;return r=!0,setTimeout(()=>r=!1,t),n})}throttle(t){return this.leading(t)}take(t){let r=0;return this.step(n=>{if(++r>t)throw e.SKIP;return n})}map(t){return this.step((r,n)=>t(r,n))}switchMap(t){let r=null;return this.step(async(n,s,e)=>(null==r||r.abort(),r=new AbortController,e.addEventListener("abort",()=>null==r?void 0:r.abort()),t(n,s,r.signal)))}exhaustMap(t){let r=!1;return this.step(async(n,s,i)=>{if(r)throw e.SKIP;r=!0;try{return await t(n,s,i)}finally{r=!1}})}distinct(t=Object.is){let r,n=!1;return this.step(s=>{if(n&&t(r,s))throw e.SKIP;return n=!0,r=s,s})}retry(t){const r=this.ops.pop();if(!r)return this;const n="number"==typeof t?{times:t}:t,{times:e,delay:i=0,backoff:o}=n;return this.ops.push(async(t,n,a)=>{let l=0;for(;;)try{return await r(t,n,a)}catch(t){if(l++,l>e)throw t;if(i>0){const t="exponential"===o?i*Math.pow(2,l-1):"linear"===o?i*l:i;await s(t,a)}}}),this}poll(t,r){const n=this.ops.pop();if(!n)return this;const{until:e,max:i}=r||{};return this.ops.push(async(r,o,a)=>{let l,u=0;for(;;){if(l=await n(r,o,a),null==e?void 0:e(l))return l;if(i&&++u>=i)throw Error("poll max reached");await s(t,a)}}),this}timeout(t){const r=this.ops.pop();if(!r)return this;return this.ops.push((n,e,i)=>Promise.race([r(n,e,i),s(t,i).then(()=>{throw Error("timeout")})])),this}catch(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(n,s,e)=>{try{return await r(n,s,e)}catch(r){return t(r,s)}}),this}finally(t){return this.finallyHandlers.push(t),this}}function i(s,i,o){const a=t(null),l=t(null!=o?o:{});l.current=null!=o?o:l.current,r(()=>{var t;null===(t=a.current)||void 0===t||t.cancel();const r=e.from(s,l.current),n=i(r);return a.current=n,n.run(),()=>n.cancel()},[s,i]);return{cancel:n(()=>{var t;null===(t=a.current)||void 0===t||t.cancel()},[]),pause:n(()=>{var t;null===(t=a.current)||void 0===t||t.pause()},[]),resume:n(()=>{var t;null===(t=a.current)||void 0===t||t.resumeFlow()},[]),flow:a.current}}e.SKIP=Symbol("FLOW_SKIP");export{e as Flow,s as sleep,i as useFlow};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-flow-z",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A lightweight async flow runtime for orchestrating side effects with explicit control over cancellation, debounce, throttling, and execution order.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Delpi.Kye",
|