react-flow-z 1.0.0-z
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/LICENSE +21 -0
- package/README.md +223 -0
- package/build/flow-system/Flow.d.ts +55 -0
- package/build/flow-system/types.d.ts +3 -0
- package/build/flow-system/useFlow.d.ts +7 -0
- package/build/flow-system/utils.d.ts +1 -0
- package/build/index.cjs.js +1 -0
- package/build/index.d.ts +4 -0
- package/build/index.esm.js +1 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Delpi.Kye
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# 🌊 react-flow-z
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/react-flow-z) 
|
|
4
|
+
|
|
5
|
+
<a href="https://codesandbox.io/p/sandbox/vkl64l" target="_blank">LIVE EXAMPLE</a>
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
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
|
|
15
|
+
|
|
16
|
+
> This library is about **orchestration**, not reactivity.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Why react-flow-z
|
|
21
|
+
|
|
22
|
+
- Typed async execution pipeline
|
|
23
|
+
- Immutable flow composition
|
|
24
|
+
- Abort & cancellation via `AbortController`
|
|
25
|
+
- Async orchestration operators: `debounce` · `retry` · `timeout` · `switchMap` ·` parallel`
|
|
26
|
+
- Control flow: `filter` · `take` · `conditional execution`
|
|
27
|
+
- Pause / resume execution
|
|
28
|
+
- Framework-agnostic core
|
|
29
|
+
- Optional React hook (`useFlow`)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install react-flow-z
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Basic Usage
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { Flow } from "react-flow-z"
|
|
45
|
+
|
|
46
|
+
new Flow()
|
|
47
|
+
.debounce(300)
|
|
48
|
+
.switchMap(q => fetch(`/search?q=${q}`))
|
|
49
|
+
.tap(res => console.log(res))
|
|
50
|
+
.run("hello")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Cancellation
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const flow = new Flow()
|
|
59
|
+
.step(async (v, _, signal) => {
|
|
60
|
+
await sleep(1000, signal)
|
|
61
|
+
return v
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
flow.run(1)
|
|
65
|
+
flow.cancel()
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Pause / Resume
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
flow.pause()
|
|
74
|
+
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
flow.resumeFlow()
|
|
77
|
+
}, 1000)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## React Integration
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { useFlow } from "react-flow-z"
|
|
86
|
+
|
|
87
|
+
useFlow(
|
|
88
|
+
keyword,
|
|
89
|
+
flow =>
|
|
90
|
+
flow
|
|
91
|
+
.debounce(300)
|
|
92
|
+
.switchMap(search)
|
|
93
|
+
.tap(setResult)
|
|
94
|
+
.catch(() => []),
|
|
95
|
+
{}
|
|
96
|
+
)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Search posts (official example)
|
|
102
|
+
|
|
103
|
+
#### ✅ Pattern 1: Flow instance (recommended)
|
|
104
|
+
|
|
105
|
+
##### searchFlow.ts
|
|
106
|
+
```ts
|
|
107
|
+
import { Flow } from "react-flow-z"
|
|
108
|
+
|
|
109
|
+
export const searchFlow = new Flow()
|
|
110
|
+
.onStart(() => console.log("loading..."))
|
|
111
|
+
.debounce(300)
|
|
112
|
+
.filter((q: string) => q.length > 0)
|
|
113
|
+
.switchMap(async (q: string) => {
|
|
114
|
+
const res = await fetch(
|
|
115
|
+
`https://jsonplaceholder.typicode.com/posts?q=${q}`
|
|
116
|
+
)
|
|
117
|
+
if (!res.ok) throw new Error("network error")
|
|
118
|
+
return res.json()
|
|
119
|
+
})
|
|
120
|
+
.onDone(() => console.log("done"))
|
|
121
|
+
.onError(err => console.error(err))
|
|
122
|
+
|
|
123
|
+
// searchFlow.run("r")
|
|
124
|
+
// searchFlow.run("re")
|
|
125
|
+
// searchFlow.run("react")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
##### React usage
|
|
129
|
+
```ts
|
|
130
|
+
function SearchExample() {
|
|
131
|
+
const [q, setQ] = useState("")
|
|
132
|
+
const [posts, setPosts] = useState<any[]>([])
|
|
133
|
+
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
searchFlow
|
|
136
|
+
.tap(setPosts)
|
|
137
|
+
.catch(() => [])
|
|
138
|
+
.run(q)
|
|
139
|
+
}, [q])
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<>
|
|
143
|
+
<input
|
|
144
|
+
value={q}
|
|
145
|
+
onChange={e => setQ(e.target.value)}
|
|
146
|
+
placeholder="Search posts..."
|
|
147
|
+
/>
|
|
148
|
+
<ul>
|
|
149
|
+
{posts.map(p => (
|
|
150
|
+
<li key={p.id}>{p.title}</li>
|
|
151
|
+
))}
|
|
152
|
+
</ul>
|
|
153
|
+
</>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
#### ✅ Pattern 2: One-off Flow execution
|
|
162
|
+
|
|
163
|
+
##### Submit form – prevent double submit (leading)
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { Flow } from "react-flow-z"
|
|
167
|
+
|
|
168
|
+
export function runSearch(q: string) {
|
|
169
|
+
return new Flow()
|
|
170
|
+
.debounce(300)
|
|
171
|
+
.filter(Boolean)
|
|
172
|
+
.switchMap(async query => {
|
|
173
|
+
const res = await fetch(
|
|
174
|
+
`https://jsonplaceholder.typicode.com/posts?q=${query}`
|
|
175
|
+
)
|
|
176
|
+
if (!res.ok) throw new Error("network error")
|
|
177
|
+
return res.json()
|
|
178
|
+
})
|
|
179
|
+
.run(q)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Philosophy
|
|
187
|
+
|
|
188
|
+
- Explicit over implicit
|
|
189
|
+
- Async/await over streams
|
|
190
|
+
- No global state
|
|
191
|
+
- No magic scheduling
|
|
192
|
+
- You own execution
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Compare high-level
|
|
197
|
+
|
|
198
|
+
| Point | react-flow-z | RxJS | Redux-Saga | XState | React Query |
|
|
199
|
+
| ---------------------- | ------------ | ----- | ---------- | ------- | ----------- |
|
|
200
|
+
| Async orchestration | ✅ | ✅ | ✅ | 🟡 | ❌ |
|
|
201
|
+
| Debounce / cancel | ✅ | ✅ | 🟡 | 🟡 | ❌ |
|
|
202
|
+
| Execution-first design | ✅ | ❌ | 🟡 | ❌ | ❌ |
|
|
203
|
+
| Framework-agnostic | ✅ | ✅ | ❌ | 🟡 | ❌ |
|
|
204
|
+
| Learning curve | ⭐ easy | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐ |
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### What react-flow-z is NOT
|
|
209
|
+
|
|
210
|
+
- ❌ Not a state manager
|
|
211
|
+
- ❌ Not a reactive signal system
|
|
212
|
+
- ❌ Not a data cache like React Query
|
|
213
|
+
- ❌ Not a stream library like RxJS
|
|
214
|
+
|
|
215
|
+
If you only need data fetching → use React Query
|
|
216
|
+
If you need event streams → use RxJS
|
|
217
|
+
If you need **explicit async execution with cancel / debounce / queue** → react-flow-z
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
MIT
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type Step<I, O, Context> = (input: I, context: Context, signal: AbortSignal) => O | Promise<O>;
|
|
2
|
+
export type Condition<T> = (v: T) => boolean;
|
|
3
|
+
export type CancelHandler = () => void;
|
|
4
|
+
export type TypedFlow<I, O, Context> = Flow<Context> & {
|
|
5
|
+
run(input?: I): Promise<O | undefined>;
|
|
6
|
+
step<N>(fn: Step<O, N, Context>): TypedFlow<I, N, Context>;
|
|
7
|
+
tap(fn: (v: O, context: Context) => void): TypedFlow<I, O, Context>;
|
|
8
|
+
filter(cond: Condition<O>): TypedFlow<I, O, Context>;
|
|
9
|
+
debounce(ms: number): TypedFlow<I, O, Context>;
|
|
10
|
+
throttle(ms: number): TypedFlow<I, O, Context>;
|
|
11
|
+
leading(ms: number): TypedFlow<I, O, Context>;
|
|
12
|
+
switchMap<N>(fn: Step<O, N, Context>): TypedFlow<I, N, Context>;
|
|
13
|
+
exhaustMap<N>(fn: Step<O, N, Context>): TypedFlow<I, N, Context>;
|
|
14
|
+
retry(times: number): TypedFlow<I, O, Context>;
|
|
15
|
+
timeout(ms: number): TypedFlow<I, O, Context>;
|
|
16
|
+
catch(fn: (e: any, context: Context) => O | Promise<O>): TypedFlow<I, O, Context>;
|
|
17
|
+
take(n: number): TypedFlow<I, O, Context>;
|
|
18
|
+
};
|
|
19
|
+
export declare class Flow<Context = {}> {
|
|
20
|
+
private readonly ctx;
|
|
21
|
+
static SKIP: symbol;
|
|
22
|
+
private ops;
|
|
23
|
+
private paused?;
|
|
24
|
+
private resume;
|
|
25
|
+
private controller;
|
|
26
|
+
private cancelHandlers;
|
|
27
|
+
private onStartHandlers;
|
|
28
|
+
private onDoneHandlers;
|
|
29
|
+
private onErrorHandlers;
|
|
30
|
+
private initialInput?;
|
|
31
|
+
constructor(ctx?: Context);
|
|
32
|
+
static from<I, Context = {}>(input: I, context?: Context): TypedFlow<I, I, Context>;
|
|
33
|
+
run(input?: unknown): Promise<any>;
|
|
34
|
+
onStart(fn: () => void): this;
|
|
35
|
+
onDone(fn: () => void): this;
|
|
36
|
+
onError(fn: (e: any) => void): this;
|
|
37
|
+
onCancel(fn: CancelHandler): this;
|
|
38
|
+
cancel(): void;
|
|
39
|
+
pause(): this;
|
|
40
|
+
resumeFlow(): this;
|
|
41
|
+
private waitIfPaused;
|
|
42
|
+
context(): Context;
|
|
43
|
+
step(fn: Step<any, any, Context>): any;
|
|
44
|
+
tap(fn: (v: any, context: Context) => void): any;
|
|
45
|
+
filter(cond: Condition<any>): any;
|
|
46
|
+
debounce(ms: number): any;
|
|
47
|
+
leading(ms: number): any;
|
|
48
|
+
throttle(ms: number): any;
|
|
49
|
+
take(n: number): any;
|
|
50
|
+
switchMap(fn: Step<any, any, Context>): any;
|
|
51
|
+
exhaustMap(fn: Step<any, any, Context>): any;
|
|
52
|
+
retry(times: number): this;
|
|
53
|
+
timeout(ms: number): this;
|
|
54
|
+
catch(fn: (e: any, context: Context) => any): this;
|
|
55
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TypedFlow } from "./Flow";
|
|
2
|
+
export declare function useFlow<I, O = I, Context = {}>(source: I, builder: (f: TypedFlow<I, I, Context>) => TypedFlow<I, O, Context>, context?: Context): {
|
|
3
|
+
cancel: () => void;
|
|
4
|
+
pause: () => void;
|
|
5
|
+
resume: () => void;
|
|
6
|
+
flow: TypedFlow<I, O, Context> | null;
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sleep: (ms: number, signal: AbortSignal) => Promise<void>;
|
|
@@ -0,0 +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 r=this.ops.pop();if(!r)return this;return this.ops.push(async(e,s,n)=>{let i=0;for(;;)try{return await r(e,s,n)}catch(r){if(++i>t)throw r}}),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}}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
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useRef as t,useEffect as r,useCallback as n}from"react";const e=(t,r)=>new Promise((n,e)=>{const s=setTimeout(n,t);r.addEventListener("abort",()=>{clearTimeout(s),e("aborted")})});class s{constructor(t={}){this.ctx=t,this.ops=[],this.controller=null,this.cancelHandlers=[],this.onStartHandlers=[],this.onDoneHandlers=[],this.onErrorHandlers=[]}static from(t,r){const n=new s(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 e=n;try{for(const t of this.ops){if(this.controller.signal.aborted)return;await this.waitIfPaused(),e=await t(e,this.ctx,this.controller.signal)}return this.onDoneHandlers.forEach(t=>t()),e}catch(t){if(t===s.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,n)=>(t(r,n),r))}filter(t){return this.step(r=>{if(!t(r))throw s.SKIP;return r})}debounce(t){return this.step(async(r,n,s)=>(await e(t,s),r))}leading(t){let r=!1;return this.step(async n=>{if(r)throw s.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 s.SKIP;return n})}switchMap(t){let r=null;return this.step(async(n,e,s)=>(null==r||r.abort(),r=new AbortController,s.addEventListener("abort",()=>null==r?void 0:r.abort()),t(n,e,r.signal)))}exhaustMap(t){let r=!1;return this.step(async(n,e,i)=>{if(r)throw s.SKIP;r=!0;try{return await t(n,e,i)}finally{r=!1}})}retry(t){const r=this.ops.pop();if(!r)return this;return this.ops.push(async(n,e,s)=>{let i=0;for(;;)try{return await r(n,e,s)}catch(r){if(++i>t)throw r}}),this}timeout(t){const r=this.ops.pop();if(!r)return this;return this.ops.push((n,s,i)=>Promise.race([r(n,s,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(n,e,s)=>{try{return await r(n,e,s)}catch(r){return t(r,e)}}),this}}function i(e,i,o){const a=t(null),u=t(null!=o?o:{});u.current=null!=o?o:u.current,r(()=>{var t;null===(t=a.current)||void 0===t||t.cancel();const r=s.from(e,u.current),n=i(r);return a.current=n,n.run(),()=>n.cancel()},[e,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}}s.SKIP=Symbol("FLOW_SKIP");export{s as Flow,e as sleep,i as useFlow};
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-flow-z",
|
|
3
|
+
"version": "1.0.0-z",
|
|
4
|
+
"description": "A lightweight async flow runtime for orchestrating side effects with explicit control over cancellation, debounce, throttling, and execution order.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Delpi.Kye",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "build/index.cjs.js",
|
|
10
|
+
"module": "build/index.esm.js",
|
|
11
|
+
"types": "build/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./build/index.d.ts",
|
|
15
|
+
"import": "./build/index.esm.js",
|
|
16
|
+
"require": "./build/index.cjs.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": ["build"],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"clean": "rimraf build",
|
|
22
|
+
"dev": "rollup -c -w",
|
|
23
|
+
"build": "rollup -c",
|
|
24
|
+
"cb": "npm run clean && npm run build",
|
|
25
|
+
"lint": "tsc --noEmit",
|
|
26
|
+
"prepublishOnly": "npm run cb"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/delpikye-v/react-flow.git"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/delpikye-v/react-flow#readme",
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/delpikye-v/react-flow/issues"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"async-flow",
|
|
38
|
+
"async-runtime",
|
|
39
|
+
"side-effects",
|
|
40
|
+
"effect-orchestration",
|
|
41
|
+
"cancellation",
|
|
42
|
+
"debounce",
|
|
43
|
+
"throttle",
|
|
44
|
+
"takeLatest",
|
|
45
|
+
"queue",
|
|
46
|
+
"abort-controller",
|
|
47
|
+
"flow-control",
|
|
48
|
+
"headless",
|
|
49
|
+
"framework-agnostic",
|
|
50
|
+
"typescript"
|
|
51
|
+
],
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"react": ">=16.8"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"react": "^18.2.0",
|
|
57
|
+
"react-dom": "^18.2.0",
|
|
58
|
+
"@types/react": "^18.2.0",
|
|
59
|
+
|
|
60
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
61
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
62
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
63
|
+
"rimraf": "^5.0.5",
|
|
64
|
+
"rollup": "^4.12.0",
|
|
65
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
66
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
67
|
+
"tslib": "^2.6.2",
|
|
68
|
+
"typescript": "^5.3.3"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=16.0.0"
|
|
72
|
+
}
|
|
73
|
+
}
|