@dmop/puru 0.1.5 → 0.1.10
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/AGENTS.md +18 -42
- package/README.md +159 -434
- package/dist/index.cjs +38 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -15
- package/dist/index.d.ts +26 -15
- package/dist/index.js +40 -43
- package/dist/index.js.map +1 -1
- package/llms-full.txt +1 -1
- package/package.json +34 -4
package/AGENTS.md
CHANGED
|
@@ -80,66 +80,42 @@ const { result } = spawn(() => {
|
|
|
80
80
|
console.log(await result)
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
### Multiple tasks in parallel (
|
|
83
|
+
### Multiple tasks in parallel (`task()`)
|
|
84
84
|
|
|
85
85
|
```typescript
|
|
86
|
-
import {
|
|
86
|
+
import { task } from '@dmop/puru'
|
|
87
87
|
|
|
88
88
|
const items = [1, 2, 3, 4]
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
for (const item of items) {
|
|
92
|
-
const value = item // capture as a literal for each iteration
|
|
93
|
-
wg.spawn(() => {
|
|
94
|
-
// `value` is NOT captured from closure — this won't work
|
|
95
|
-
// you must inline or use register()/run()
|
|
96
|
-
})
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
To pass per-task data, use `register`/`run`:
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
import { register, run, WaitGroup } from '@dmop/puru'
|
|
104
|
-
|
|
105
|
-
// Register once at startup
|
|
106
|
-
register('processItem', (item: number) => item * 2)
|
|
107
|
-
|
|
108
|
-
const items = [1, 2, 3, 4]
|
|
109
|
-
const wg = new WaitGroup()
|
|
110
|
-
for (const item of items) {
|
|
111
|
-
wg.spawn(() => run('processItem', item))
|
|
112
|
-
}
|
|
113
|
-
const results = await wg.wait()
|
|
89
|
+
const processItem = task((item: number) => item * 2)
|
|
90
|
+
const results = await Promise.all(items.map((item) => processItem(item)))
|
|
114
91
|
```
|
|
115
92
|
|
|
116
93
|
### Concurrent I/O (concurrent mode)
|
|
117
94
|
|
|
118
95
|
```typescript
|
|
119
|
-
import {
|
|
96
|
+
import { spawn } from '@dmop/puru'
|
|
120
97
|
|
|
121
|
-
const
|
|
122
|
-
|
|
98
|
+
const user = spawn(
|
|
99
|
+
() => fetch('https://api.example.com/users/1').then((r) => r.json()),
|
|
100
|
+
{ concurrent: true },
|
|
101
|
+
)
|
|
123
102
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
103
|
+
const orders = spawn(
|
|
104
|
+
() => fetch('https://api.example.com/users/1/orders').then((r) => r.json()),
|
|
105
|
+
{ concurrent: true },
|
|
106
|
+
)
|
|
127
107
|
|
|
128
|
-
|
|
129
|
-
const results = await wg.wait()
|
|
108
|
+
const results = await Promise.all([user.result, orders.result])
|
|
130
109
|
```
|
|
131
110
|
|
|
132
111
|
### Cancel on first error (ErrGroup)
|
|
133
112
|
|
|
134
113
|
```typescript
|
|
135
|
-
import { ErrGroup
|
|
136
|
-
|
|
137
|
-
register('fetchUser', (id: number) => fetch(`/api/users/${id}`).then(r => r.json()))
|
|
138
|
-
register('fetchOrders', (id: number) => fetch(`/api/orders/${id}`).then(r => r.json()))
|
|
114
|
+
import { ErrGroup } from '@dmop/puru'
|
|
139
115
|
|
|
140
116
|
const eg = new ErrGroup()
|
|
141
|
-
eg.spawn(() =>
|
|
142
|
-
eg.spawn(() =>
|
|
117
|
+
eg.spawn(() => fetch('https://api.example.com/users/1').then((r) => r.json()), { concurrent: true })
|
|
118
|
+
eg.spawn(() => fetch('https://api.example.com/users/1/orders').then((r) => r.json()), { concurrent: true })
|
|
143
119
|
|
|
144
120
|
const [user, orders] = await eg.wait() // throws on first error, cancels the rest
|
|
145
121
|
```
|
|
@@ -202,7 +178,7 @@ configure({ adapter: 'inline' })
|
|
|
202
178
|
|
|
203
179
|
## Runtimes
|
|
204
180
|
|
|
205
|
-
- Node.js >=
|
|
181
|
+
- Node.js >= 20: full support
|
|
206
182
|
- Bun: full support
|
|
207
183
|
- Deno: planned
|
|
208
184
|
- Cloudflare Workers / Vercel Edge: not supported (no thread API)
|