react-flow-z 1.0.4 → 1.0.5

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 CHANGED
@@ -7,18 +7,13 @@
7
7
  ---
8
8
 
9
9
  `react-flow-z` is a **small, framework-agnostic async flow runtime**.
10
-
11
- It focuses on **how async logic runs**, not:
12
- - how state is stored
13
- - how UI renders
14
- - or how effects are magically managed
10
+ It focuses on **how async logic runs**
15
11
 
16
12
  > This library is about **orchestration**, not reactivity.
17
13
 
18
14
  ---
19
15
 
20
16
  ## Why react-flow-z
21
-
22
17
  - Typed async execution pipeline
23
18
  - Declarative flow composition
24
19
  - Abort & cancellation via `AbortController`
@@ -109,7 +104,7 @@ useFlow(
109
104
 
110
105
  ##### searchFlow.ts
111
106
  ```ts
112
- import { Flow } from "react-flow-z";
107
+ import { Flow, createFlow } from "react-flow-z";
113
108
 
114
109
  export type Post = {
115
110
  id: number;
@@ -134,6 +129,21 @@ export const searchFlow = new Flow<string, Post[]>()
134
129
  // searchFlow.run("react")
135
130
  ```
136
131
 
132
+ ##### createFlow.ts
133
+
134
+ ```ts
135
+ import { Flow, createFlow } from "react-flow-z";
136
+ export const searchFlow = createFlow<string, Post[]>()
137
+ .debounce(300)
138
+ .filter(q => q.trim().length > 0)
139
+ .switchMap(async q => {
140
+ const res = await fetch(
141
+ `https://jsonplaceholder.typicode.com/posts?q=${q}`
142
+ )
143
+ return res.json()
144
+ })
145
+ ```
146
+
137
147
  ##### React usage
138
148
  ```ts
139
149
  import { useEffect, useState } from "react";
@@ -244,13 +254,13 @@ export function runSearch(q: string) {
244
254
 
245
255
  ## Compare high-level
246
256
 
247
- | Point | react-flow-z | RxJS | Redux-Saga | XState | React Query |
248
- | ---------------------- | ------------ | ----- | ---------- | ------- | ----------- |
249
- | Async orchestration | ✅ | ✅ | ✅ | 🟡 | ❌ |
250
- | Debounce / cancel | ✅ | ✅ | 🟡 | 🟡 | ❌ |
251
- | Execution-first design | ✅ | ❌ | 🟡 | ❌ | ❌ |
252
- | Framework-agnostic | ✅ | ✅ | ❌ | 🟡 | ❌ |
253
- | Learning curve | ⭐ easy | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐ |
257
+ | Point | react-flow-z | RxJS | Redux-Saga | XState |
258
+ | ---------------------- | ------------ | ----- | ---------- | ------- |
259
+ | Async orchestration | ✅ | ✅ | ✅ | 🟡 |
260
+ | Debounce / cancel | ✅ | ✅ | 🟡 | 🟡 |
261
+ | Execution-first design | ✅ | ❌ | 🟡 | ❌ |
262
+ | Framework-agnostic | ✅ | ✅ | ❌ | 🟡 |
263
+ | Learning curve | ⭐ easy | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
254
264
 
255
265
  ---
256
266
 
@@ -271,9 +281,7 @@ If you need **explicit async execution with cancel / debounce / queue** → reac
271
281
 
272
282
  - A `Flow` instance is stateful
273
283
  - Operators like `tap`, `catch`, `onDone` mutate the instance
274
- - Prefer:
275
- - configuring the flow once
276
- - handling React state outside the flow
284
+ - Prefer: configuring the flow once, handling React state outside the flow
277
285
 
278
286
  ---
279
287
 
@@ -7,6 +7,7 @@ export type TypedFlow<I, O, Context> = Flow<Context> & {
7
7
  tap(fn: (v: O, context: Context) => void): TypedFlow<I, O, Context>;
8
8
  filter(cond: Condition<O>): TypedFlow<I, O, Context>;
9
9
  debounce(ms: number): TypedFlow<I, O, Context>;
10
+ delay(ms: number): TypedFlow<I, O, Context>;
10
11
  throttle(ms: number): TypedFlow<I, O, Context>;
11
12
  leading(ms: number): TypedFlow<I, O, Context>;
12
13
  map<N>(fn: (v: O, context: Context) => N): TypedFlow<I, N, Context>;
@@ -23,6 +24,7 @@ export type TypedFlow<I, O, Context> = Flow<Context> & {
23
24
  max?: number;
24
25
  }): TypedFlow<I, O, Context>;
25
26
  timeout(ms: number): TypedFlow<I, O, Context>;
27
+ tapError(fn: (v: O, context: Context) => void): TypedFlow<I, O, Context>;
26
28
  catch(fn: (e: any, context: Context) => O | Promise<O>): TypedFlow<I, O, Context>;
27
29
  take(n: number): TypedFlow<I, O, Context>;
28
30
  finally(fn: () => void): TypedFlow<I, O, Context>;
@@ -56,6 +58,7 @@ export declare class Flow<Context = {}> {
56
58
  tap(fn: (v: any, context: Context) => void): any;
57
59
  filter(cond: Condition<any>): any;
58
60
  debounce(ms: number): any;
61
+ delay(ms: number): any;
59
62
  leading(ms: number): any;
60
63
  throttle(ms: number): any;
61
64
  take(n: number): any;
@@ -73,6 +76,7 @@ export declare class Flow<Context = {}> {
73
76
  max?: number;
74
77
  }): this;
75
78
  timeout(ms: number): this;
79
+ tapError(fn: (e: any, context: Context) => void): this;
76
80
  catch(fn: (e: any, context: Context) => any): this;
77
81
  finally(fn: () => void): this;
78
82
  }
@@ -1 +1,3 @@
1
+ import { TypedFlow } from "./Flow";
1
2
  export declare const sleep: (ms: number, signal: AbortSignal) => Promise<void>;
3
+ export declare function createFlow<I, O = I, Context = {}>(context?: Context): TypedFlow<I, O, Context>;
@@ -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")})}),e=Symbol("FLOW_HANDLED");class s{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 e=new s(r);return e.initialInput=t,e}async run(t){const r=void 0!==t?t:this.initialInput;if(void 0===r)throw Error("Flow.run: missing input");this.cancel(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let n=r,i=!1;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===s.SKIP)return void(i=!0);throw(null==t?void 0:t[e])||this.onErrorHandlers.forEach(r=>r(t)),t}finally{i||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.controller=null,this.resume&&(this.resume(),this.resume=void 0,this.paused=void 0),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>{this.resume=t})),this}resumeFlow(){return this.resume&&(this.resume(),this.resume=void 0,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 s.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 e=>{if(r)throw s.SKIP;return r=!0,setTimeout(()=>r=!1,t),e})}throttle(t){return this.leading(t)}take(t){let r=0;return this.step(e=>{if(++r>t)throw s.SKIP;return e})}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(e,n,i)=>{if(r)throw s.SKIP;r=!0;try{return await t(e,n,i)}finally{r=!1}})}distinct(t=Object.is){let r,e=!1;return this.step(n=>{if(e&&t(r,n))throw s.SKIP;return e=!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(s,n,i)=>{try{return await r(s,n,i)}catch(r){return r[e]=!0,t(r,n)}}),this}finally(t){return this.finallyHandlers.push(t),this}}s.SKIP=Symbol("FLOW_SKIP"),exports.Flow=s,exports.sleep=r,exports.useFlow=function(r,e,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=s.from(r,o.current),a=e(n);return i.current=a,a.run(),()=>a.cancel()},[r,e]),{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}};
1
+ "use strict";var t=require("react");const r=(t,r)=>new Promise((s,e)=>{const n=setTimeout(s,t);r.addEventListener("abort",()=>{clearTimeout(n),e("aborted")})});const s=Symbol("FLOW_HANDLED");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){const r=void 0!==t?t:this.initialInput;if(void 0===r)throw Error("Flow.run: missing input");this.cancel(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let n=r,i=!1;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 void(i=!0);throw(null==t?void 0:t[s])||this.onErrorHandlers.forEach(r=>r(t)),t}finally{i||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.controller=null,this.resume&&(this.resume(),this.resume=void 0,this.paused=void 0),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>{this.resume=t})),this}resumeFlow(){return this.resume&&(this.resume(),this.resume=void 0,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,s)=>(t(r,s),r))}filter(t){return this.step(r=>{if(!t(r))throw e.SKIP;return r})}debounce(t){return this.step(async(s,e,n)=>(await r(t,n),s))}delay(t){return this.step(async(s,e,n)=>(await r(t,n),s))}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,s)=>t(r,s))}switchMap(t){let r=null;return this.step(async(s,e,n)=>(null==r||r.abort(),r=new AbortController,n.addEventListener("abort",()=>null==r?void 0:r.abort()),t(s,e,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 s=this.ops.pop();if(!s)return this;const e="number"==typeof t?{times:t}:t,{times:n,delay:i=0,backoff:o}=e;return this.ops.push(async(t,e,a)=>{let u=0;for(;;)try{return await s(t,e,a)}catch(t){if(u++,u>n)throw t;if(i>0){const t="exponential"===o?i*Math.pow(2,u-1):"linear"===o?i*u:i;await r(t,a)}}}),this}poll(t,s){const e=this.ops.pop();if(!e)return this;const{until:n,max:i}=s||{};return this.ops.push(async(s,o,a)=>{let u,l=0;for(;;){if(u=await e(s,o,a),null==n?void 0:n(u))return u;if(i&&++l>=i)throw Error("poll max reached");await r(t,a)}}),this}timeout(t){const s=this.ops.pop();if(!s)return this;return this.ops.push((e,n,i)=>Promise.race([s(e,n,i),r(t,i).then(()=>{throw Error("timeout")})])),this}tapError(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(s,e,n)=>{try{return await r(s,e,n)}catch(r){throw t(r,e),r}}),this}catch(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(e,n,i)=>{try{return await r(e,n,i)}catch(r){return r[s]=!0,t(r,n)}}),this}finally(t){return this.finallyHandlers.push(t),this}}e.SKIP=Symbol("FLOW_SKIP"),exports.Flow=e,exports.createFlow=function(t){return new e(t)},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
@@ -2,4 +2,4 @@ export { Flow } from "./flow-system/Flow";
2
2
  export type { TypedFlow } from "./flow-system/Flow";
3
3
  export { useFlow } from "./flow-system/useFlow";
4
4
  export type { Step, Condition, CancelHandler } from "./flow-system/types";
5
- export { sleep } from "./flow-system/utils";
5
+ export * from "./flow-system/utils";
@@ -1 +1 @@
1
- import{useRef as t,useEffect as r,useCallback as s}from"react";const e=(t,r)=>new Promise((s,e)=>{const n=setTimeout(s,t);r.addEventListener("abort",()=>{clearTimeout(n),e("aborted")})}),n=Symbol("FLOW_HANDLED");class i{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 i(r);return s.initialInput=t,s}async run(t){const r=void 0!==t?t:this.initialInput;if(void 0===r)throw Error("Flow.run: missing input");this.cancel(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let s=r,e=!1;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===i.SKIP)return void(e=!0);throw(null==t?void 0:t[n])||this.onErrorHandlers.forEach(r=>r(t)),t}finally{e||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.controller=null,this.resume&&(this.resume(),this.resume=void 0,this.paused=void 0),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>{this.resume=t})),this}resumeFlow(){return this.resume&&(this.resume(),this.resume=void 0,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,s)=>(t(r,s),r))}filter(t){return this.step(r=>{if(!t(r))throw i.SKIP;return r})}debounce(t){return this.step(async(r,s,n)=>(await e(t,n),r))}leading(t){let r=!1;return this.step(async s=>{if(r)throw i.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 i.SKIP;return s})}map(t){return this.step((r,s)=>t(r,s))}switchMap(t){let r=null;return this.step(async(s,e,n)=>(null==r||r.abort(),r=new AbortController,n.addEventListener("abort",()=>null==r?void 0:r.abort()),t(s,e,r.signal)))}exhaustMap(t){let r=!1;return this.step(async(s,e,n)=>{if(r)throw i.SKIP;r=!0;try{return await t(s,e,n)}finally{r=!1}})}distinct(t=Object.is){let r,s=!1;return this.step(e=>{if(s&&t(r,e))throw i.SKIP;return s=!0,r=e,e})}retry(t){const r=this.ops.pop();if(!r)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 r(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 e(t,a)}}}),this}poll(t,r){const s=this.ops.pop();if(!s)return this;const{until:n,max:i}=r||{};return this.ops.push(async(r,o,a)=>{let l,u=0;for(;;){if(l=await s(r,o,a),null==n?void 0:n(l))return l;if(i&&++u>=i)throw Error("poll max reached");await e(t,a)}}),this}timeout(t){const r=this.ops.pop();if(!r)return this;return this.ops.push((s,n,i)=>Promise.race([r(s,n,i),e(t,i).then(()=>{throw Error("timeout")})])),this}catch(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(s,e,i)=>{try{return await r(s,e,i)}catch(r){return r[n]=!0,t(r,e)}}),this}finally(t){return this.finallyHandlers.push(t),this}}function o(e,n,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=i.from(e,l.current),s=n(r);return a.current=s,s.run(),()=>s.cancel()},[e,n]);return{cancel:s(()=>{var t;null===(t=a.current)||void 0===t||t.cancel()},[]),pause:s(()=>{var t;null===(t=a.current)||void 0===t||t.pause()},[]),resume:s(()=>{var t;null===(t=a.current)||void 0===t||t.resumeFlow()},[]),flow:a.current}}i.SKIP=Symbol("FLOW_SKIP");export{i as Flow,e as sleep,o as useFlow};
1
+ import{useRef as t,useEffect as r,useCallback as s}from"react";const e=(t,r)=>new Promise((s,e)=>{const n=setTimeout(s,t);r.addEventListener("abort",()=>{clearTimeout(n),e("aborted")})});function n(t){return new o(t)}const i=Symbol("FLOW_HANDLED");class o{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 o(r);return s.initialInput=t,s}async run(t){const r=void 0!==t?t:this.initialInput;if(void 0===r)throw Error("Flow.run: missing input");this.cancel(),this.controller=new AbortController,this.onStartHandlers.forEach(t=>t());let s=r,e=!1;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===o.SKIP)return void(e=!0);throw(null==t?void 0:t[i])||this.onErrorHandlers.forEach(r=>r(t)),t}finally{e||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.controller=null,this.resume&&(this.resume(),this.resume=void 0,this.paused=void 0),this.cancelHandlers.forEach(t=>t())}pause(){return this.paused||(this.paused=new Promise(t=>{this.resume=t})),this}resumeFlow(){return this.resume&&(this.resume(),this.resume=void 0,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,s)=>(t(r,s),r))}filter(t){return this.step(r=>{if(!t(r))throw o.SKIP;return r})}debounce(t){return this.step(async(r,s,n)=>(await e(t,n),r))}delay(t){return this.step(async(r,s,n)=>(await e(t,n),r))}leading(t){let r=!1;return this.step(async s=>{if(r)throw o.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 o.SKIP;return s})}map(t){return this.step((r,s)=>t(r,s))}switchMap(t){let r=null;return this.step(async(s,e,n)=>(null==r||r.abort(),r=new AbortController,n.addEventListener("abort",()=>null==r?void 0:r.abort()),t(s,e,r.signal)))}exhaustMap(t){let r=!1;return this.step(async(s,e,n)=>{if(r)throw o.SKIP;r=!0;try{return await t(s,e,n)}finally{r=!1}})}distinct(t=Object.is){let r,s=!1;return this.step(e=>{if(s&&t(r,e))throw o.SKIP;return s=!0,r=e,e})}retry(t){const r=this.ops.pop();if(!r)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 u=0;for(;;)try{return await r(t,s,a)}catch(t){if(u++,u>n)throw t;if(i>0){const t="exponential"===o?i*Math.pow(2,u-1):"linear"===o?i*u:i;await e(t,a)}}}),this}poll(t,r){const s=this.ops.pop();if(!s)return this;const{until:n,max:i}=r||{};return this.ops.push(async(r,o,a)=>{let u,h=0;for(;;){if(u=await s(r,o,a),null==n?void 0:n(u))return u;if(i&&++h>=i)throw Error("poll max reached");await e(t,a)}}),this}timeout(t){const r=this.ops.pop();if(!r)return this;return this.ops.push((s,n,i)=>Promise.race([r(s,n,i),e(t,i).then(()=>{throw Error("timeout")})])),this}tapError(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(s,e,n)=>{try{return await r(s,e,n)}catch(r){throw t(r,e),r}}),this}catch(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(s,e,n)=>{try{return await r(s,e,n)}catch(r){return r[i]=!0,t(r,e)}}),this}finally(t){return this.finallyHandlers.push(t),this}}function a(e,n,i){const a=t(null),u=t(null!=i?i:{});u.current=null!=i?i:u.current,r(()=>{var t;null===(t=a.current)||void 0===t||t.cancel();const r=o.from(e,u.current),s=n(r);return a.current=s,s.run(),()=>s.cancel()},[e,n]);return{cancel:s(()=>{var t;null===(t=a.current)||void 0===t||t.cancel()},[]),pause:s(()=>{var t;null===(t=a.current)||void 0===t||t.pause()},[]),resume:s(()=>{var t;null===(t=a.current)||void 0===t||t.resumeFlow()},[]),flow:a.current}}o.SKIP=Symbol("FLOW_SKIP");export{o as Flow,n as createFlow,e as sleep,a as useFlow};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-flow-z",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
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",