@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/browser.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;
@@ -1417,12 +1443,20 @@ class WorkerServerBase {
1417
1443
  const uniqueTransferables = [...new Set(transferables)];
1418
1444
  postMessage({ id, type: "complete", data: result }, uniqueTransferables);
1419
1445
  };
1420
- postError = (id, errorMessage) => {
1446
+ postError = (id, error) => {
1421
1447
  if (this.completedRequests.has(id)) {
1422
1448
  return;
1423
1449
  }
1424
1450
  this.completedRequests.add(id);
1425
- postMessage({ id, type: "error", data: errorMessage });
1451
+ let data;
1452
+ if (typeof error === "string") {
1453
+ data = { message: error, name: "Error" };
1454
+ } else if (error instanceof Error) {
1455
+ data = { message: error.message, name: error.name };
1456
+ } else {
1457
+ data = { message: String(error), name: "Error" };
1458
+ }
1459
+ postMessage({ id, type: "error", data });
1426
1460
  };
1427
1461
  postStreamChunk = (id, event) => {
1428
1462
  if (this.completedRequests.has(id)) {
@@ -1468,6 +1502,7 @@ class WorkerServerBase {
1468
1502
  controller?.abort();
1469
1503
  this.requestControllers.delete(id);
1470
1504
  this.postError(id, "Operation aborted");
1505
+ this.scheduleCompletedRequestCleanup(id);
1471
1506
  }
1472
1507
  }
1473
1508
  async handleReactiveCall(id, functionName, [input, output, model]) {
@@ -1480,7 +1515,7 @@ class WorkerServerBase {
1480
1515
  const result = await fn(input, output, model);
1481
1516
  this.postResult(id, result);
1482
1517
  } catch (error) {
1483
- this.postError(id, error.message);
1518
+ this.postError(id, error);
1484
1519
  }
1485
1520
  }
1486
1521
  async handleCall(id, functionName, [input, model]) {
@@ -1500,12 +1535,10 @@ class WorkerServerBase {
1500
1535
  const result = await fn(input, model, postProgress, abortController.signal);
1501
1536
  this.postResult(id, result);
1502
1537
  } catch (error) {
1503
- this.postError(id, error.message);
1538
+ this.postError(id, error);
1504
1539
  } finally {
1505
1540
  this.requestControllers.delete(id);
1506
- setTimeout(() => {
1507
- this.completedRequests.delete(id);
1508
- }, 1000);
1541
+ this.scheduleCompletedRequestCleanup(id);
1509
1542
  }
1510
1543
  }
1511
1544
  async handleStreamCall(id, functionName, [input, model]) {
@@ -1522,12 +1555,10 @@ class WorkerServerBase {
1522
1555
  }
1523
1556
  this.postResult(id, undefined);
1524
1557
  } catch (error) {
1525
- this.postError(id, error.message);
1558
+ this.postError(id, error);
1526
1559
  } finally {
1527
1560
  this.requestControllers.delete(id);
1528
- setTimeout(() => {
1529
- this.completedRequests.delete(id);
1530
- }, 1000);
1561
+ this.scheduleCompletedRequestCleanup(id);
1531
1562
  }
1532
1563
  } else if (functionName in this.functions) {
1533
1564
  try {
@@ -1539,17 +1570,29 @@ class WorkerServerBase {
1539
1570
  this.postStreamChunk(id, { type: "finish", data: result });
1540
1571
  this.postResult(id, undefined);
1541
1572
  } catch (error) {
1542
- this.postError(id, error.message);
1573
+ this.postError(id, error);
1543
1574
  } finally {
1544
1575
  this.requestControllers.delete(id);
1545
- setTimeout(() => {
1546
- this.completedRequests.delete(id);
1547
- }, 1000);
1576
+ this.scheduleCompletedRequestCleanup(id);
1548
1577
  }
1549
1578
  } else {
1550
1579
  this.postError(id, `Function ${functionName} not found`);
1551
1580
  }
1552
1581
  }
1582
+ scheduleCompletedRequestCleanup(id) {
1583
+ setTimeout(() => {
1584
+ this.completedRequests.delete(id);
1585
+ }, 5000);
1586
+ if (this.completedRequests.size > 1e4) {
1587
+ const iter = this.completedRequests.values();
1588
+ for (let i = 0;i < 5000; i++) {
1589
+ const entry = iter.next();
1590
+ if (entry.done)
1591
+ break;
1592
+ this.completedRequests.delete(entry.value);
1593
+ }
1594
+ }
1595
+ }
1553
1596
  }
1554
1597
 
1555
1598
  // src/worker/Worker.browser.ts
@@ -1622,4 +1665,4 @@ export {
1622
1665
  BaseError
1623
1666
  };
1624
1667
 
1625
- //# debugId=C665251EA27E791364756E2164756E21
1668
+ //# debugId=65F2AF5A900EB08C64756E2164756E21