@workglow/util 0.0.126 → 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/dist/node.js CHANGED
@@ -215,10 +215,19 @@ class EventEmitter {
215
215
  emit(event, ...args) {
216
216
  const listeners = this.listeners[event];
217
217
  if (listeners) {
218
- listeners.forEach(({ listener }) => {
219
- listener(...args);
220
- });
218
+ const snapshot = [...listeners];
219
+ const errors = [];
220
+ for (const { listener } of snapshot) {
221
+ try {
222
+ listener(...args);
223
+ } catch (e) {
224
+ errors.push(e);
225
+ }
226
+ }
221
227
  this.listeners[event] = listeners.filter((l) => !l.once);
228
+ if (errors.length > 0) {
229
+ throw errors[0];
230
+ }
222
231
  }
223
232
  }
224
233
  subscribe(event, listener) {
@@ -766,10 +775,23 @@ class WorkerManager {
766
775
  worker.addEventListener("messageerror", (event) => {
767
776
  console.error("Worker message error:", event);
768
777
  });
769
- const readyPromise = new Promise((resolve) => {
778
+ const readyPromise = new Promise((resolve, reject) => {
779
+ const timeout = setTimeout(() => {
780
+ worker.removeEventListener("message", handleReady);
781
+ worker.removeEventListener("error", handleError);
782
+ reject(new Error(`Worker "${name}" did not become ready within 10s`));
783
+ }, 1e4);
784
+ const handleError = (event) => {
785
+ clearTimeout(timeout);
786
+ worker.removeEventListener("message", handleReady);
787
+ worker.removeEventListener("error", handleError);
788
+ reject(new Error(`Worker "${name}" initialization error: ${event.message ?? "unknown error"}`));
789
+ };
770
790
  const handleReady = (event) => {
771
791
  if (event.data?.type === "ready") {
792
+ clearTimeout(timeout);
772
793
  worker.removeEventListener("message", handleReady);
794
+ worker.removeEventListener("error", handleError);
773
795
  this.workerFunctions.set(name, new Set(event.data.functions ?? []));
774
796
  this.workerStreamFunctions.set(name, new Set(event.data.streamFunctions ?? []));
775
797
  this.workerReactiveFunctions.set(name, new Set(event.data.reactiveFunctions ?? []));
@@ -777,6 +799,7 @@ class WorkerManager {
777
799
  }
778
800
  };
779
801
  worker.addEventListener("message", handleReady);
802
+ worker.addEventListener("error", handleError);
780
803
  });
781
804
  this.readyWorkers.set(name, readyPromise);
782
805
  }
@@ -835,7 +858,10 @@ class WorkerManager {
835
858
  } else if (type === "error") {
836
859
  cleanup();
837
860
  getLogger().debug(`Worker ${workerName} function ${functionName} error.`, { data });
838
- reject(new Error(data));
861
+ const err = typeof data === "object" && data !== null ? Object.assign(new Error(data.message ?? String(data)), {
862
+ name: data.name ?? "Error"
863
+ }) : new Error(String(data));
864
+ reject(err);
839
865
  }
840
866
  };
841
867
  const handleAbort = () => {
@@ -1162,7 +1188,7 @@ var SALT_LENGTH = 16;
1162
1188
  async function deriveKey(passphrase, salt) {
1163
1189
  const enc = new TextEncoder;
1164
1190
  const keyMaterial = await crypto.subtle.importKey("raw", enc.encode(passphrase), "PBKDF2", false, ["deriveKey"]);
1165
- return crypto.subtle.deriveKey({ name: "PBKDF2", salt, iterations: 1e5, hash: "SHA-256" }, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
1191
+ return crypto.subtle.deriveKey({ name: "PBKDF2", salt, iterations: 600000, hash: "SHA-256" }, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
1166
1192
  }
1167
1193
  async function encrypt(plaintext, passphrase, keyCache) {
1168
1194
  const enc = new TextEncoder;
@@ -1422,12 +1448,20 @@ class WorkerServerBase {
1422
1448
  const uniqueTransferables = [...new Set(transferables)];
1423
1449
  postMessage({ id, type: "complete", data: result }, uniqueTransferables);
1424
1450
  };
1425
- postError = (id, errorMessage) => {
1451
+ postError = (id, error) => {
1426
1452
  if (this.completedRequests.has(id)) {
1427
1453
  return;
1428
1454
  }
1429
1455
  this.completedRequests.add(id);
1430
- postMessage({ id, type: "error", data: errorMessage });
1456
+ let data;
1457
+ if (typeof error === "string") {
1458
+ data = { message: error, name: "Error" };
1459
+ } else if (error instanceof Error) {
1460
+ data = { message: error.message, name: error.name };
1461
+ } else {
1462
+ data = { message: String(error), name: "Error" };
1463
+ }
1464
+ postMessage({ id, type: "error", data });
1431
1465
  };
1432
1466
  postStreamChunk = (id, event) => {
1433
1467
  if (this.completedRequests.has(id)) {
@@ -1473,6 +1507,7 @@ class WorkerServerBase {
1473
1507
  controller?.abort();
1474
1508
  this.requestControllers.delete(id);
1475
1509
  this.postError(id, "Operation aborted");
1510
+ this.scheduleCompletedRequestCleanup(id);
1476
1511
  }
1477
1512
  }
1478
1513
  async handleReactiveCall(id, functionName, [input, output, model]) {
@@ -1485,7 +1520,7 @@ class WorkerServerBase {
1485
1520
  const result = await fn(input, output, model);
1486
1521
  this.postResult(id, result);
1487
1522
  } catch (error) {
1488
- this.postError(id, error.message);
1523
+ this.postError(id, error);
1489
1524
  }
1490
1525
  }
1491
1526
  async handleCall(id, functionName, [input, model]) {
@@ -1505,12 +1540,10 @@ class WorkerServerBase {
1505
1540
  const result = await fn(input, model, postProgress, abortController.signal);
1506
1541
  this.postResult(id, result);
1507
1542
  } catch (error) {
1508
- this.postError(id, error.message);
1543
+ this.postError(id, error);
1509
1544
  } finally {
1510
1545
  this.requestControllers.delete(id);
1511
- setTimeout(() => {
1512
- this.completedRequests.delete(id);
1513
- }, 1000);
1546
+ this.scheduleCompletedRequestCleanup(id);
1514
1547
  }
1515
1548
  }
1516
1549
  async handleStreamCall(id, functionName, [input, model]) {
@@ -1527,12 +1560,10 @@ class WorkerServerBase {
1527
1560
  }
1528
1561
  this.postResult(id, undefined);
1529
1562
  } catch (error) {
1530
- this.postError(id, error.message);
1563
+ this.postError(id, error);
1531
1564
  } finally {
1532
1565
  this.requestControllers.delete(id);
1533
- setTimeout(() => {
1534
- this.completedRequests.delete(id);
1535
- }, 1000);
1566
+ this.scheduleCompletedRequestCleanup(id);
1536
1567
  }
1537
1568
  } else if (functionName in this.functions) {
1538
1569
  try {
@@ -1544,17 +1575,29 @@ class WorkerServerBase {
1544
1575
  this.postStreamChunk(id, { type: "finish", data: result });
1545
1576
  this.postResult(id, undefined);
1546
1577
  } catch (error) {
1547
- this.postError(id, error.message);
1578
+ this.postError(id, error);
1548
1579
  } finally {
1549
1580
  this.requestControllers.delete(id);
1550
- setTimeout(() => {
1551
- this.completedRequests.delete(id);
1552
- }, 1000);
1581
+ this.scheduleCompletedRequestCleanup(id);
1553
1582
  }
1554
1583
  } else {
1555
1584
  this.postError(id, `Function ${functionName} not found`);
1556
1585
  }
1557
1586
  }
1587
+ scheduleCompletedRequestCleanup(id) {
1588
+ setTimeout(() => {
1589
+ this.completedRequests.delete(id);
1590
+ }, 5000);
1591
+ if (this.completedRequests.size > 1e4) {
1592
+ const iter = this.completedRequests.values();
1593
+ for (let i = 0;i < 5000; i++) {
1594
+ const entry = iter.next();
1595
+ if (entry.done)
1596
+ break;
1597
+ this.completedRequests.delete(entry.value);
1598
+ }
1599
+ }
1600
+ }
1558
1601
  }
1559
1602
 
1560
1603
  // src/worker/Worker.node.ts
@@ -1644,4 +1687,4 @@ export {
1644
1687
  BaseError
1645
1688
  };
1646
1689
 
1647
- //# debugId=542A5A44460369BC64756E2164756E21
1690
+ //# debugId=95A7F4B72D9E347164756E2164756E21