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

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,20 @@ class JournalDurableBackend {
1907
1908
  }
1908
1909
  *append(runId, event, options) {
1909
1910
  const lease = yield* this.ownership(runId);
1911
+ const base = this.sequences.get(runId);
1912
+ const pinned = options?.expectSeq;
1913
+ const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
1914
+ if (encoded !== undefined) {
1915
+ try {
1916
+ return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
1917
+ } catch (error) {
1918
+ if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
1919
+ throw error;
1920
+ }
1921
+ }
1922
+ yield* this.write(runId, lease, event, options);
1923
+ }
1924
+ *write(runId, lease, event, options) {
1910
1925
  try {
1911
1926
  const outcome = yield* invoke(() => this.journal.append(lease, event, options));
1912
1927
  const nextSeq = (this.sequences.get(runId) ?? 0) + 1;
@@ -2088,17 +2103,6 @@ class JournalDurableBackend {
2088
2103
  pendingStageMessages: replacePendingStageMessagesForRun(handle.pendingStageMessages ?? [], logicalRunId, messages),
2089
2104
  updatedAt: Math.max(Date.now(), handle.updatedAt + 1)
2090
2105
  };
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
2106
  yield* this.snapshot(next, RUN_EVENT_TYPES.messageQueued);
2103
2107
  return true;
2104
2108
  }
@@ -2438,31 +2442,143 @@ function uniqueByIdentity(messages) {
2438
2442
  function isDeltaEncoded(message) {
2439
2443
  return message.deliveryDelta !== undefined;
2440
2444
  }
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 } };
2445
+ function deliveryDelta(base, deliveries) {
2446
+ const drop = [];
2447
+ let kept = 0;
2448
+ base.forEach((delivery, index) => {
2449
+ if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
2450
+ kept++;
2451
+ else
2452
+ drop.push(index);
2464
2453
  });
2465
- return encodedAny ? encoded : undefined;
2454
+ const add = deliveries.slice(kept);
2455
+ return drop.length === 0 ? { add } : { drop, add };
2456
+ }
2457
+ function pendingStageFields(message) {
2458
+ return Object.keys(message);
2459
+ }
2460
+ function copyField(target, source, key) {
2461
+ target[key] = source[key];
2462
+ }
2463
+ function isRemovedField(message, key) {
2464
+ return message[key] === undefined;
2465
+ }
2466
+ function json(message) {
2467
+ let text = entryJson.get(message);
2468
+ if (text === undefined) {
2469
+ text = JSON.stringify(message);
2470
+ entryJson.set(message, text);
2471
+ }
2472
+ return text;
2473
+ }
2474
+ function patchEntry(index, base, message) {
2475
+ const set = {};
2476
+ const unset = pendingStageFields(base).filter((key) => base[key] !== undefined && isRemovedField(message, key));
2477
+ for (const key of pendingStageFields(message)) {
2478
+ if (message[key] === undefined || key === "deliveries")
2479
+ continue;
2480
+ if (JSON.stringify(message[key]) !== JSON.stringify(base[key]))
2481
+ copyField(set, message, key);
2482
+ }
2483
+ let delta;
2484
+ if (message.deliveries !== undefined) {
2485
+ if (base.deliveries === undefined)
2486
+ set.deliveries = message.deliveries;
2487
+ else if (JSON.stringify(base.deliveries) !== JSON.stringify(message.deliveries))
2488
+ delta = deliveryDelta(base.deliveries, message.deliveries);
2489
+ }
2490
+ return {
2491
+ patch: index,
2492
+ ...Object.keys(set).length === 0 ? {} : { set },
2493
+ ...unset.length === 0 ? {} : { unset },
2494
+ ...delta === undefined ? {} : { deliveryDelta: delta }
2495
+ };
2496
+ }
2497
+ function encodePendingStageList(previous, next) {
2498
+ const positions = new Map;
2499
+ const repeated = new Set;
2500
+ previous.forEach((message, index) => {
2501
+ const key = identity(message);
2502
+ if (positions.has(key))
2503
+ repeated.add(key);
2504
+ positions.set(key, index);
2505
+ });
2506
+ for (const key of repeated)
2507
+ positions.delete(key);
2508
+ const items = [];
2509
+ let reused = 0;
2510
+ for (const message of next) {
2511
+ const index = positions.get(identity(message));
2512
+ const base = index === undefined ? undefined : previous[index];
2513
+ if (base === undefined) {
2514
+ items.push(message);
2515
+ continue;
2516
+ }
2517
+ reused++;
2518
+ const patched = base === message || json(base) === json(message) ? undefined : patchEntry(index, base, message);
2519
+ if (patched === undefined || Object.keys(patched).length === 1) {
2520
+ const last = items.at(-1);
2521
+ if (Array.isArray(last) && last[0] + last[1] === index)
2522
+ last[1]++;
2523
+ else
2524
+ items.push([index, 1]);
2525
+ continue;
2526
+ }
2527
+ items.push(JSON.stringify(patched).length < json(message).length ? patched : message);
2528
+ }
2529
+ return reused > 0 ? items : undefined;
2530
+ }
2531
+ function decodePendingStageList(previous, items) {
2532
+ const base = (index) => {
2533
+ if (!Number.isInteger(index) || index < 0 || index >= previous.length)
2534
+ throw new Error(`atomic-workflows: journal pending-stage change names missing entry ${index}`);
2535
+ return previous[index];
2536
+ };
2537
+ const result = [];
2538
+ for (const item of items) {
2539
+ if (Array.isArray(item)) {
2540
+ const [start, count] = item;
2541
+ for (let index = start;index < start + count; index++)
2542
+ result.push(base(index));
2543
+ } else if (typeof item.patch === "number") {
2544
+ const { patch, set, unset, deliveryDelta: delta } = item;
2545
+ const entry = { ...base(patch), ...set };
2546
+ for (const key of unset ?? [])
2547
+ delete entry[key];
2548
+ if (delta !== undefined) {
2549
+ const dropped = new Set(delta.drop ?? []);
2550
+ const deliveries = base(patch).deliveries ?? [];
2551
+ entry.deliveries = [...deliveries.filter((_, index) => !dropped.has(index)), ...delta.add];
2552
+ }
2553
+ result.push(entry);
2554
+ } else
2555
+ result.push(item);
2556
+ }
2557
+ return result;
2558
+ }
2559
+ function encodeHandleEvent(event, previous) {
2560
+ const handle = writtenHandle(event);
2561
+ if (handle?.pendingStageMessages === undefined || previous === undefined)
2562
+ return;
2563
+ const change = encodePendingStageList(previous, handle.pendingStageMessages);
2564
+ if (change === undefined)
2565
+ return;
2566
+ const { pendingStageMessages: _full, ...rest } = handle;
2567
+ const encoded = { ...rest, pendingStageMessageChange: change };
2568
+ if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
2569
+ return { ...event, payload: { ...event.payload, handle: encoded } };
2570
+ return { ...event, payload: encoded };
2571
+ }
2572
+ function decodeHandle(handle, previous) {
2573
+ const { pendingStageMessageChange: change, ...rest } = handle;
2574
+ if (change !== undefined)
2575
+ return { ...rest, pendingStageMessages: decodePendingStageList(previous ?? [], change) };
2576
+ if (!hasPendingStageDeliveryDelta(handle.pendingStageMessages))
2577
+ return handle;
2578
+ return {
2579
+ ...handle,
2580
+ pendingStageMessages: decodePendingStageDeliveries(previous ?? [], handle.pendingStageMessages ?? [])
2581
+ };
2466
2582
  }
2467
2583
  function decodePendingStageDeliveries(previous, messages) {
2468
2584
  if (!messages.some(isDeltaEncoded))
@@ -2482,7 +2598,7 @@ function decodePendingStageDeliveries(previous, messages) {
2482
2598
  function hasPendingStageDeliveryDelta(messages) {
2483
2599
  return messages?.some(isDeltaEncoded) === true;
2484
2600
  }
2485
- var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError;
2601
+ var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
2486
2602
  var init_journal_backend = __esm(() => {
2487
2603
  init_workflow_instance_ownership_error();
2488
2604
  init_backend();
@@ -2540,6 +2656,7 @@ var init_journal_backend = __esm(() => {
2540
2656
  this.name = "JournalMessageScopeError";
2541
2657
  }
2542
2658
  };
2659
+ entryJson = new WeakMap;
2543
2660
  });
2544
2661
 
2545
2662
  // dist/builtin/workflows/src/durable/journal/legacy-journal-tables.ts
@@ -57532,7 +57649,20 @@ function createWorkflowBoundarySegmentsResolver(runs) {
57532
57649
  };
57533
57650
  }
57534
57651
  function workflowBoundaryHops(runs, runId) {
57652
+ return boundaryHopsFrom(new Map(runs.map((run) => [run.id, run])), runId);
57653
+ }
57654
+ function createWorkflowBoundaryHopsResolver(runs) {
57535
57655
  const runById = new Map(runs.map((run) => [run.id, run]));
57656
+ const cache = new Map;
57657
+ return (runId) => {
57658
+ if (cache.has(runId))
57659
+ return cache.get(runId);
57660
+ const hops = boundaryHopsFrom(runById, runId);
57661
+ cache.set(runId, hops);
57662
+ return hops;
57663
+ };
57664
+ }
57665
+ function boundaryHopsFrom(runById, runId) {
57536
57666
  const hops = [];
57537
57667
  let current = runById.get(runId);
57538
57668
  while (current !== undefined && current.parentRunId !== undefined) {
@@ -57558,6 +57688,35 @@ function workflowStagePathVariants(hops, stageSegments) {
57558
57688
  function stageMatchesPathPattern(patternSegments, hops, stageSegments) {
57559
57689
  return workflowStagePathVariants(hops, stageSegments).some((candidate) => matchStagePathSegments(patternSegments, candidate));
57560
57690
  }
57691
+ function createStagePathPatternIndex(patterns) {
57692
+ const byFirstSegment = new Map;
57693
+ const globFirst = [];
57694
+ patterns.forEach((pattern, index) => {
57695
+ const first = pattern[0];
57696
+ if (first === undefined || first.includes("*")) {
57697
+ globFirst.push(index);
57698
+ return;
57699
+ }
57700
+ const bucket = byFirstSegment.get(first);
57701
+ if (bucket === undefined)
57702
+ byFirstSegment.set(first, [index]);
57703
+ else
57704
+ bucket.push(index);
57705
+ });
57706
+ return {
57707
+ matching(hops, stageSegments) {
57708
+ if (patterns.length === 0)
57709
+ return [];
57710
+ const variants = workflowStagePathVariants(hops, stageSegments);
57711
+ const candidates = new Set(globFirst);
57712
+ for (const variant of variants) {
57713
+ for (const index of byFirstSegment.get(variant[0]) ?? [])
57714
+ candidates.add(index);
57715
+ }
57716
+ return [...candidates].sort((left, right) => left - right).filter((index) => variants.some((variant) => matchStagePathSegments(patterns[index], variant)));
57717
+ }
57718
+ };
57719
+ }
57561
57720
  var init_pending_stage_status = __esm(() => {
57562
57721
  init_store_internal();
57563
57722
  init_workflow_stage_target();
@@ -57568,24 +57727,63 @@ function stickyStageDeliveryStatuses(runs, rootRunId, availableBackend) {
57568
57727
  const root = runs.find((run) => run.id === rootRunId);
57569
57728
  const entries = (root?.pendingStageMessages ?? []).filter((entry) => entry.sticky === true);
57570
57729
  const result = [];
57730
+ const patternByTarget = new Map;
57731
+ const patterns = [];
57732
+ const entriesByPattern = [];
57733
+ const ownEntries = [];
57734
+ entries.forEach((entry, index) => {
57735
+ const target = entry.targetPath ?? entry.stageKey;
57736
+ let pattern = patternByTarget.get(target);
57737
+ if (pattern === undefined) {
57738
+ const parsed = parseWorkflowStageTarget(target);
57739
+ pattern = parsed?.rootRunId === rootRunId ? patterns.push(parsed.segments) - 1 : -1;
57740
+ if (pattern >= 0)
57741
+ entriesByPattern.push([]);
57742
+ patternByTarget.set(target, pattern);
57743
+ }
57744
+ if (pattern < 0)
57745
+ return;
57746
+ entriesByPattern[pattern].push(index);
57747
+ ownEntries.push(index);
57748
+ });
57749
+ if (ownEntries.length === 0)
57750
+ return result;
57751
+ const patternIndex = createStagePathPatternIndex(patterns);
57752
+ const deliveriesByEntry = new Map;
57753
+ const entryReceipts = (index, runId, stageId) => {
57754
+ let byStage = deliveriesByEntry.get(index);
57755
+ if (byStage === undefined) {
57756
+ byStage = new Map;
57757
+ for (const delivery of entries[index].deliveries ?? []) {
57758
+ const key = `${delivery.runId}\x00${delivery.stageId}`;
57759
+ const list = byStage.get(key);
57760
+ if (list === undefined)
57761
+ byStage.set(key, [delivery]);
57762
+ else
57763
+ list.push(delivery);
57764
+ }
57765
+ deliveriesByEntry.set(index, byStage);
57766
+ }
57767
+ return byStage.get(`${runId}\x00${stageId}`) ?? [];
57768
+ };
57571
57769
  availableBackend = availableRunDurableBackend(runs, rootRunId) ?? availableBackend;
57572
57770
  const backend = availableBackend === undefined ? undefined : durableBackendForRun(availableBackend, runs, rootRunId);
57771
+ const runById = new Map(runs.map((run) => [run.id, run]));
57772
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
57573
57773
  for (const run of runs) {
57574
- if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunIdForRun(runs, run.id) !== rootRunId)
57774
+ const durableRootRunId = reciprocalWorkflowRootRunId(runById, run.id);
57775
+ if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunId !== rootRunId)
57575
57776
  continue;
57576
- const resolved = durableRootRunIdForRun(runs, run.id) === rootRunId;
57577
- const hops = workflowBoundaryHops(runs, run.id);
57777
+ const resolved = durableRootRunId === rootRunId;
57778
+ const hops = hopsFor(run.id);
57578
57779
  for (const stage of run.stages) {
57579
57780
  if (stage.nodeKind === "tool" || stage.replayKey?.startsWith("prompt:") === true || stage.replayKey?.startsWith("workflow:") === true || stage.workflowChildRun !== undefined || stage.workflowChild !== undefined)
57580
57781
  continue;
57581
- for (const entry of entries) {
57782
+ const matchedEntries = resolved && hops ? patternIndex.matching(hops, [stage.id, stage.name]).flatMap((pattern) => entriesByPattern[pattern]).sort((left, right) => left - right) : ownEntries;
57783
+ for (const index of matchedEntries) {
57784
+ const entry = entries[index];
57582
57785
  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);
57786
+ const receipts = entryReceipts(index, run.id, stage.id);
57589
57787
  const delivered = backend?.hasCachedPendingStageDeliveryReceipt?.(rootRunId, entry.id, {
57590
57788
  runId: run.id,
57591
57789
  stageId: stage.id,
@@ -57903,20 +58101,27 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
57903
58101
  if (isTerminalRunStatus(rootRun.status))
57904
58102
  return [];
57905
58103
  const stickyQueued = (rootRun.pendingStageMessages ?? []).filter((entry) => entry.sticky === true && entry.status === "queued");
58104
+ const segmentsByTarget = new Map;
57906
58105
  const stickySegments = (entry) => {
57907
- const parsed = parseWorkflowStageTarget(entry.targetPath ?? entry.stageKey);
57908
- return parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
58106
+ const target = entry.targetPath ?? entry.stageKey;
58107
+ if (segmentsByTarget.has(target))
58108
+ return segmentsByTarget.get(target);
58109
+ const parsed = parseWorkflowStageTarget(target);
58110
+ const segments = parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
58111
+ segmentsByTarget.set(target, segments);
58112
+ return segments;
57909
58113
  };
57910
58114
  const scanEntries = stickyQueued.filter((entry) => {
57911
58115
  const segments = stickySegments(entry);
57912
58116
  return !(segments !== undefined && segments.length === 1 && segments[0] === "**");
57913
58117
  });
58118
+ const liveStageMatches = materializedStageMatcher(runs, rootRunId);
57914
58119
  const rows = [];
57915
58120
  for (const scanEntry of rootRun.possibleStages ?? []) {
57916
58121
  const rowSegments = splitStagePathSegments(scanEntry);
57917
58122
  if (rowSegments.length === 0 || rowSegments.some((segment) => segment.length === 0))
57918
58123
  continue;
57919
- if (!rowSegments.some((segment) => segment.includes("*")) && materializedStageMatches(runs, rootRunId, rowSegments)) {
58124
+ if (!rowSegments.some((segment) => segment.includes("*")) && liveStageMatches(rowSegments)) {
57920
58125
  continue;
57921
58126
  }
57922
58127
  rows.push({
@@ -57937,28 +58142,43 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
57937
58142
  }).length
57938
58143
  });
57939
58144
  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))
58145
+ const statusesByTarget = new Map;
58146
+ for (const status of statuses) {
58147
+ const forTarget = statusesByTarget.get(status.target);
58148
+ if (forTarget === undefined)
58149
+ statusesByTarget.set(status.target, [status]);
58150
+ else
58151
+ forTarget.push(status);
58152
+ }
58153
+ const queuedByTarget = new Map;
58154
+ for (const entry of stickyQueued) {
58155
+ const target = entry.targetPath ?? entry.stageKey;
58156
+ queuedByTarget.set(target, (queuedByTarget.get(target) ?? 0) + 1);
58157
+ }
58158
+ const rowTargets = new Set(rows.map((row) => row.target));
58159
+ for (const target of statusesByTarget.keys()) {
58160
+ if (rowTargets.has(target))
57942
58161
  continue;
57943
- rows.push({
57944
- target,
57945
- queuedCount: stickyQueued.filter((entry) => (entry.targetPath ?? entry.stageKey) === target).length,
57946
- deliveryOnly: true
57947
- });
58162
+ rowTargets.add(target);
58163
+ rows.push({ target, queuedCount: queuedByTarget.get(target) ?? 0, deliveryOnly: true });
57948
58164
  }
57949
58165
  for (let index = 0;index < rows.length; index++) {
57950
58166
  const row = rows[index];
57951
- const deliveryStates = statuses.filter((status) => status.target === row.target);
57952
- if (deliveryStates.length > 0)
58167
+ const deliveryStates = statusesByTarget.get(row.target);
58168
+ if (deliveryStates !== undefined)
57953
58169
  rows[index] = { ...row, deliveryStates };
57954
58170
  }
57955
58171
  return rows;
57956
58172
  }
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);
58173
+ function materializedStageMatcher(runs, rootRunId) {
58174
+ const runById = new Map(runs.map((run) => [run.id, run]));
58175
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58176
+ const invocationRuns = runs.filter((run) => reciprocalWorkflowRootRunId(runById, run.id) === rootRunId);
58177
+ return (entrySegments) => materializedStageMatches(invocationRuns, hopsFor, entrySegments);
58178
+ }
58179
+ function materializedStageMatches(invocationRuns, hopsFor, entrySegments) {
58180
+ for (const run of invocationRuns) {
58181
+ const hops = hopsFor(run.id);
57962
58182
  if (hops === undefined)
57963
58183
  continue;
57964
58184
  for (const stage of run.stages) {
@@ -58233,10 +58453,12 @@ async function recordConfirmedStickyDeliveries(activeStore, event) {
58233
58453
  }
58234
58454
  function matchingLiveStages(runs, rootRunId, patternSegments) {
58235
58455
  const matches = [];
58456
+ const runById = new Map(runs.map((run) => [run.id, run]));
58457
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58236
58458
  for (const run of runs) {
58237
- if (durableRootRunIdForRun(runs, run.id) !== rootRunId)
58459
+ if (reciprocalWorkflowRootRunId(runById, run.id) !== rootRunId)
58238
58460
  continue;
58239
- const hops = workflowBoundaryHops(runs, run.id);
58461
+ const hops = hopsFor(run.id);
58240
58462
  if (hops === undefined)
58241
58463
  continue;
58242
58464
  for (const stage of run.stages) {
@@ -58372,11 +58594,26 @@ function writeMessage(socket, msg, callback) {
58372
58594
  }
58373
58595
  function createMessageReader(onMessage, onError) {
58374
58596
  let buffer = Buffer.alloc(0);
58597
+ let pending = [];
58598
+ let pendingLength = 0;
58599
+ let awaitedLength = 0;
58375
58600
  return (data) => {
58376
- buffer = Buffer.concat([buffer, data]);
58601
+ if (pendingLength + data.length < awaitedLength) {
58602
+ pending.push(data);
58603
+ pendingLength += data.length;
58604
+ return;
58605
+ }
58606
+ buffer = pending.length === 0 ? Buffer.concat([buffer, data]) : Buffer.concat([...pending, data]);
58607
+ pending = [];
58608
+ pendingLength = 0;
58609
+ awaitedLength = 0;
58377
58610
  while (buffer.length >= 4) {
58378
58611
  const length = buffer.readUInt32BE(0);
58379
58612
  if (buffer.length < 4 + length) {
58613
+ pending = [buffer];
58614
+ pendingLength = buffer.length;
58615
+ awaitedLength = 4 + length;
58616
+ buffer = Buffer.alloc(0);
58380
58617
  break;
58381
58618
  }
58382
58619
  const payload = buffer.subarray(4, 4 + length);
@@ -163,9 +163,9 @@
163
163
  "license": "Unlicense"
164
164
  },
165
165
  "node_modules/undici": {
166
- "version": "6.29.0",
167
- "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz",
168
- "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==",
166
+ "version": "6.29.1",
167
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz",
168
+ "integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==",
169
169
  "license": "MIT",
170
170
  "engines": {
171
171
  "node": ">=18.17"