@nadrif/thread 0.1.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/src/index.js ADDED
@@ -0,0 +1,557 @@
1
+ /**
2
+ * @file thread — Enterprise Web Worker & GPU Compute Framework
3
+ *
4
+ * A modular, feature-rich library for running CPU-intensive work in
5
+ * **Web Workers** and **WebGPU compute shaders**, with a thread pool,
6
+ * work-stealing, dependency tracking, health checks, and framework
7
+ * adapters for Preact, React, Zustand, and Preact Signals.
8
+ *
9
+ * ---
10
+ *
11
+ * ## Architecture
12
+ *
13
+ * ```
14
+ * thread
15
+ * ├── Thread – Single worker with full lifecycle management
16
+ * ├── ThreadPool – Pool with priority queue, deps, work-stealing
17
+ * ├── GPUCompute – WebGPU compute shader executor
18
+ * │ ├── PipelineChain – Fluent multi-step GPU pipelines
19
+ * │ ├── DataPipelineChain – Data-carrying pipelines with named methods
20
+ * │ └── 57+ built-in ops – multiply, sqrt, ema, reduce, matmul, …
21
+ * ├── Metrics – Performance counters (avg, throughput, errors)
22
+ * ├── Serializer – JSON-safe serialization with function support
23
+ * ├── Errors – Typed error hierarchy (timeout, abort, GPU, …)
24
+ * ├── Factories – createThread, createPool, createGPUOp, …
25
+ * ├── Hooks – useThread, usePool, useGPU (Preact/React)
26
+ * └── Adapters – Zustand, Signals, generic store bindings
27
+ * ```
28
+ *
29
+ * ---
30
+ *
31
+ * ## Quick start
32
+ *
33
+ * ### CPU workers
34
+ *
35
+ * ```js
36
+ * import { createThread, createPool } from 'thread';
37
+ *
38
+ * // Single thread
39
+ * const t = createThread((x) => x * 2);
40
+ * console.log(await t.run(5)); // 10
41
+ *
42
+ * // Thread pool
43
+ * const pool = createPool(4, (x) => x + 1);
44
+ * const { id, promise } = pool.run(1);
45
+ * console.log(await promise); // 2
46
+ * ```
47
+ *
48
+ * ### GPU compute
49
+ *
50
+ * ```js
51
+ * import { createGPUOp } from 'thread';
52
+ *
53
+ * // One-liner GPU operation
54
+ * const gpu = createGPUOp('double', (data) => data.value * 2);
55
+ * const result = await gpu.run('double', {
56
+ * inputs: { data: new Float32Array([1, 2, 3]) },
57
+ * outputs: { result: 3 },
58
+ * });
59
+ * console.log(result.result); // Float32Array [2, 4, 6]
60
+ * ```
61
+ *
62
+ * ---
63
+ *
64
+ * ## Full feature tour
65
+ *
66
+ * ### 1. Stateful workers with setup / exec / cleanup
67
+ *
68
+ * ```js
69
+ * import { createThread } from 'thread';
70
+ *
71
+ * const db = createThread({
72
+ * setup() {
73
+ * return { conn: openDatabase() };
74
+ * },
75
+ * async exec(state, query, ctx) {
76
+ * ctx.log(`Running: ${query}`);
77
+ * return state.conn.query(query);
78
+ * },
79
+ * async cleanup(state) {
80
+ * await state.conn.close();
81
+ * ctx.log('Connection closed');
82
+ * },
83
+ * }, { timeout: 10_000 });
84
+ *
85
+ * const rows = await db.run('SELECT * FROM users');
86
+ * await db.terminateGracefully(); // cleanup runs
87
+ * ```
88
+ *
89
+ * ### 2. Timeouts, abort, and retries
90
+ *
91
+ * ```js
92
+ * import { createThread, ThreadTimeoutError, ThreadAbortError } from 'thread';
93
+ *
94
+ * const t = createThread((data) => heavyProcess(data));
95
+ * const controller = new AbortController();
96
+ *
97
+ * try {
98
+ * const result = await t.run(hugeData, {
99
+ * timeout: 30_000,
100
+ * signal: controller.signal,
101
+ * retries: 2,
102
+ * transfer: [hugeData.buffer],
103
+ * });
104
+ * } catch (err) {
105
+ * if (err instanceof ThreadTimeoutError) {
106
+ * console.error('Too slow – aborting');
107
+ * controller.abort();
108
+ * }
109
+ * }
110
+ * ```
111
+ *
112
+ * ### 3. Pool with priorities and dependencies
113
+ *
114
+ * ```js
115
+ * import { createPool } from 'thread';
116
+ *
117
+ * const pool = createPool(4, (x) => x * 2);
118
+ *
119
+ * // High priority runs first
120
+ * pool.run(urgent, { priority: 0 });
121
+ * pool.run(batch, { priority: 10 });
122
+ *
123
+ * // Dependency chain: fetch → transform → store
124
+ * const fetched = pool.run(url1);
125
+ * const transformed = pool.run(fetchResult, { dependsOn: [fetched.id] });
126
+ * const stored = pool.run(transformed, { dependsOn: [transformed.id] });
127
+ *
128
+ * await stored.promise;
129
+ * console.log('Pipeline complete');
130
+ * ```
131
+ *
132
+ * ### 4. GPU — define ops from plain JS
133
+ *
134
+ * ```js
135
+ * import { createGPUOp } from 'thread';
136
+ *
137
+ * // EMA (Exponential Moving Average)
138
+ * const gpu = createGPUOp('ema', (data, { alpha }) =>
139
+ * data.value * alpha + data.index * (1 - alpha)
140
+ * );
141
+ *
142
+ * const result = await gpu.run('ema', {
143
+ * inputs: { data: new Float32Array([100, 102, 101, 105, 107]) },
144
+ * uniforms: { alpha: new Float32Array([0.3]) },
145
+ * outputs: { result: 5 },
146
+ * });
147
+ * ```
148
+ *
149
+ * ### 5. GPU pipeline chaining
150
+ *
151
+ * ```js * import { GPUCompute } from 'thread';
152
+ *
153
+ * const gpu = new GPUCompute();
154
+ * gpu.define('ema', (data, { alpha }) => data.value * alpha);
155
+ * gpu.define('double', (data) => data.value * 2);
156
+ *
157
+ * const chain = gpu.pipe()
158
+ * .add('ema', { inputs: { data: prices }, uniforms: { alpha: new Float32Array([0.3]) } })
159
+ * .add('double');
160
+ *
161
+ * const output = await chain.result();
162
+ * ```
163
+ *
164
+ * ### 6. GPU fluent data pipeline
165
+ *
166
+ * ```js * const gpu = new GPUCompute();
167
+ * gpu.define('ema', (data, { alpha }) => data.value * alpha);
168
+ * gpu.define('double', (data) => data.value * 2);
169
+ *
170
+ * // Data-carrying chain with named methods
171
+ * const output = await gpu.pipe(new Float32Array([1, 2, 3]))
172
+ * .ema({ alpha: 0.3 })
173
+ * .double()
174
+ * .result();
175
+ * ```
176
+ *
177
+ * ### 7. GPU reductions and special ops
178
+ *
179
+ * ```js
180
+ * import { createGPUReducer } from 'thread';
181
+ *
182
+ * const gpu = createGPUReducer();
183
+ * const data = new Float32Array([1, 2, 3, 4, 5]);
184
+ *
185
+ * const sum = await gpu.run('reduce_sum', {
186
+ * inputs: { data },
187
+ * outputs: { result: 5 },
188
+ * });
189
+ * // sum.result → Float32Array([15])
190
+ *
191
+ * const max = await gpu.run('reduce_max', {
192
+ * inputs: { data },
193
+ * outputs: { result: 5 },
194
+ * });
195
+ * // max.result → Float32Array([5])
196
+ * ```
197
+ *
198
+ * ### 8. GPU map() — parallel element-wise transform
199
+ *
200
+ * ```js * const gpu = new GPUCompute();
201
+ * const result = await gpu.map(
202
+ * new Float32Array([1, 4, 9, 16]),
203
+ * (x) => Math.sqrt(x)
204
+ * );
205
+ * // result → Float32Array([1, 2, 3, 4])
206
+ * ```
207
+ *
208
+ * ### 9. Preact / React hooks
209
+ *
210
+ * ```jsx
211
+ * import { useGPU, useThread, usePool } from 'thread';
212
+ *
213
+ * function GPUDemo({ prices }) {
214
+ * const { run, result, loading, error, status } = useGPU();
215
+ *
216
+ * return (
217
+ * <div>
218
+ * <p>GPU: {status}</p>
219
+ * <button onClick={() => run('ema', { inputs: { data: prices }, ... })} disabled={loading}>
220
+ * {loading ? 'Computing...' : 'Run EMA'}
221
+ * </button>
222
+ * {error && <p className="error">{error}</p>}
223
+ * </div>
224
+ * );
225
+ * }
226
+ * ```
227
+ *
228
+ * ### 10. Zustand / Signal adapters
229
+ *
230
+ * ```js
231
+ * import { createGPUBinder, createGPUSignalBinder } from 'thread';
232
+ * import { signal } from '@preact/signals';
233
+ *
234
+ * // Bind GPU to Zustand store
235
+ * const binder = createGPUBinder(gpu, useStore, 'setData', {
236
+ * errorAction: 'setError',
237
+ * });
238
+ * await binder.run('ema', { inputs: { data: prices }, ... });
239
+ *
240
+ * // Bind GPU to a Preact Signal
241
+ * const dataSignal = signal(null);
242
+ * const sigBinder = createGPUSignalBinder(gpu, dataSignal);
243
+ * await sigBinder.run('ema', { inputs: { data: prices }, ... });
244
+ * console.log(dataSignal.value);
245
+ * ```
246
+ *
247
+ * ---
248
+ *
249
+ * ## TypeScript
250
+ *
251
+ * Import types from `thread/types`:
252
+ *
253
+ * ```ts
254
+ * import type {
255
+ * ThreadDefinition,
256
+ * ThreadOptions,
257
+ * ThreadRunOptions,
258
+ * PoolOptions,
259
+ * PoolRunOptions,
260
+ * PoolTaskResult,
261
+ * PoolStatus,
262
+ * MetricsSnapshot,
263
+ * ThreadEventName,
264
+ * GPUComputeOptions,
265
+ * GPUComputeInput,
266
+ * GPUComputeSnapshot,
267
+ * OpDeclaration,
268
+ * UseThreadReturn,
269
+ * UsePoolReturn,
270
+ * UseGPUReturn,
271
+ * ZustandBinderOptions,
272
+ * SignalBinderOptions,
273
+ * StoreBinderOptions,
274
+ * BinderHandle,
275
+ * Signal,
276
+ * } from 'thread/types';
277
+ * ```
278
+ *
279
+ * ---
280
+ *
281
+ * ## Error handling
282
+ *
283
+ * All errors extend `ThreadError`:
284
+ *
285
+ * | Error | When |
286
+ * |--------------------------|-------------------------------------------|
287
+ * | `ThreadTimeoutError` | Task exceeded its timeout |
288
+ * | `ThreadAbortError` | Task was aborted via AbortController |
289
+ * | `ThreadTerminatedError` | Thread/pool was terminated |
290
+ * | `ThreadHealthError` | Health check failed (internal) |
291
+ * | `ThreadDependencyError` | A dependency task failed |
292
+ * | `GPUComputeError` | Shader compilation, buffer, or dispatch |
293
+ *
294
+ * ```js
295
+ * import { ThreadError, ThreadTimeoutError, GPUComputeError } from 'thread';
296
+ *
297
+ * try {
298
+ * await gpu.run('myOp', input);
299
+ * } catch (err) {
300
+ * if (err instanceof GPUComputeError) {
301
+ * console.error(`GPU failed: ${err.message}`);
302
+ * } else if (err instanceof ThreadTimeoutError) {
303
+ * console.error('Timed out');
304
+ * }
305
+ * }
306
+ * ```
307
+ *
308
+ * ---
309
+ *
310
+ * @module thread
311
+ */
312
+
313
+ import {
314
+ ThreadAbortError,
315
+ ThreadDependencyError,
316
+ ThreadError,
317
+ ThreadHealthError,
318
+ ThreadTerminatedError,
319
+ ThreadTimeoutError,
320
+ GPUComputeError,
321
+ } from "./error";
322
+ import {
323
+ createPool,
324
+ createThread,
325
+ createWorker,
326
+ createWorkerDef,
327
+ createManagedThread,
328
+ createGPUOp,
329
+ createGPUPipeline,
330
+ createGPUReducer,
331
+ } from "./factory";
332
+ import {
333
+ useThread,
334
+ usePool,
335
+ useThreadMetrics,
336
+ usePoolMetrics,
337
+ useThreadWorker,
338
+ useThreadEvent,
339
+ } from "./hooks";
340
+ import {
341
+ createZustandBinder,
342
+ createSignalBinder,
343
+ createStoreBinder,
344
+ createPoolBinder,
345
+ } from "./adapters";
346
+ import {
347
+ GPUCompute,
348
+ PipelineChain,
349
+ DataPipelineChain,
350
+ createGPUCompute,
351
+ createGPUWithFallback,
352
+ outputSpec,
353
+ uniform,
354
+ } from "./gpu/index.js";
355
+ import {
356
+ useGPU,
357
+ useGPURun,
358
+ useGPUMetrics,
359
+ useGPUStatus,
360
+ } from "./gpu/hooks.js";
361
+ import {
362
+ createGPUBinder,
363
+ createGPUSignalBinder,
364
+ createGPUStoreBinder,
365
+ } from "./gpu/adapters.js";
366
+ import {
367
+ buildShader,
368
+ BUILT_IN_OPS,
369
+ BUILT_IN_OP_NAMES,
370
+ SPECIAL_OPS
371
+ } from "./gpu/shaders.js";
372
+ import { Metrics } from "./metrix";
373
+ import { ThreadPool } from "./pool";
374
+ import { Serializer } from "./serializer";
375
+ import { Thread } from "./thread";
376
+ import { defineConfig,
377
+ getConfig,
378
+ setConfig,
379
+ DEFAULTS,
380
+ FRAMEWORKS,
381
+ STATE_MANAGERS,
382
+ mergeWithDefaults,
383
+ validateConfig,
384
+ resolveHooks,
385
+ getAdapter } from "./config.js";
386
+ import { env } from "./env.js";
387
+ import {
388
+ createWorker as createPlatformWorker,
389
+ terminateWorker,
390
+ supportsWorkers,
391
+ workerInfo
392
+ } from "./worker-factory.js";
393
+ import { gpuEnv,
394
+ isGPUAvailable,
395
+ requestGPUAdapter,
396
+ requestGPUDevice
397
+ } from "./gpu/env.js";
398
+
399
+ export {
400
+ // Errors
401
+ ThreadError,
402
+ ThreadTimeoutError,
403
+ ThreadAbortError,
404
+ ThreadTerminatedError,
405
+ ThreadHealthError,
406
+ ThreadDependencyError,
407
+ GPUComputeError,
408
+ // Classes
409
+ Metrics,
410
+ Serializer,
411
+ Thread,
412
+ ThreadPool,
413
+ GPUCompute,
414
+ PipelineChain,
415
+ DataPipelineChain,
416
+ // CPU Factories
417
+ createThread,
418
+ createPool,
419
+ createWorker,
420
+ createWorkerDef,
421
+ createManagedThread,
422
+ // GPU Factories
423
+ createGPUCompute,
424
+ createGPUWithFallback,
425
+ createGPUOp,
426
+ createGPUPipeline,
427
+ createGPUReducer,
428
+ outputSpec,
429
+ uniform,
430
+ // Shaders
431
+ buildShader,
432
+ BUILT_IN_OPS,
433
+ BUILT_IN_OP_NAMES,
434
+ SPECIAL_OPS,
435
+ // Hooks (Preact / React)
436
+ useThread,
437
+ usePool,
438
+ useThreadMetrics,
439
+ usePoolMetrics,
440
+ useThreadWorker,
441
+ useThreadEvent,
442
+ // GPU Hooks (Preact / React)
443
+ useGPU,
444
+ useGPURun,
445
+ useGPUMetrics,
446
+ useGPUStatus,
447
+ // Adapters (framework-agnostic)
448
+ createZustandBinder,
449
+ createSignalBinder,
450
+ createStoreBinder,
451
+ createPoolBinder,
452
+ // GPU Adapters
453
+ createGPUBinder,
454
+ createGPUSignalBinder,
455
+ createGPUStoreBinder,
456
+ // Config
457
+ defineConfig,
458
+ getConfig,
459
+ setConfig,
460
+ DEFAULTS,
461
+ FRAMEWORKS,
462
+ STATE_MANAGERS,
463
+ mergeWithDefaults,
464
+ validateConfig,
465
+ resolveHooks,
466
+ getAdapter,
467
+ // Environment
468
+ env,
469
+ createPlatformWorker,
470
+ terminateWorker,
471
+ supportsWorkers,
472
+ workerInfo,
473
+ gpuEnv,
474
+ isGPUAvailable,
475
+ requestGPUAdapter,
476
+ requestGPUDevice,
477
+ };
478
+
479
+ export default {
480
+ // Errors
481
+ ThreadError,
482
+ ThreadTimeoutError,
483
+ ThreadAbortError,
484
+ ThreadTerminatedError,
485
+ ThreadHealthError,
486
+ ThreadDependencyError,
487
+ GPUComputeError,
488
+ // Classes
489
+ Metrics,
490
+ Serializer,
491
+ Thread,
492
+ ThreadPool,
493
+ GPUCompute,
494
+ PipelineChain,
495
+ DataPipelineChain,
496
+ // CPU Factories
497
+ createThread,
498
+ createPool,
499
+ createWorker,
500
+ createWorkerDef,
501
+ createManagedThread,
502
+ // GPU Factories
503
+ createGPUCompute,
504
+ createGPUWithFallback,
505
+ createGPUOp,
506
+ createGPUPipeline,
507
+ createGPUReducer,
508
+ outputSpec,
509
+ uniform,
510
+ // Shaders
511
+ buildShader,
512
+ BUILT_IN_OPS,
513
+ BUILT_IN_OP_NAMES,
514
+ SPECIAL_OPS,
515
+ // Hooks
516
+ useThread,
517
+ usePool,
518
+ useThreadMetrics,
519
+ usePoolMetrics,
520
+ useThreadWorker,
521
+ useThreadEvent,
522
+ // GPU Hooks
523
+ useGPU,
524
+ useGPURun,
525
+ useGPUMetrics,
526
+ useGPUStatus,
527
+ // Adapters
528
+ createZustandBinder,
529
+ createSignalBinder,
530
+ createStoreBinder,
531
+ createPoolBinder,
532
+ // GPU Adapters
533
+ createGPUBinder,
534
+ createGPUSignalBinder,
535
+ createGPUStoreBinder,
536
+ // Config
537
+ defineConfig,
538
+ getConfig,
539
+ setConfig,
540
+ DEFAULTS,
541
+ FRAMEWORKS,
542
+ STATE_MANAGERS,
543
+ mergeWithDefaults,
544
+ validateConfig,
545
+ resolveHooks,
546
+ getAdapter,
547
+ // Environment
548
+ env,
549
+ createPlatformWorker,
550
+ terminateWorker,
551
+ supportsWorkers,
552
+ workerInfo,
553
+ gpuEnv,
554
+ isGPUAvailable,
555
+ requestGPUAdapter,
556
+ requestGPUDevice,
557
+ };