@bian-womp/spark-workbench 0.3.79 → 0.3.80

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.
@@ -14,25 +14,19 @@ export declare class RemoteGraphRunner extends AbstractGraphRunner {
14
14
  private valueCache;
15
15
  private listenersBound;
16
16
  private registryFetched;
17
- private registryFetchPromise?;
18
- private readonly MAX_REGISTRY_FETCH_ATTEMPTS;
19
- private readonly INITIAL_RETRY_DELAY_MS;
20
- private readonly REGISTRY_FETCH_TIMEOUT_MS;
17
+ private registryBootstrapPromise?;
18
+ private registryBootstrapResolve?;
19
+ private registryBootstrapReject?;
20
+ private readonly REGISTRY_BOOTSTRAP_TIMEOUT_MS;
21
21
  /**
22
22
  * Generate cache key that includes io type to prevent collisions
23
23
  * between input and output handles with the same name
24
24
  */
25
25
  private getCacheKey;
26
- /**
27
- * Fetch full registry description from remote and register it locally.
28
- * Simplified with straightforward retry loop.
29
- * Ensures only one fetch happens at a time, even with concurrent calls.
30
- */
31
- private fetchRegistry;
32
- /**
33
- * Internal method that performs the actual registry fetch.
34
- */
35
- private _doFetchRegistry;
26
+ private applyRegistryDescriptor;
27
+ private isRecord;
28
+ private isRegistryDescriptorEvent;
29
+ private waitForRegistryBootstrap;
36
30
  /**
37
31
  * Build RemoteRuntimeClient config from RemoteExecutionBackend config.
38
32
  */
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/RemoteGraphRunner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RemoteGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/RemoteGraphRunner.ts"],"names":[],"mappings":"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"}
package/lib/esm/index.js CHANGED
@@ -1501,139 +1501,101 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1501
1501
  getCacheKey(nodeId, handle, io) {
1502
1502
  return `${nodeId}.${io}.${handle}`;
1503
1503
  }
1504
- /**
1505
- * Fetch full registry description from remote and register it locally.
1506
- * Simplified with straightforward retry loop.
1507
- * Ensures only one fetch happens at a time, even with concurrent calls.
1508
- */
1509
- async fetchRegistry(client) {
1510
- if (this.registryFetched) {
1511
- return;
1512
- }
1513
- // If already fetching, wait for that fetch to complete
1514
- if (this.registryFetchPromise) {
1515
- return this.registryFetchPromise;
1516
- }
1517
- // Create promise wrapper and assign atomically to prevent race conditions
1518
- // This ensures concurrent calls will see the promise and wait for it
1519
- let promise;
1520
- this.registryFetchPromise = promise = (async () => {
1521
- try {
1522
- await this._doFetchRegistry(client);
1504
+ applyRegistryDescriptor(desc) {
1505
+ for (const t of desc.types) {
1506
+ if (t.options) {
1507
+ this.registry.registerEnum({
1508
+ id: t.id,
1509
+ options: t.options,
1510
+ bakeTarget: t.bakeTarget,
1511
+ });
1523
1512
  }
1524
- finally {
1525
- // Clear the promise after completion (success or failure)
1526
- this.registryFetchPromise = undefined;
1513
+ else if (!this.registry.types.has(t.id)) {
1514
+ this.registry.registerType({
1515
+ id: t.id,
1516
+ displayName: t.displayName,
1517
+ validate: (_v) => true,
1518
+ bakeTarget: t.bakeTarget,
1519
+ });
1527
1520
  }
1528
- })();
1529
- return promise;
1530
- }
1531
- /**
1532
- * Internal method that performs the actual registry fetch.
1533
- */
1534
- async _doFetchRegistry(client) {
1535
- let lastError;
1536
- for (let attempt = 1; attempt <= this.MAX_REGISTRY_FETCH_ATTEMPTS; attempt++) {
1537
- try {
1538
- // Add timeout to registry fetch - if it exceeds 3s, retry
1539
- let timeoutId;
1540
- const timeoutPromise = new Promise((_, reject) => {
1541
- timeoutId = setTimeout(() => reject(new Error("Registry fetch timeout (3s exceeded)")), this.REGISTRY_FETCH_TIMEOUT_MS);
1521
+ }
1522
+ for (const c of desc.categories || []) {
1523
+ if (!this.registry.categories.has(c.id)) {
1524
+ const category = {
1525
+ id: c.id,
1526
+ displayName: c.displayName,
1527
+ createRuntime: () => ({
1528
+ async onInputsChanged() { },
1529
+ }),
1530
+ policy: { asyncConcurrency: "switch" },
1531
+ };
1532
+ this.registry.categories.register(category);
1533
+ }
1534
+ }
1535
+ for (const c of desc.coercions) {
1536
+ if (c.async) {
1537
+ this.registry.registerAsyncCoercion(c.from, c.to, async (v) => v, {
1538
+ nonTransitive: c.nonTransitive,
1542
1539
  });
1543
- const fetchPromise = client.api.describeRegistry().finally(() => {
1544
- // Clear timeout if request completes first
1545
- if (timeoutId) {
1546
- clearTimeout(timeoutId);
1547
- timeoutId = undefined;
1548
- }
1540
+ }
1541
+ else {
1542
+ this.registry.registerCoercion(c.from, c.to, (v) => v, {
1543
+ nonTransitive: c.nonTransitive,
1549
1544
  });
1550
- const desc = await Promise.race([fetchPromise, timeoutPromise]);
1551
- // Register types
1552
- for (const t of desc.types) {
1553
- if (t.options) {
1554
- this.registry.registerEnum({
1555
- id: t.id,
1556
- options: t.options,
1557
- bakeTarget: t.bakeTarget,
1558
- });
1559
- }
1560
- else {
1561
- if (!this.registry.types.has(t.id)) {
1562
- this.registry.registerType({
1563
- id: t.id,
1564
- displayName: t.displayName,
1565
- validate: (_v) => true,
1566
- bakeTarget: t.bakeTarget,
1567
- });
1568
- }
1569
- }
1570
- }
1571
- // Register categories
1572
- for (const c of desc.categories || []) {
1573
- if (!this.registry.categories.has(c.id)) {
1574
- // Create placeholder category descriptor
1575
- const category = {
1576
- id: c.id,
1577
- displayName: c.displayName,
1578
- createRuntime: () => ({
1579
- async onInputsChanged() { },
1580
- }),
1581
- policy: { asyncConcurrency: "switch" },
1582
- };
1583
- this.registry.categories.register(category);
1584
- }
1585
- }
1586
- // Register coercions
1587
- for (const c of desc.coercions) {
1588
- if (c.async) {
1589
- this.registry.registerAsyncCoercion(c.from, c.to, async (v) => v, {
1590
- nonTransitive: c.nonTransitive,
1591
- });
1592
- }
1593
- else {
1594
- this.registry.registerCoercion(c.from, c.to, (v) => v, {
1595
- nonTransitive: c.nonTransitive,
1596
- });
1597
- }
1598
- }
1599
- // Register nodes
1600
- for (const n of desc.nodes) {
1601
- if (!this.registry.nodes.has(n.id)) {
1602
- this.registry.registerNode({
1603
- id: n.id,
1604
- categoryId: n.categoryId,
1605
- displayName: n.displayName,
1606
- inputs: n.inputs || {},
1607
- outputs: n.outputs || {},
1608
- policy: n.policy || {},
1609
- impl: () => { },
1610
- });
1611
- }
1612
- }
1613
- this.registryFetched = true;
1614
- this.emit("registry", this.registry);
1615
- return;
1616
1545
  }
1617
- catch (err) {
1618
- lastError = err instanceof Error ? err : new Error(String(err));
1619
- if (attempt < this.MAX_REGISTRY_FETCH_ATTEMPTS) {
1620
- const delayMs = this.INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt - 1);
1621
- console.warn(`Failed to fetch registry (attempt ${attempt}/${this.MAX_REGISTRY_FETCH_ATTEMPTS}), retrying in ${delayMs}ms...`, lastError);
1622
- // Wait before retrying
1623
- await new Promise((resolve) => setTimeout(resolve, delayMs));
1624
- }
1546
+ }
1547
+ for (const n of desc.nodes) {
1548
+ if (!this.registry.nodes.has(n.id)) {
1549
+ this.registry.registerNode({
1550
+ id: n.id,
1551
+ categoryId: n.categoryId,
1552
+ displayName: n.displayName,
1553
+ inputs: n.inputs || {},
1554
+ outputs: n.outputs || {},
1555
+ policy: n.policy || {},
1556
+ impl: () => { },
1557
+ });
1625
1558
  }
1626
1559
  }
1627
- // Max attempts reached, emit final error and throw
1628
- console.error(`Failed to fetch registry after ${this.MAX_REGISTRY_FETCH_ATTEMPTS} attempts:`, lastError);
1629
- this.emit("error", {
1630
- kind: "registry",
1631
- message: `Failed to fetch registry after ${this.MAX_REGISTRY_FETCH_ATTEMPTS} attempts. Please check your connection and try refreshing.`,
1632
- err: lastError,
1633
- attempt: this.MAX_REGISTRY_FETCH_ATTEMPTS,
1634
- maxAttempts: this.MAX_REGISTRY_FETCH_ATTEMPTS,
1560
+ this.registryFetched = true;
1561
+ if (this.registryBootstrapResolve) {
1562
+ this.registryBootstrapResolve();
1563
+ this.registryBootstrapResolve = undefined;
1564
+ this.registryBootstrapReject = undefined;
1565
+ }
1566
+ this.emit("registry", this.registry);
1567
+ }
1568
+ isRecord(value) {
1569
+ return typeof value === "object" && value !== null;
1570
+ }
1571
+ isRegistryDescriptorEvent(message) {
1572
+ if (!this.isRecord(message))
1573
+ return false;
1574
+ if (message.type !== "registry-descriptor")
1575
+ return false;
1576
+ if (!this.isRecord(message.payload))
1577
+ return false;
1578
+ return "registry" in message.payload;
1579
+ }
1580
+ waitForRegistryBootstrap() {
1581
+ if (this.registryFetched)
1582
+ return Promise.resolve();
1583
+ if (this.registryBootstrapPromise)
1584
+ return this.registryBootstrapPromise;
1585
+ this.registryBootstrapPromise = new Promise((resolve, reject) => {
1586
+ this.registryBootstrapResolve = resolve;
1587
+ this.registryBootstrapReject = reject;
1588
+ setTimeout(() => {
1589
+ if (!this.registryFetched && this.registryBootstrapReject) {
1590
+ this.registryBootstrapReject(new Error(`Registry bootstrap timeout (${this.REGISTRY_BOOTSTRAP_TIMEOUT_MS}ms exceeded)`));
1591
+ this.registryBootstrapResolve = undefined;
1592
+ this.registryBootstrapReject = undefined;
1593
+ }
1594
+ }, this.REGISTRY_BOOTSTRAP_TIMEOUT_MS);
1595
+ }).finally(() => {
1596
+ this.registryBootstrapPromise = undefined;
1635
1597
  });
1636
- throw lastError;
1598
+ return this.registryBootstrapPromise;
1637
1599
  }
1638
1600
  /**
1639
1601
  * Build RemoteRuntimeClient config from RemoteExecutionBackend config.
@@ -1695,13 +1657,27 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1695
1657
  const clientConfig = this.buildClientConfig(backend);
1696
1658
  // Wrap custom event handler to intercept viewport events and emit viewport event
1697
1659
  const wrappedOnCustomEvent = (event) => {
1698
- const msg = event?.message;
1699
- if (msg && typeof msg === "object" && "type" in msg && msg.type === "viewport") {
1700
- const viewport = msg.payload?.viewport;
1660
+ const msg = event.message;
1661
+ if (this.isRecord(msg) && msg.type === "viewport" && this.isRecord(msg.payload)) {
1662
+ const viewport = msg.payload.viewport;
1701
1663
  if (isValidViewport(viewport)) {
1702
1664
  this.emit("viewport", { viewport });
1703
1665
  }
1704
1666
  }
1667
+ else if (this.isRecord(msg) && msg.type === "flow-opened" && this.isRecord(msg.payload)) {
1668
+ const sessionId = msg.payload.sessionId;
1669
+ const resumed = msg.payload.resumed;
1670
+ if (typeof sessionId === "number") {
1671
+ console.info(`[RemoteGraphRunner] Flow opened (runner=${this.runnerId}, sessionId=${sessionId}, resumed=${Boolean(resumed)})`);
1672
+ }
1673
+ }
1674
+ else if (this.isRecord(msg) && msg.type === "flow-closed" && this.isRecord(msg.payload)) {
1675
+ const reason = msg.payload.reason;
1676
+ console.warn(`[RemoteGraphRunner] Flow closed (runner=${this.runnerId}, reason=${typeof reason === "string" ? reason : "unknown"})`);
1677
+ }
1678
+ else if (this.isRegistryDescriptorEvent(msg)) {
1679
+ this.applyRegistryDescriptor(msg.payload.registry);
1680
+ }
1705
1681
  // Call original handler if provided
1706
1682
  if (backend.onCustomEvent) {
1707
1683
  backend.onCustomEvent(event);
@@ -1719,12 +1695,11 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1719
1695
  this.client = client;
1720
1696
  this.valueCache.clear();
1721
1697
  this.listenersBound = false;
1722
- // Fetch registry before returning (wait for it to complete)
1723
- // Only fetch if not already fetched (handles concurrent calls)
1698
+ // Wait for registry descriptor pushed by backend on flow-open.
1724
1699
  if (!this.registryFetched) {
1725
- console.info("[RemoteGraphRunner] Loading registry from remote...");
1726
- await this.fetchRegistry(client);
1727
- console.info("[RemoteGraphRunner] Loaded registry from remote");
1700
+ console.info("[RemoteGraphRunner] Waiting for registry bootstrap event...");
1701
+ await this.waitForRegistryBootstrap();
1702
+ console.info("[RemoteGraphRunner] Received registry bootstrap event");
1728
1703
  }
1729
1704
  // Clear promise on success
1730
1705
  this.clientPromise = undefined;
@@ -1738,9 +1713,7 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1738
1713
  this.valueCache = new Map();
1739
1714
  this.listenersBound = false;
1740
1715
  this.registryFetched = false;
1741
- this.MAX_REGISTRY_FETCH_ATTEMPTS = 3;
1742
- this.INITIAL_RETRY_DELAY_MS = 1000; // 1 second
1743
- this.REGISTRY_FETCH_TIMEOUT_MS = 3000; // 3 seconds
1716
+ this.REGISTRY_BOOTSTRAP_TIMEOUT_MS = 15000; // 15 seconds
1744
1717
  // Generate readable ID for this runner instance (e.g., remote-001, remote-002)
1745
1718
  remoteRunnerCounter++;
1746
1719
  this.runnerId = `remote-${String(remoteRunnerCounter).padStart(3, "0")}`;