@effectionx/worker 0.4.2 → 0.5.0
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 +130 -0
- package/channel.test.ts +902 -0
- package/channel.ts +380 -0
- package/dist/channel.d.ts +167 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +236 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +137 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +27 -1
- package/dist/worker-main.d.ts +16 -2
- package/dist/worker-main.d.ts.map +1 -1
- package/dist/worker-main.js +78 -6
- package/dist/worker.d.ts +34 -2
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +138 -22
- package/package.json +3 -1
- package/test-assets/bidirectional-worker.ts +19 -0
- package/test-assets/concurrent-requests-worker.ts +9 -0
- package/test-assets/error-cause-worker.ts +19 -0
- package/test-assets/error-handling-worker.ts +12 -0
- package/test-assets/error-throw-worker.ts +9 -0
- package/test-assets/no-requests-worker.ts +5 -0
- package/test-assets/send-inside-foreach-worker.ts +18 -0
- package/test-assets/sequential-requests-worker.ts +10 -0
- package/test-assets/single-request-worker.ts +8 -0
- package/test-assets/slow-request-worker.ts +8 -0
- package/tsconfig.json +3 -0
- package/types.ts +157 -3
- package/worker-main.ts +119 -8
- package/worker.test.ts +302 -4
- package/worker.ts +213 -29
- package/dist/message-channel.d.ts +0 -3
- package/dist/message-channel.d.ts.map +0 -1
- package/dist/message-channel.js +0 -13
- package/message-channel.ts +0 -13
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ thread.
|
|
|
17
17
|
- Gracefully shutdowns the worker from the main thread
|
|
18
18
|
- Propagates errors from the worker to the main thread
|
|
19
19
|
- Type-safe message handling with TypeScript
|
|
20
|
+
- Supports worker-initiated requests handled by the host
|
|
20
21
|
|
|
21
22
|
## Usage: Get worker's return value
|
|
22
23
|
|
|
@@ -84,6 +85,135 @@ try {
|
|
|
84
85
|
}
|
|
85
86
|
```
|
|
86
87
|
|
|
88
|
+
## Usage: Worker-initiated requests
|
|
89
|
+
|
|
90
|
+
Workers can initiate requests to the host using the `send` function provided to
|
|
91
|
+
`workerMain`. The host handles these requests with `worker.forEach`, returning a
|
|
92
|
+
response for each request.
|
|
93
|
+
|
|
94
|
+
### Worker Thread
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { workerMain } from "@effectionx/worker";
|
|
98
|
+
|
|
99
|
+
await workerMain<never, never, string, void, string, string>(
|
|
100
|
+
function* ({ send }) {
|
|
101
|
+
const response = yield* send("hello");
|
|
102
|
+
return `received: ${response}`;
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Main Thread
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { run } from "effection";
|
|
111
|
+
import { useWorker } from "@effectionx/worker";
|
|
112
|
+
|
|
113
|
+
await run(function* () {
|
|
114
|
+
const worker = yield* useWorker<never, never, string, void>(
|
|
115
|
+
"./worker.ts",
|
|
116
|
+
{ type: "module" },
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const result = yield* worker.forEach<string, string>(function* (request) {
|
|
120
|
+
return `echo: ${request}`;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
console.log(result); // Output: received: echo: hello
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Notes
|
|
128
|
+
|
|
129
|
+
- Only one `forEach` can be active at a time; concurrent calls throw.
|
|
130
|
+
- Requests are queued until `forEach` is called.
|
|
131
|
+
- Errors are serialized and rethrown on the caller side.
|
|
132
|
+
|
|
133
|
+
## Usage: Progress streaming
|
|
134
|
+
|
|
135
|
+
The host can send progress updates back to the worker during request processing.
|
|
136
|
+
This enables real-time feedback for long-running operations.
|
|
137
|
+
|
|
138
|
+
### Worker Thread
|
|
139
|
+
|
|
140
|
+
Use `send.stream<TProgress>()` to receive a subscription that yields progress
|
|
141
|
+
values before the final response:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { workerMain } from "@effectionx/worker";
|
|
145
|
+
|
|
146
|
+
interface Progress {
|
|
147
|
+
percent: number;
|
|
148
|
+
message: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
await workerMain<never, never, string, void, string, string>(
|
|
152
|
+
function* ({ send }) {
|
|
153
|
+
// Request with progress streaming
|
|
154
|
+
const subscription = yield* send.stream<Progress>("process-data");
|
|
155
|
+
|
|
156
|
+
let next = yield* subscription.next();
|
|
157
|
+
while (!next.done) {
|
|
158
|
+
const progress = next.value;
|
|
159
|
+
console.log(`${progress.percent}%: ${progress.message}`);
|
|
160
|
+
next = yield* subscription.next();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Final response
|
|
164
|
+
return `completed: ${next.value}`;
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Main Thread
|
|
170
|
+
|
|
171
|
+
The `forEach` handler receives a context object with a `progress()` method:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { run } from "effection";
|
|
175
|
+
import { useWorker } from "@effectionx/worker";
|
|
176
|
+
|
|
177
|
+
interface Progress {
|
|
178
|
+
percent: number;
|
|
179
|
+
message: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await run(function* () {
|
|
183
|
+
const worker = yield* useWorker<never, never, string, void>(
|
|
184
|
+
"./worker.ts",
|
|
185
|
+
{ type: "module" },
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const result = yield* worker.forEach<string, string, Progress>(
|
|
189
|
+
function* (request, ctx) {
|
|
190
|
+
yield* ctx.progress({ percent: 25, message: "Loading..." });
|
|
191
|
+
yield* ctx.progress({ percent: 50, message: "Processing..." });
|
|
192
|
+
yield* ctx.progress({ percent: 75, message: "Finalizing..." });
|
|
193
|
+
return "done";
|
|
194
|
+
},
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
console.log(result); // Output: completed: done
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Backpressure
|
|
202
|
+
|
|
203
|
+
The `progress()` method implements true backpressure:
|
|
204
|
+
|
|
205
|
+
- **`ctx.progress()` blocks** until the worker calls `subscription.next()`
|
|
206
|
+
- The host cannot send progress faster than the worker can receive it
|
|
207
|
+
- If the worker does async work between `next()` calls, the host remains blocked
|
|
208
|
+
|
|
209
|
+
This ensures the worker is never overwhelmed with progress updates.
|
|
210
|
+
|
|
211
|
+
### Notes
|
|
212
|
+
|
|
213
|
+
- `send(request)` still works for simple request/response (ignores any progress)
|
|
214
|
+
- Progress type is the third type parameter on `forEach<TRequest, TResponse, TProgress>`
|
|
215
|
+
- The subscription's final `next()` returns `{ done: true, value: TResponse }`
|
|
216
|
+
|
|
87
217
|
## Usage: Sending messages to the worker
|
|
88
218
|
|
|
89
219
|
The worker can respond to incoming messages using `forEach` function provided by
|