@bastani/atomic 0.9.44-alpha.2 → 0.9.44-alpha.4

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.
@@ -1661,12 +1661,16 @@ function removeProcessExitCleanup(cleanup) {
1661
1661
  if (processExitCleanups.delete(cleanup) && processExitCleanups.size === 0)
1662
1662
  process.off("exit", runProcessExitCleanups);
1663
1663
  }
1664
+ function writtenHandle(event) {
1665
+ if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
1666
+ return event.payload.handle;
1667
+ if (event.type === RUN_EVENT_TYPES.checkpointRecorded || event.type === RUN_EVENT_TYPES.messageSettled || event.type === RUN_EVENT_TYPES.messageDelivered)
1668
+ return;
1669
+ return event.payload;
1670
+ }
1664
1671
  function snapshotNeedsHistory(tail) {
1665
- const event = tail.snapshot.event;
1666
- if (event.type !== RUN_EVENT_TYPES.messageQueued)
1667
- return false;
1668
- const payload = event.payload;
1669
- return hasPendingStageDeliveryDelta(payload.pendingStageMessages);
1672
+ const handle = writtenHandle(tail.snapshot.event);
1673
+ return handle !== undefined && (handle.pendingStageMessageChange !== undefined || hasPendingStageDeliveryDelta(handle.pendingStageMessages));
1670
1674
  }
1671
1675
  function* invoke(action) {
1672
1676
  try {
@@ -1780,14 +1784,11 @@ class JournalDurableBackend {
1780
1784
  const payload = event.payload;
1781
1785
  this.projection.archivePendingStageDeliveryReceipt(entry.runId, payload.messageId, payload.delivery, payload.accounting);
1782
1786
  } else if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased) {
1783
- this.projection.applyWorkflowSnapshot(event.payload.handle);
1787
+ this.projection.applyWorkflowSnapshot(decodeHandle(event.payload.handle, this.projection.getWorkflow(entry.runId)?.pendingStageMessages));
1784
1788
  this.prompts.set(entry.runId, new PromptReservationState(event.payload.handle.pendingPrompts, event.payload.prompts));
1785
1789
  } else {
1786
1790
  const previous = this.projection.getWorkflow(entry.runId);
1787
- const handle = event.type === RUN_EVENT_TYPES.messageQueued && hasPendingStageDeliveryDelta(event.payload.pendingStageMessages) ? {
1788
- ...event.payload,
1789
- pendingStageMessages: decodePendingStageDeliveries(previous?.pendingStageMessages ?? [], event.payload.pendingStageMessages ?? [])
1790
- } : event.payload;
1791
+ const handle = decodeHandle(event.payload, previous?.pendingStageMessages);
1791
1792
  this.projection.applyWorkflowSnapshot(handle);
1792
1793
  if (event.type === RUN_EVENT_TYPES.runStarted || previous?.pendingPrompts !== handle.pendingPrompts)
1793
1794
  this.prompts.delete(entry.runId);
@@ -1907,6 +1908,24 @@ class JournalDurableBackend {
1907
1908
  }
1908
1909
  *append(runId, event, options) {
1909
1910
  const lease = yield* this.ownership(runId);
1911
+ const pinned = options?.expectSeq;
1912
+ for (let attempt = 0;attempt < CHANGE_APPEND_ATTEMPTS; attempt++) {
1913
+ const base = this.sequences.get(runId);
1914
+ const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
1915
+ if (encoded === undefined)
1916
+ break;
1917
+ try {
1918
+ return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
1919
+ } catch (error) {
1920
+ if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
1921
+ throw error;
1922
+ }
1923
+ for (const entry of yield* this.entries(runId, (this.sequences.get(runId) ?? 0) + 1))
1924
+ this.fold(entry);
1925
+ }
1926
+ yield* this.write(runId, lease, event, options);
1927
+ }
1928
+ *write(runId, lease, event, options) {
1910
1929
  try {
1911
1930
  const outcome = yield* invoke(() => this.journal.append(lease, event, options));
1912
1931
  const nextSeq = (this.sequences.get(runId) ?? 0) + 1;
@@ -2088,17 +2107,6 @@ class JournalDurableBackend {
2088
2107
  pendingStageMessages: replacePendingStageMessagesForRun(handle.pendingStageMessages ?? [], logicalRunId, messages),
2089
2108
  updatedAt: Math.max(Date.now(), handle.updatedAt + 1)
2090
2109
  };
2091
- const encoded = encodePendingStageDeliveries(handle.pendingStageMessages ?? [], next.pendingStageMessages ?? []);
2092
- const base = this.sequences.get(runId);
2093
- if (encoded !== undefined && base !== undefined) {
2094
- try {
2095
- yield* this.append(runId, { type: RUN_EVENT_TYPES.messageQueued, payload: { ...next, pendingStageMessages: encoded } }, { expectSeq: base });
2096
- return true;
2097
- } catch (error) {
2098
- if (!(error instanceof JournalCasConflictError))
2099
- throw error;
2100
- }
2101
- }
2102
2110
  yield* this.snapshot(next, RUN_EVENT_TYPES.messageQueued);
2103
2111
  return true;
2104
2112
  }
@@ -2438,31 +2446,143 @@ function uniqueByIdentity(messages) {
2438
2446
  function isDeltaEncoded(message) {
2439
2447
  return message.deliveryDelta !== undefined;
2440
2448
  }
2441
- function encodePendingStageDeliveries(previous, next) {
2442
- const bases = uniqueByIdentity(previous);
2443
- const nextIdentities = uniqueByIdentity(next);
2444
- let encodedAny = false;
2445
- const encoded = next.map((message) => {
2446
- const base = bases.get(identity(message))?.deliveries;
2447
- const deliveries = message.deliveries;
2448
- if (base === undefined || deliveries === undefined || !nextIdentities.has(identity(message)))
2449
- return message;
2450
- const drop = [];
2451
- let kept = 0;
2452
- base.forEach((delivery, index) => {
2453
- if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
2454
- kept++;
2455
- else
2456
- drop.push(index);
2457
- });
2458
- const add = deliveries.slice(kept);
2459
- if (drop.length + add.length >= deliveries.length)
2460
- return message;
2461
- encodedAny = true;
2462
- const { deliveries: _full, ...rest } = message;
2463
- return { ...rest, deliveryDelta: drop.length === 0 ? { add } : { drop, add } };
2449
+ function deliveryDelta(base, deliveries) {
2450
+ const drop = [];
2451
+ let kept = 0;
2452
+ base.forEach((delivery, index) => {
2453
+ if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
2454
+ kept++;
2455
+ else
2456
+ drop.push(index);
2457
+ });
2458
+ const add = deliveries.slice(kept);
2459
+ return drop.length === 0 ? { add } : { drop, add };
2460
+ }
2461
+ function pendingStageFields(message) {
2462
+ return Object.keys(message);
2463
+ }
2464
+ function copyField(target, source, key) {
2465
+ target[key] = source[key];
2466
+ }
2467
+ function isRemovedField(message, key) {
2468
+ return message[key] === undefined;
2469
+ }
2470
+ function json(message) {
2471
+ let text = entryJson.get(message);
2472
+ if (text === undefined) {
2473
+ text = JSON.stringify(message);
2474
+ entryJson.set(message, text);
2475
+ }
2476
+ return text;
2477
+ }
2478
+ function patchEntry(index, base, message) {
2479
+ const set = {};
2480
+ const unset = pendingStageFields(base).filter((key) => base[key] !== undefined && isRemovedField(message, key));
2481
+ for (const key of pendingStageFields(message)) {
2482
+ if (message[key] === undefined || key === "deliveries")
2483
+ continue;
2484
+ if (JSON.stringify(message[key]) !== JSON.stringify(base[key]))
2485
+ copyField(set, message, key);
2486
+ }
2487
+ let delta;
2488
+ if (message.deliveries !== undefined) {
2489
+ if (base.deliveries === undefined)
2490
+ set.deliveries = message.deliveries;
2491
+ else if (JSON.stringify(base.deliveries) !== JSON.stringify(message.deliveries))
2492
+ delta = deliveryDelta(base.deliveries, message.deliveries);
2493
+ }
2494
+ return {
2495
+ patch: index,
2496
+ ...Object.keys(set).length === 0 ? {} : { set },
2497
+ ...unset.length === 0 ? {} : { unset },
2498
+ ...delta === undefined ? {} : { deliveryDelta: delta }
2499
+ };
2500
+ }
2501
+ function encodePendingStageList(previous, next) {
2502
+ const positions = new Map;
2503
+ const repeated = new Set;
2504
+ previous.forEach((message, index) => {
2505
+ const key = identity(message);
2506
+ if (positions.has(key))
2507
+ repeated.add(key);
2508
+ positions.set(key, index);
2464
2509
  });
2465
- return encodedAny ? encoded : undefined;
2510
+ for (const key of repeated)
2511
+ positions.delete(key);
2512
+ const items = [];
2513
+ let reused = 0;
2514
+ for (const message of next) {
2515
+ const index = positions.get(identity(message));
2516
+ const base = index === undefined ? undefined : previous[index];
2517
+ if (base === undefined) {
2518
+ items.push(message);
2519
+ continue;
2520
+ }
2521
+ reused++;
2522
+ const patched = base === message || json(base) === json(message) ? undefined : patchEntry(index, base, message);
2523
+ if (patched === undefined || Object.keys(patched).length === 1) {
2524
+ const last = items.at(-1);
2525
+ if (Array.isArray(last) && last[0] + last[1] === index)
2526
+ last[1]++;
2527
+ else
2528
+ items.push([index, 1]);
2529
+ continue;
2530
+ }
2531
+ items.push(JSON.stringify(patched).length < json(message).length ? patched : message);
2532
+ }
2533
+ return reused > 0 ? items : undefined;
2534
+ }
2535
+ function decodePendingStageList(previous, items) {
2536
+ const base = (index) => {
2537
+ if (!Number.isInteger(index) || index < 0 || index >= previous.length)
2538
+ throw new Error(`atomic-workflows: journal pending-stage change names missing entry ${index}`);
2539
+ return previous[index];
2540
+ };
2541
+ const result = [];
2542
+ for (const item of items) {
2543
+ if (Array.isArray(item)) {
2544
+ const [start, count] = item;
2545
+ for (let index = start;index < start + count; index++)
2546
+ result.push(base(index));
2547
+ } else if (typeof item.patch === "number") {
2548
+ const { patch, set, unset, deliveryDelta: delta } = item;
2549
+ const entry = { ...base(patch), ...set };
2550
+ for (const key of unset ?? [])
2551
+ delete entry[key];
2552
+ if (delta !== undefined) {
2553
+ const dropped = new Set(delta.drop ?? []);
2554
+ const deliveries = base(patch).deliveries ?? [];
2555
+ entry.deliveries = [...deliveries.filter((_, index) => !dropped.has(index)), ...delta.add];
2556
+ }
2557
+ result.push(entry);
2558
+ } else
2559
+ result.push(item);
2560
+ }
2561
+ return result;
2562
+ }
2563
+ function encodeHandleEvent(event, previous) {
2564
+ const handle = writtenHandle(event);
2565
+ if (handle?.pendingStageMessages === undefined || previous === undefined)
2566
+ return;
2567
+ const change = encodePendingStageList(previous, handle.pendingStageMessages);
2568
+ if (change === undefined)
2569
+ return;
2570
+ const { pendingStageMessages: _full, ...rest } = handle;
2571
+ const encoded = { ...rest, pendingStageMessageChange: change };
2572
+ if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
2573
+ return { ...event, payload: { ...event.payload, handle: encoded } };
2574
+ return { ...event, payload: encoded };
2575
+ }
2576
+ function decodeHandle(handle, previous) {
2577
+ const { pendingStageMessageChange: change, ...rest } = handle;
2578
+ if (change !== undefined)
2579
+ return { ...rest, pendingStageMessages: decodePendingStageList(previous ?? [], change) };
2580
+ if (!hasPendingStageDeliveryDelta(handle.pendingStageMessages))
2581
+ return handle;
2582
+ return {
2583
+ ...handle,
2584
+ pendingStageMessages: decodePendingStageDeliveries(previous ?? [], handle.pendingStageMessages ?? [])
2585
+ };
2466
2586
  }
2467
2587
  function decodePendingStageDeliveries(previous, messages) {
2468
2588
  if (!messages.some(isDeltaEncoded))
@@ -2482,7 +2602,7 @@ function decodePendingStageDeliveries(previous, messages) {
2482
2602
  function hasPendingStageDeliveryDelta(messages) {
2483
2603
  return messages?.some(isDeltaEncoded) === true;
2484
2604
  }
2485
- var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError;
2605
+ var PROCESS_HOLDER_ID, CHANGE_APPEND_ATTEMPTS = 4, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
2486
2606
  var init_journal_backend = __esm(() => {
2487
2607
  init_workflow_instance_ownership_error();
2488
2608
  init_backend();
@@ -2540,6 +2660,7 @@ var init_journal_backend = __esm(() => {
2540
2660
  this.name = "JournalMessageScopeError";
2541
2661
  }
2542
2662
  };
2663
+ entryJson = new WeakMap;
2543
2664
  });
2544
2665
 
2545
2666
  // dist/builtin/workflows/src/durable/journal/legacy-journal-tables.ts
@@ -57532,7 +57653,20 @@ function createWorkflowBoundarySegmentsResolver(runs) {
57532
57653
  };
57533
57654
  }
57534
57655
  function workflowBoundaryHops(runs, runId) {
57656
+ return boundaryHopsFrom(new Map(runs.map((run) => [run.id, run])), runId);
57657
+ }
57658
+ function createWorkflowBoundaryHopsResolver(runs) {
57535
57659
  const runById = new Map(runs.map((run) => [run.id, run]));
57660
+ const cache = new Map;
57661
+ return (runId) => {
57662
+ if (cache.has(runId))
57663
+ return cache.get(runId);
57664
+ const hops = boundaryHopsFrom(runById, runId);
57665
+ cache.set(runId, hops);
57666
+ return hops;
57667
+ };
57668
+ }
57669
+ function boundaryHopsFrom(runById, runId) {
57536
57670
  const hops = [];
57537
57671
  let current = runById.get(runId);
57538
57672
  while (current !== undefined && current.parentRunId !== undefined) {
@@ -57558,6 +57692,35 @@ function workflowStagePathVariants(hops, stageSegments) {
57558
57692
  function stageMatchesPathPattern(patternSegments, hops, stageSegments) {
57559
57693
  return workflowStagePathVariants(hops, stageSegments).some((candidate) => matchStagePathSegments(patternSegments, candidate));
57560
57694
  }
57695
+ function createStagePathPatternIndex(patterns) {
57696
+ const byFirstSegment = new Map;
57697
+ const globFirst = [];
57698
+ patterns.forEach((pattern, index) => {
57699
+ const first = pattern[0];
57700
+ if (first === undefined || first.includes("*")) {
57701
+ globFirst.push(index);
57702
+ return;
57703
+ }
57704
+ const bucket = byFirstSegment.get(first);
57705
+ if (bucket === undefined)
57706
+ byFirstSegment.set(first, [index]);
57707
+ else
57708
+ bucket.push(index);
57709
+ });
57710
+ return {
57711
+ matching(hops, stageSegments) {
57712
+ if (patterns.length === 0)
57713
+ return [];
57714
+ const variants = workflowStagePathVariants(hops, stageSegments);
57715
+ const candidates = new Set(globFirst);
57716
+ for (const variant of variants) {
57717
+ for (const index of byFirstSegment.get(variant[0]) ?? [])
57718
+ candidates.add(index);
57719
+ }
57720
+ return [...candidates].sort((left, right) => left - right).filter((index) => variants.some((variant) => matchStagePathSegments(patterns[index], variant)));
57721
+ }
57722
+ };
57723
+ }
57561
57724
  var init_pending_stage_status = __esm(() => {
57562
57725
  init_store_internal();
57563
57726
  init_workflow_stage_target();
@@ -57568,24 +57731,63 @@ function stickyStageDeliveryStatuses(runs, rootRunId, availableBackend) {
57568
57731
  const root = runs.find((run) => run.id === rootRunId);
57569
57732
  const entries = (root?.pendingStageMessages ?? []).filter((entry) => entry.sticky === true);
57570
57733
  const result = [];
57734
+ const patternByTarget = new Map;
57735
+ const patterns = [];
57736
+ const entriesByPattern = [];
57737
+ const ownEntries = [];
57738
+ entries.forEach((entry, index) => {
57739
+ const target = entry.targetPath ?? entry.stageKey;
57740
+ let pattern = patternByTarget.get(target);
57741
+ if (pattern === undefined) {
57742
+ const parsed = parseWorkflowStageTarget(target);
57743
+ pattern = parsed?.rootRunId === rootRunId ? patterns.push(parsed.segments) - 1 : -1;
57744
+ if (pattern >= 0)
57745
+ entriesByPattern.push([]);
57746
+ patternByTarget.set(target, pattern);
57747
+ }
57748
+ if (pattern < 0)
57749
+ return;
57750
+ entriesByPattern[pattern].push(index);
57751
+ ownEntries.push(index);
57752
+ });
57753
+ if (ownEntries.length === 0)
57754
+ return result;
57755
+ const patternIndex = createStagePathPatternIndex(patterns);
57756
+ const deliveriesByEntry = new Map;
57757
+ const entryReceipts = (index, runId, stageId) => {
57758
+ let byStage = deliveriesByEntry.get(index);
57759
+ if (byStage === undefined) {
57760
+ byStage = new Map;
57761
+ for (const delivery of entries[index].deliveries ?? []) {
57762
+ const key = `${delivery.runId}\x00${delivery.stageId}`;
57763
+ const list = byStage.get(key);
57764
+ if (list === undefined)
57765
+ byStage.set(key, [delivery]);
57766
+ else
57767
+ list.push(delivery);
57768
+ }
57769
+ deliveriesByEntry.set(index, byStage);
57770
+ }
57771
+ return byStage.get(`${runId}\x00${stageId}`) ?? [];
57772
+ };
57571
57773
  availableBackend = availableRunDurableBackend(runs, rootRunId) ?? availableBackend;
57572
57774
  const backend = availableBackend === undefined ? undefined : durableBackendForRun(availableBackend, runs, rootRunId);
57775
+ const runById = new Map(runs.map((run) => [run.id, run]));
57776
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
57573
57777
  for (const run of runs) {
57574
- if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunIdForRun(runs, run.id) !== rootRunId)
57778
+ const durableRootRunId = reciprocalWorkflowRootRunId(runById, run.id);
57779
+ if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunId !== rootRunId)
57575
57780
  continue;
57576
- const resolved = durableRootRunIdForRun(runs, run.id) === rootRunId;
57577
- const hops = workflowBoundaryHops(runs, run.id);
57781
+ const resolved = durableRootRunId === rootRunId;
57782
+ const hops = hopsFor(run.id);
57578
57783
  for (const stage of run.stages) {
57579
57784
  if (stage.nodeKind === "tool" || stage.replayKey?.startsWith("prompt:") === true || stage.replayKey?.startsWith("workflow:") === true || stage.workflowChildRun !== undefined || stage.workflowChild !== undefined)
57580
57785
  continue;
57581
- for (const entry of entries) {
57786
+ const matchedEntries = resolved && hops ? patternIndex.matching(hops, [stage.id, stage.name]).flatMap((pattern) => entriesByPattern[pattern]).sort((left, right) => left - right) : ownEntries;
57787
+ for (const index of matchedEntries) {
57788
+ const entry = entries[index];
57582
57789
  const target = entry.targetPath ?? entry.stageKey;
57583
- const parsed = parseWorkflowStageTarget(target);
57584
- if (!parsed || parsed.rootRunId !== rootRunId)
57585
- continue;
57586
- if (resolved && hops && !stageMatchesPathPattern(parsed.segments, hops, [stage.id, stage.name]))
57587
- continue;
57588
- const receipts = (entry.deliveries ?? []).filter((delivery) => delivery.runId === run.id && delivery.stageId === stage.id);
57790
+ const receipts = entryReceipts(index, run.id, stage.id);
57589
57791
  const delivered = backend?.hasCachedPendingStageDeliveryReceipt?.(rootRunId, entry.id, {
57590
57792
  runId: run.id,
57591
57793
  stageId: stage.id,
@@ -57903,20 +58105,27 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
57903
58105
  if (isTerminalRunStatus(rootRun.status))
57904
58106
  return [];
57905
58107
  const stickyQueued = (rootRun.pendingStageMessages ?? []).filter((entry) => entry.sticky === true && entry.status === "queued");
58108
+ const segmentsByTarget = new Map;
57906
58109
  const stickySegments = (entry) => {
57907
- const parsed = parseWorkflowStageTarget(entry.targetPath ?? entry.stageKey);
57908
- return parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
58110
+ const target = entry.targetPath ?? entry.stageKey;
58111
+ if (segmentsByTarget.has(target))
58112
+ return segmentsByTarget.get(target);
58113
+ const parsed = parseWorkflowStageTarget(target);
58114
+ const segments = parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
58115
+ segmentsByTarget.set(target, segments);
58116
+ return segments;
57909
58117
  };
57910
58118
  const scanEntries = stickyQueued.filter((entry) => {
57911
58119
  const segments = stickySegments(entry);
57912
58120
  return !(segments !== undefined && segments.length === 1 && segments[0] === "**");
57913
58121
  });
58122
+ const liveStageMatches = materializedStageMatcher(runs, rootRunId);
57914
58123
  const rows = [];
57915
58124
  for (const scanEntry of rootRun.possibleStages ?? []) {
57916
58125
  const rowSegments = splitStagePathSegments(scanEntry);
57917
58126
  if (rowSegments.length === 0 || rowSegments.some((segment) => segment.length === 0))
57918
58127
  continue;
57919
- if (!rowSegments.some((segment) => segment.includes("*")) && materializedStageMatches(runs, rootRunId, rowSegments)) {
58128
+ if (!rowSegments.some((segment) => segment.includes("*")) && liveStageMatches(rowSegments)) {
57920
58129
  continue;
57921
58130
  }
57922
58131
  rows.push({
@@ -57937,28 +58146,43 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
57937
58146
  }).length
57938
58147
  });
57939
58148
  const statuses = stickyStageDeliveryStatuses(runs, rootRunId, backend);
57940
- for (const target of new Set(statuses.map((status) => status.target))) {
57941
- if (rows.some((row) => row.target === target))
58149
+ const statusesByTarget = new Map;
58150
+ for (const status of statuses) {
58151
+ const forTarget = statusesByTarget.get(status.target);
58152
+ if (forTarget === undefined)
58153
+ statusesByTarget.set(status.target, [status]);
58154
+ else
58155
+ forTarget.push(status);
58156
+ }
58157
+ const queuedByTarget = new Map;
58158
+ for (const entry of stickyQueued) {
58159
+ const target = entry.targetPath ?? entry.stageKey;
58160
+ queuedByTarget.set(target, (queuedByTarget.get(target) ?? 0) + 1);
58161
+ }
58162
+ const rowTargets = new Set(rows.map((row) => row.target));
58163
+ for (const target of statusesByTarget.keys()) {
58164
+ if (rowTargets.has(target))
57942
58165
  continue;
57943
- rows.push({
57944
- target,
57945
- queuedCount: stickyQueued.filter((entry) => (entry.targetPath ?? entry.stageKey) === target).length,
57946
- deliveryOnly: true
57947
- });
58166
+ rowTargets.add(target);
58167
+ rows.push({ target, queuedCount: queuedByTarget.get(target) ?? 0, deliveryOnly: true });
57948
58168
  }
57949
58169
  for (let index = 0;index < rows.length; index++) {
57950
58170
  const row = rows[index];
57951
- const deliveryStates = statuses.filter((status) => status.target === row.target);
57952
- if (deliveryStates.length > 0)
58171
+ const deliveryStates = statusesByTarget.get(row.target);
58172
+ if (deliveryStates !== undefined)
57953
58173
  rows[index] = { ...row, deliveryStates };
57954
58174
  }
57955
58175
  return rows;
57956
58176
  }
57957
- function materializedStageMatches(runs, rootRunId, entrySegments) {
57958
- for (const run of runs) {
57959
- if (durableRootRunIdForRun(runs, run.id) !== rootRunId)
57960
- continue;
57961
- const hops = workflowBoundaryHops(runs, run.id);
58177
+ function materializedStageMatcher(runs, rootRunId) {
58178
+ const runById = new Map(runs.map((run) => [run.id, run]));
58179
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58180
+ const invocationRuns = runs.filter((run) => reciprocalWorkflowRootRunId(runById, run.id) === rootRunId);
58181
+ return (entrySegments) => materializedStageMatches(invocationRuns, hopsFor, entrySegments);
58182
+ }
58183
+ function materializedStageMatches(invocationRuns, hopsFor, entrySegments) {
58184
+ for (const run of invocationRuns) {
58185
+ const hops = hopsFor(run.id);
57962
58186
  if (hops === undefined)
57963
58187
  continue;
57964
58188
  for (const stage of run.stages) {
@@ -58233,10 +58457,12 @@ async function recordConfirmedStickyDeliveries(activeStore, event) {
58233
58457
  }
58234
58458
  function matchingLiveStages(runs, rootRunId, patternSegments) {
58235
58459
  const matches = [];
58460
+ const runById = new Map(runs.map((run) => [run.id, run]));
58461
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58236
58462
  for (const run of runs) {
58237
- if (durableRootRunIdForRun(runs, run.id) !== rootRunId)
58463
+ if (reciprocalWorkflowRootRunId(runById, run.id) !== rootRunId)
58238
58464
  continue;
58239
- const hops = workflowBoundaryHops(runs, run.id);
58465
+ const hops = hopsFor(run.id);
58240
58466
  if (hops === undefined)
58241
58467
  continue;
58242
58468
  for (const stage of run.stages) {
@@ -58372,11 +58598,26 @@ function writeMessage(socket, msg, callback) {
58372
58598
  }
58373
58599
  function createMessageReader(onMessage, onError) {
58374
58600
  let buffer = Buffer.alloc(0);
58601
+ let pending = [];
58602
+ let pendingLength = 0;
58603
+ let awaitedLength = 0;
58375
58604
  return (data) => {
58376
- buffer = Buffer.concat([buffer, data]);
58605
+ if (pendingLength + data.length < awaitedLength) {
58606
+ pending.push(data);
58607
+ pendingLength += data.length;
58608
+ return;
58609
+ }
58610
+ buffer = pending.length === 0 ? Buffer.concat([buffer, data]) : Buffer.concat([...pending, data]);
58611
+ pending = [];
58612
+ pendingLength = 0;
58613
+ awaitedLength = 0;
58377
58614
  while (buffer.length >= 4) {
58378
58615
  const length = buffer.readUInt32BE(0);
58379
58616
  if (buffer.length < 4 + length) {
58617
+ pending = [buffer];
58618
+ pendingLength = buffer.length;
58619
+ awaitedLength = 4 + length;
58620
+ buffer = Buffer.alloc(0);
58380
58621
  break;
58381
58622
  }
58382
58623
  const payload = buffer.subarray(4, 4 + length);