@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/dist/index.cjs CHANGED
@@ -98,16 +98,15 @@ function getConfig() {
98
98
 
99
99
  // src/runtime.ts
100
100
  function detectRuntime() {
101
- if (typeof globalThis.Bun !== "undefined") return "bun";
102
- if (typeof globalThis.Deno !== "undefined") return "deno";
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 (typeof globalThis.Worker !== "undefined") return "full-threads";
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
- this.worker = new Worker(getBootstrapFile());
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(data) {
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 ?? false, msg.channels);
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
- this.emit("message", msg);
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", (msg) => {
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
- for (const [taskId, w] of this.exclusiveWorkers) {
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
- for (const [taskId, w] of this.exclusiveWorkers) {
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
- const impl = ch;
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 = void 0;
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) => {