@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/dist/index.cjs
CHANGED
|
@@ -98,16 +98,15 @@ function getConfig() {
|
|
|
98
98
|
|
|
99
99
|
// src/runtime.ts
|
|
100
100
|
function detectRuntime() {
|
|
101
|
-
if (
|
|
102
|
-
if (
|
|
103
|
-
if (typeof globalThis.process !== "undefined" && globalThis.process.versions?.node)
|
|
104
|
-
return "node";
|
|
101
|
+
if ("Bun" in globalThis) return "bun";
|
|
102
|
+
if ("Deno" in globalThis) return "deno";
|
|
103
|
+
if (typeof globalThis.process !== "undefined" && globalThis.process.versions?.node) return "node";
|
|
105
104
|
return "browser";
|
|
106
105
|
}
|
|
107
106
|
function detectCapability() {
|
|
108
107
|
const runtime = detectRuntime();
|
|
109
108
|
if (runtime === "node" || runtime === "bun") return "full-threads";
|
|
110
|
-
if (
|
|
109
|
+
if ("Worker" in globalThis) return "full-threads";
|
|
111
110
|
return "single-thread";
|
|
112
111
|
}
|
|
113
112
|
|
|
@@ -374,7 +373,11 @@ var BunManagedWorker = class {
|
|
|
374
373
|
id;
|
|
375
374
|
constructor() {
|
|
376
375
|
this.id = ++workerIdCounter;
|
|
377
|
-
|
|
376
|
+
const WorkerConstructor = globalThis.Worker;
|
|
377
|
+
if (!WorkerConstructor) {
|
|
378
|
+
throw new Error("Bun Worker constructor is not available in this runtime");
|
|
379
|
+
}
|
|
380
|
+
this.worker = new WorkerConstructor(getBootstrapFile());
|
|
378
381
|
}
|
|
379
382
|
postMessage(data) {
|
|
380
383
|
this.worker.postMessage(data);
|
|
@@ -386,27 +389,28 @@ var BunManagedWorker = class {
|
|
|
386
389
|
on(event, handler) {
|
|
387
390
|
if (event === "message") {
|
|
388
391
|
this.worker.addEventListener("message", (e) => {
|
|
392
|
+
;
|
|
389
393
|
handler(e.data);
|
|
390
394
|
});
|
|
391
395
|
} else if (event === "error") {
|
|
392
396
|
this.worker.addEventListener("error", (e) => {
|
|
397
|
+
;
|
|
393
398
|
handler(e.error ?? new Error(e.message));
|
|
394
399
|
});
|
|
395
400
|
} else if (event === "exit") {
|
|
396
401
|
this.worker.addEventListener("close", (e) => {
|
|
402
|
+
;
|
|
397
403
|
handler(e.code ?? 0);
|
|
398
404
|
});
|
|
399
405
|
}
|
|
400
406
|
}
|
|
401
407
|
unref() {
|
|
402
408
|
if ("unref" in this.worker && typeof this.worker.unref === "function") {
|
|
403
|
-
;
|
|
404
409
|
this.worker.unref();
|
|
405
410
|
}
|
|
406
411
|
}
|
|
407
412
|
ref() {
|
|
408
413
|
if ("ref" in this.worker && typeof this.worker.ref === "function") {
|
|
409
|
-
;
|
|
410
414
|
this.worker.ref();
|
|
411
415
|
}
|
|
412
416
|
}
|
|
@@ -505,6 +509,9 @@ function chan(capacity = 0) {
|
|
|
505
509
|
function getChannelById(id) {
|
|
506
510
|
return channelRegistry.get(id);
|
|
507
511
|
}
|
|
512
|
+
function getChannelId(channel) {
|
|
513
|
+
return channel._id;
|
|
514
|
+
}
|
|
508
515
|
|
|
509
516
|
// src/adapters/inline.ts
|
|
510
517
|
var inlineIdCounter = 0;
|
|
@@ -521,15 +528,14 @@ var InlineManagedWorker = class {
|
|
|
521
528
|
this.emit("message", { type: "ready" });
|
|
522
529
|
});
|
|
523
530
|
}
|
|
524
|
-
postMessage(
|
|
531
|
+
postMessage(msg) {
|
|
525
532
|
if (this.terminated) return;
|
|
526
|
-
const msg = data;
|
|
527
533
|
if (msg.type === "execute") {
|
|
528
|
-
this.executeTask(msg.taskId, msg.fnStr, msg.concurrent
|
|
534
|
+
this.executeTask(msg.taskId, msg.fnStr, msg.concurrent, msg.channels);
|
|
529
535
|
} else if (msg.type === "cancel") {
|
|
530
536
|
this.cancelledTasks.add(msg.taskId);
|
|
531
537
|
} else if (msg.type === "channel-result") {
|
|
532
|
-
|
|
538
|
+
return;
|
|
533
539
|
} else if (msg.type === "shutdown") {
|
|
534
540
|
this.terminated = true;
|
|
535
541
|
this.emit("exit", 0);
|
|
@@ -559,7 +565,6 @@ var InlineManagedWorker = class {
|
|
|
559
565
|
}
|
|
560
566
|
}
|
|
561
567
|
buildChannelProxies(channels) {
|
|
562
|
-
const self = this;
|
|
563
568
|
const proxies = {};
|
|
564
569
|
for (const [name, channelId] of Object.entries(channels)) {
|
|
565
570
|
proxies[name] = {
|
|
@@ -581,13 +586,7 @@ var InlineManagedWorker = class {
|
|
|
581
586
|
[Symbol.asyncIterator]() {
|
|
582
587
|
const ch = getChannelById(channelId);
|
|
583
588
|
if (!ch) throw new Error(`Channel ${channelId} not found`);
|
|
584
|
-
return
|
|
585
|
-
async next() {
|
|
586
|
-
const value = await ch.recv();
|
|
587
|
-
if (value === null) return { done: true, value: void 0 };
|
|
588
|
-
return { done: false, value };
|
|
589
|
-
}
|
|
590
|
-
};
|
|
589
|
+
return ch[Symbol.asyncIterator]();
|
|
591
590
|
}
|
|
592
591
|
};
|
|
593
592
|
}
|
|
@@ -935,6 +934,15 @@ var WorkerPool = class {
|
|
|
935
934
|
task2.reject(reason);
|
|
936
935
|
}
|
|
937
936
|
}
|
|
937
|
+
rejectExclusiveTaskForWorker(worker, reason) {
|
|
938
|
+
for (const [taskId, assignedWorker] of this.exclusiveWorkers) {
|
|
939
|
+
if (assignedWorker === worker) {
|
|
940
|
+
this.exclusiveWorkers.delete(taskId);
|
|
941
|
+
this.rejectTask(taskId, reason);
|
|
942
|
+
break;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
938
946
|
// --- Cancellation ---
|
|
939
947
|
cancelTask(taskId) {
|
|
940
948
|
const removed = this.removeFromQueue(taskId);
|
|
@@ -983,6 +991,10 @@ var WorkerPool = class {
|
|
|
983
991
|
}
|
|
984
992
|
this.concurrentQueues[priority] = [];
|
|
985
993
|
}
|
|
994
|
+
for (const [taskId] of this.exclusiveWorkers) {
|
|
995
|
+
this.taskMap.delete(taskId);
|
|
996
|
+
}
|
|
997
|
+
this.exclusiveWorkers.clear();
|
|
986
998
|
for (const [, taskSet] of this.sharedWorkers) {
|
|
987
999
|
for (const taskId of taskSet) {
|
|
988
1000
|
this.taskMap.delete(taskId);
|
|
@@ -1040,8 +1052,7 @@ var WorkerPool = class {
|
|
|
1040
1052
|
this.makeIdle(worker);
|
|
1041
1053
|
}
|
|
1042
1054
|
};
|
|
1043
|
-
worker.on("message", (
|
|
1044
|
-
const response = msg;
|
|
1055
|
+
worker.on("message", (response) => {
|
|
1045
1056
|
if (response.type === "ready") {
|
|
1046
1057
|
onReady();
|
|
1047
1058
|
return;
|
|
@@ -1049,12 +1060,7 @@ var WorkerPool = class {
|
|
|
1049
1060
|
this.handleWorkerMessage(worker, response);
|
|
1050
1061
|
});
|
|
1051
1062
|
worker.on("error", (err) => {
|
|
1052
|
-
|
|
1053
|
-
if (w === worker) {
|
|
1054
|
-
this.exclusiveWorkers.delete(taskId);
|
|
1055
|
-
break;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1063
|
+
this.rejectExclusiveTaskForWorker(worker, err);
|
|
1058
1064
|
const taskSet = this.sharedWorkers.get(worker);
|
|
1059
1065
|
if (taskSet) {
|
|
1060
1066
|
for (const taskId of taskSet) {
|
|
@@ -1074,12 +1080,7 @@ var WorkerPool = class {
|
|
|
1074
1080
|
if (idleIdx !== -1) {
|
|
1075
1081
|
this.idleWorkers.splice(idleIdx, 1);
|
|
1076
1082
|
}
|
|
1077
|
-
|
|
1078
|
-
if (w === worker) {
|
|
1079
|
-
this.exclusiveWorkers.delete(taskId);
|
|
1080
|
-
break;
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
+
this.rejectExclusiveTaskForWorker(worker, new Error("Worker exited unexpectedly"));
|
|
1083
1084
|
const taskSet = this.sharedWorkers.get(worker);
|
|
1084
1085
|
if (taskSet) {
|
|
1085
1086
|
for (const taskId of taskSet) {
|
|
@@ -1173,11 +1174,7 @@ function spawn(fn, opts) {
|
|
|
1173
1174
|
if (opts?.channels) {
|
|
1174
1175
|
channelMap = {};
|
|
1175
1176
|
for (const [name, ch] of Object.entries(opts.channels)) {
|
|
1176
|
-
|
|
1177
|
-
if (!impl._id) {
|
|
1178
|
-
throw new Error(`Channel "${name}" is not a valid puru channel`);
|
|
1179
|
-
}
|
|
1180
|
-
channelMap[name] = impl._id;
|
|
1177
|
+
channelMap[name] = getChannelId(ch);
|
|
1181
1178
|
}
|
|
1182
1179
|
}
|
|
1183
1180
|
const task2 = {
|
|
@@ -1266,7 +1263,7 @@ var WaitGroup = class {
|
|
|
1266
1263
|
var ErrGroup = class {
|
|
1267
1264
|
tasks = [];
|
|
1268
1265
|
controller = new AbortController();
|
|
1269
|
-
firstError =
|
|
1266
|
+
firstError = null;
|
|
1270
1267
|
hasError = false;
|
|
1271
1268
|
get signal() {
|
|
1272
1269
|
return this.controller.signal;
|
|
@@ -1287,7 +1284,7 @@ var ErrGroup = class {
|
|
|
1287
1284
|
}
|
|
1288
1285
|
async wait() {
|
|
1289
1286
|
const settled = await Promise.allSettled(this.tasks.map((t) => t.result));
|
|
1290
|
-
if (this.hasError) {
|
|
1287
|
+
if (this.hasError && this.firstError) {
|
|
1291
1288
|
throw this.firstError;
|
|
1292
1289
|
}
|
|
1293
1290
|
return settled.map((r) => {
|