@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.
@@ -9870,12 +9870,16 @@ function removeProcessExitCleanup(cleanup) {
9870
9870
  if (processExitCleanups.delete(cleanup) && processExitCleanups.size === 0)
9871
9871
  process.off("exit", runProcessExitCleanups);
9872
9872
  }
9873
+ function writtenHandle(event) {
9874
+ if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
9875
+ return event.payload.handle;
9876
+ if (event.type === RUN_EVENT_TYPES.checkpointRecorded || event.type === RUN_EVENT_TYPES.messageSettled || event.type === RUN_EVENT_TYPES.messageDelivered)
9877
+ return;
9878
+ return event.payload;
9879
+ }
9873
9880
  function snapshotNeedsHistory(tail) {
9874
- const event = tail.snapshot.event;
9875
- if (event.type !== RUN_EVENT_TYPES.messageQueued)
9876
- return false;
9877
- const payload = event.payload;
9878
- return hasPendingStageDeliveryDelta(payload.pendingStageMessages);
9881
+ const handle = writtenHandle(tail.snapshot.event);
9882
+ return handle !== undefined && (handle.pendingStageMessageChange !== undefined || hasPendingStageDeliveryDelta(handle.pendingStageMessages));
9879
9883
  }
9880
9884
  function* invoke(action) {
9881
9885
  try {
@@ -9989,14 +9993,11 @@ class JournalDurableBackend {
9989
9993
  const payload = event.payload;
9990
9994
  this.projection.archivePendingStageDeliveryReceipt(entry.runId, payload.messageId, payload.delivery, payload.accounting);
9991
9995
  } else if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased) {
9992
- this.projection.applyWorkflowSnapshot(event.payload.handle);
9996
+ this.projection.applyWorkflowSnapshot(decodeHandle(event.payload.handle, this.projection.getWorkflow(entry.runId)?.pendingStageMessages));
9993
9997
  this.prompts.set(entry.runId, new PromptReservationState(event.payload.handle.pendingPrompts, event.payload.prompts));
9994
9998
  } else {
9995
9999
  const previous = this.projection.getWorkflow(entry.runId);
9996
- const handle = event.type === RUN_EVENT_TYPES.messageQueued && hasPendingStageDeliveryDelta(event.payload.pendingStageMessages) ? {
9997
- ...event.payload,
9998
- pendingStageMessages: decodePendingStageDeliveries(previous?.pendingStageMessages ?? [], event.payload.pendingStageMessages ?? [])
9999
- } : event.payload;
10000
+ const handle = decodeHandle(event.payload, previous?.pendingStageMessages);
10000
10001
  this.projection.applyWorkflowSnapshot(handle);
10001
10002
  if (event.type === RUN_EVENT_TYPES.runStarted || previous?.pendingPrompts !== handle.pendingPrompts)
10002
10003
  this.prompts.delete(entry.runId);
@@ -10116,6 +10117,24 @@ class JournalDurableBackend {
10116
10117
  }
10117
10118
  *append(runId, event, options) {
10118
10119
  const lease = yield* this.ownership(runId);
10120
+ const pinned = options?.expectSeq;
10121
+ for (let attempt = 0;attempt < CHANGE_APPEND_ATTEMPTS; attempt++) {
10122
+ const base = this.sequences.get(runId);
10123
+ const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
10124
+ if (encoded === undefined)
10125
+ break;
10126
+ try {
10127
+ return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
10128
+ } catch (error) {
10129
+ if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
10130
+ throw error;
10131
+ }
10132
+ for (const entry of yield* this.entries(runId, (this.sequences.get(runId) ?? 0) + 1))
10133
+ this.fold(entry);
10134
+ }
10135
+ yield* this.write(runId, lease, event, options);
10136
+ }
10137
+ *write(runId, lease, event, options) {
10119
10138
  try {
10120
10139
  const outcome = yield* invoke(() => this.journal.append(lease, event, options));
10121
10140
  const nextSeq = (this.sequences.get(runId) ?? 0) + 1;
@@ -10297,17 +10316,6 @@ class JournalDurableBackend {
10297
10316
  pendingStageMessages: replacePendingStageMessagesForRun(handle.pendingStageMessages ?? [], logicalRunId, messages),
10298
10317
  updatedAt: Math.max(Date.now(), handle.updatedAt + 1)
10299
10318
  };
10300
- const encoded = encodePendingStageDeliveries(handle.pendingStageMessages ?? [], next.pendingStageMessages ?? []);
10301
- const base = this.sequences.get(runId);
10302
- if (encoded !== undefined && base !== undefined) {
10303
- try {
10304
- yield* this.append(runId, { type: RUN_EVENT_TYPES.messageQueued, payload: { ...next, pendingStageMessages: encoded } }, { expectSeq: base });
10305
- return true;
10306
- } catch (error) {
10307
- if (!(error instanceof JournalCasConflictError))
10308
- throw error;
10309
- }
10310
- }
10311
10319
  yield* this.snapshot(next, RUN_EVENT_TYPES.messageQueued);
10312
10320
  return true;
10313
10321
  }
@@ -10647,31 +10655,143 @@ function uniqueByIdentity(messages) {
10647
10655
  function isDeltaEncoded(message) {
10648
10656
  return message.deliveryDelta !== undefined;
10649
10657
  }
10650
- function encodePendingStageDeliveries(previous, next) {
10651
- const bases = uniqueByIdentity(previous);
10652
- const nextIdentities = uniqueByIdentity(next);
10653
- let encodedAny = false;
10654
- const encoded = next.map((message) => {
10655
- const base = bases.get(identity(message))?.deliveries;
10656
- const deliveries = message.deliveries;
10657
- if (base === undefined || deliveries === undefined || !nextIdentities.has(identity(message)))
10658
- return message;
10659
- const drop = [];
10660
- let kept = 0;
10661
- base.forEach((delivery, index) => {
10662
- if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
10663
- kept++;
10664
- else
10665
- drop.push(index);
10666
- });
10667
- const add = deliveries.slice(kept);
10668
- if (drop.length + add.length >= deliveries.length)
10669
- return message;
10670
- encodedAny = true;
10671
- const { deliveries: _full, ...rest } = message;
10672
- return { ...rest, deliveryDelta: drop.length === 0 ? { add } : { drop, add } };
10658
+ function deliveryDelta(base, deliveries) {
10659
+ const drop = [];
10660
+ let kept = 0;
10661
+ base.forEach((delivery, index) => {
10662
+ if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
10663
+ kept++;
10664
+ else
10665
+ drop.push(index);
10666
+ });
10667
+ const add = deliveries.slice(kept);
10668
+ return drop.length === 0 ? { add } : { drop, add };
10669
+ }
10670
+ function pendingStageFields(message) {
10671
+ return Object.keys(message);
10672
+ }
10673
+ function copyField(target, source, key) {
10674
+ target[key] = source[key];
10675
+ }
10676
+ function isRemovedField(message, key) {
10677
+ return message[key] === undefined;
10678
+ }
10679
+ function json(message) {
10680
+ let text = entryJson.get(message);
10681
+ if (text === undefined) {
10682
+ text = JSON.stringify(message);
10683
+ entryJson.set(message, text);
10684
+ }
10685
+ return text;
10686
+ }
10687
+ function patchEntry(index, base, message) {
10688
+ const set = {};
10689
+ const unset = pendingStageFields(base).filter((key) => base[key] !== undefined && isRemovedField(message, key));
10690
+ for (const key of pendingStageFields(message)) {
10691
+ if (message[key] === undefined || key === "deliveries")
10692
+ continue;
10693
+ if (JSON.stringify(message[key]) !== JSON.stringify(base[key]))
10694
+ copyField(set, message, key);
10695
+ }
10696
+ let delta;
10697
+ if (message.deliveries !== undefined) {
10698
+ if (base.deliveries === undefined)
10699
+ set.deliveries = message.deliveries;
10700
+ else if (JSON.stringify(base.deliveries) !== JSON.stringify(message.deliveries))
10701
+ delta = deliveryDelta(base.deliveries, message.deliveries);
10702
+ }
10703
+ return {
10704
+ patch: index,
10705
+ ...Object.keys(set).length === 0 ? {} : { set },
10706
+ ...unset.length === 0 ? {} : { unset },
10707
+ ...delta === undefined ? {} : { deliveryDelta: delta }
10708
+ };
10709
+ }
10710
+ function encodePendingStageList(previous, next) {
10711
+ const positions = new Map;
10712
+ const repeated = new Set;
10713
+ previous.forEach((message, index) => {
10714
+ const key = identity(message);
10715
+ if (positions.has(key))
10716
+ repeated.add(key);
10717
+ positions.set(key, index);
10673
10718
  });
10674
- return encodedAny ? encoded : undefined;
10719
+ for (const key of repeated)
10720
+ positions.delete(key);
10721
+ const items = [];
10722
+ let reused = 0;
10723
+ for (const message of next) {
10724
+ const index = positions.get(identity(message));
10725
+ const base = index === undefined ? undefined : previous[index];
10726
+ if (base === undefined) {
10727
+ items.push(message);
10728
+ continue;
10729
+ }
10730
+ reused++;
10731
+ const patched = base === message || json(base) === json(message) ? undefined : patchEntry(index, base, message);
10732
+ if (patched === undefined || Object.keys(patched).length === 1) {
10733
+ const last = items.at(-1);
10734
+ if (Array.isArray(last) && last[0] + last[1] === index)
10735
+ last[1]++;
10736
+ else
10737
+ items.push([index, 1]);
10738
+ continue;
10739
+ }
10740
+ items.push(JSON.stringify(patched).length < json(message).length ? patched : message);
10741
+ }
10742
+ return reused > 0 ? items : undefined;
10743
+ }
10744
+ function decodePendingStageList(previous, items) {
10745
+ const base = (index) => {
10746
+ if (!Number.isInteger(index) || index < 0 || index >= previous.length)
10747
+ throw new Error(`atomic-workflows: journal pending-stage change names missing entry ${index}`);
10748
+ return previous[index];
10749
+ };
10750
+ const result = [];
10751
+ for (const item of items) {
10752
+ if (Array.isArray(item)) {
10753
+ const [start, count] = item;
10754
+ for (let index = start;index < start + count; index++)
10755
+ result.push(base(index));
10756
+ } else if (typeof item.patch === "number") {
10757
+ const { patch, set, unset, deliveryDelta: delta } = item;
10758
+ const entry = { ...base(patch), ...set };
10759
+ for (const key of unset ?? [])
10760
+ delete entry[key];
10761
+ if (delta !== undefined) {
10762
+ const dropped = new Set(delta.drop ?? []);
10763
+ const deliveries = base(patch).deliveries ?? [];
10764
+ entry.deliveries = [...deliveries.filter((_, index) => !dropped.has(index)), ...delta.add];
10765
+ }
10766
+ result.push(entry);
10767
+ } else
10768
+ result.push(item);
10769
+ }
10770
+ return result;
10771
+ }
10772
+ function encodeHandleEvent(event, previous) {
10773
+ const handle = writtenHandle(event);
10774
+ if (handle?.pendingStageMessages === undefined || previous === undefined)
10775
+ return;
10776
+ const change = encodePendingStageList(previous, handle.pendingStageMessages);
10777
+ if (change === undefined)
10778
+ return;
10779
+ const { pendingStageMessages: _full, ...rest } = handle;
10780
+ const encoded = { ...rest, pendingStageMessageChange: change };
10781
+ if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
10782
+ return { ...event, payload: { ...event.payload, handle: encoded } };
10783
+ return { ...event, payload: encoded };
10784
+ }
10785
+ function decodeHandle(handle, previous) {
10786
+ const { pendingStageMessageChange: change, ...rest } = handle;
10787
+ if (change !== undefined)
10788
+ return { ...rest, pendingStageMessages: decodePendingStageList(previous ?? [], change) };
10789
+ if (!hasPendingStageDeliveryDelta(handle.pendingStageMessages))
10790
+ return handle;
10791
+ return {
10792
+ ...handle,
10793
+ pendingStageMessages: decodePendingStageDeliveries(previous ?? [], handle.pendingStageMessages ?? [])
10794
+ };
10675
10795
  }
10676
10796
  function decodePendingStageDeliveries(previous, messages) {
10677
10797
  if (!messages.some(isDeltaEncoded))
@@ -10691,7 +10811,7 @@ function decodePendingStageDeliveries(previous, messages) {
10691
10811
  function hasPendingStageDeliveryDelta(messages) {
10692
10812
  return messages?.some(isDeltaEncoded) === true;
10693
10813
  }
10694
- var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError;
10814
+ var PROCESS_HOLDER_ID, CHANGE_APPEND_ATTEMPTS = 4, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
10695
10815
  var init_journal_backend = __esm(() => {
10696
10816
  init_workflow_instance_ownership_error();
10697
10817
  init_backend();
@@ -10749,6 +10869,7 @@ var init_journal_backend = __esm(() => {
10749
10869
  this.name = "JournalMessageScopeError";
10750
10870
  }
10751
10871
  };
10872
+ entryJson = new WeakMap;
10752
10873
  });
10753
10874
 
10754
10875
  // dist/builtin/workflows/src/durable/factory.ts
@@ -58215,7 +58336,20 @@ function createWorkflowBoundarySegmentsResolver(runs) {
58215
58336
  };
58216
58337
  }
58217
58338
  function workflowBoundaryHops(runs, runId) {
58339
+ return boundaryHopsFrom(new Map(runs.map((run) => [run.id, run])), runId);
58340
+ }
58341
+ function createWorkflowBoundaryHopsResolver(runs) {
58218
58342
  const runById = new Map(runs.map((run) => [run.id, run]));
58343
+ const cache = new Map;
58344
+ return (runId) => {
58345
+ if (cache.has(runId))
58346
+ return cache.get(runId);
58347
+ const hops = boundaryHopsFrom(runById, runId);
58348
+ cache.set(runId, hops);
58349
+ return hops;
58350
+ };
58351
+ }
58352
+ function boundaryHopsFrom(runById, runId) {
58219
58353
  const hops = [];
58220
58354
  let current = runById.get(runId);
58221
58355
  while (current !== undefined && current.parentRunId !== undefined) {
@@ -58241,6 +58375,35 @@ function workflowStagePathVariants(hops, stageSegments) {
58241
58375
  function stageMatchesPathPattern(patternSegments, hops, stageSegments) {
58242
58376
  return workflowStagePathVariants(hops, stageSegments).some((candidate) => matchStagePathSegments(patternSegments, candidate));
58243
58377
  }
58378
+ function createStagePathPatternIndex(patterns) {
58379
+ const byFirstSegment = new Map;
58380
+ const globFirst = [];
58381
+ patterns.forEach((pattern, index) => {
58382
+ const first = pattern[0];
58383
+ if (first === undefined || first.includes("*")) {
58384
+ globFirst.push(index);
58385
+ return;
58386
+ }
58387
+ const bucket = byFirstSegment.get(first);
58388
+ if (bucket === undefined)
58389
+ byFirstSegment.set(first, [index]);
58390
+ else
58391
+ bucket.push(index);
58392
+ });
58393
+ return {
58394
+ matching(hops, stageSegments) {
58395
+ if (patterns.length === 0)
58396
+ return [];
58397
+ const variants = workflowStagePathVariants(hops, stageSegments);
58398
+ const candidates = new Set(globFirst);
58399
+ for (const variant of variants) {
58400
+ for (const index of byFirstSegment.get(variant[0]) ?? [])
58401
+ candidates.add(index);
58402
+ }
58403
+ return [...candidates].sort((left, right) => left - right).filter((index) => variants.some((variant) => matchStagePathSegments(patterns[index], variant)));
58404
+ }
58405
+ };
58406
+ }
58244
58407
  var init_pending_stage_status = __esm(() => {
58245
58408
  init_store_internal();
58246
58409
  init_workflow_stage_target();
@@ -58251,24 +58414,63 @@ function stickyStageDeliveryStatuses(runs, rootRunId, availableBackend) {
58251
58414
  const root = runs.find((run) => run.id === rootRunId);
58252
58415
  const entries = (root?.pendingStageMessages ?? []).filter((entry) => entry.sticky === true);
58253
58416
  const result = [];
58417
+ const patternByTarget = new Map;
58418
+ const patterns = [];
58419
+ const entriesByPattern = [];
58420
+ const ownEntries = [];
58421
+ entries.forEach((entry, index) => {
58422
+ const target = entry.targetPath ?? entry.stageKey;
58423
+ let pattern = patternByTarget.get(target);
58424
+ if (pattern === undefined) {
58425
+ const parsed = parseWorkflowStageTarget(target);
58426
+ pattern = parsed?.rootRunId === rootRunId ? patterns.push(parsed.segments) - 1 : -1;
58427
+ if (pattern >= 0)
58428
+ entriesByPattern.push([]);
58429
+ patternByTarget.set(target, pattern);
58430
+ }
58431
+ if (pattern < 0)
58432
+ return;
58433
+ entriesByPattern[pattern].push(index);
58434
+ ownEntries.push(index);
58435
+ });
58436
+ if (ownEntries.length === 0)
58437
+ return result;
58438
+ const patternIndex = createStagePathPatternIndex(patterns);
58439
+ const deliveriesByEntry = new Map;
58440
+ const entryReceipts = (index, runId, stageId) => {
58441
+ let byStage = deliveriesByEntry.get(index);
58442
+ if (byStage === undefined) {
58443
+ byStage = new Map;
58444
+ for (const delivery of entries[index].deliveries ?? []) {
58445
+ const key = `${delivery.runId}\x00${delivery.stageId}`;
58446
+ const list = byStage.get(key);
58447
+ if (list === undefined)
58448
+ byStage.set(key, [delivery]);
58449
+ else
58450
+ list.push(delivery);
58451
+ }
58452
+ deliveriesByEntry.set(index, byStage);
58453
+ }
58454
+ return byStage.get(`${runId}\x00${stageId}`) ?? [];
58455
+ };
58254
58456
  availableBackend = availableRunDurableBackend(runs, rootRunId) ?? availableBackend;
58255
58457
  const backend = availableBackend === undefined ? undefined : durableBackendForRun(availableBackend, runs, rootRunId);
58458
+ const runById = new Map(runs.map((run) => [run.id, run]));
58459
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58256
58460
  for (const run of runs) {
58257
- if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunIdForRun(runs, run.id) !== rootRunId)
58461
+ const durableRootRunId = reciprocalWorkflowRootRunId(runById, run.id);
58462
+ if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunId !== rootRunId)
58258
58463
  continue;
58259
- const resolved = durableRootRunIdForRun(runs, run.id) === rootRunId;
58260
- const hops = workflowBoundaryHops(runs, run.id);
58464
+ const resolved = durableRootRunId === rootRunId;
58465
+ const hops = hopsFor(run.id);
58261
58466
  for (const stage of run.stages) {
58262
58467
  if (stage.nodeKind === "tool" || stage.replayKey?.startsWith("prompt:") === true || stage.replayKey?.startsWith("workflow:") === true || stage.workflowChildRun !== undefined || stage.workflowChild !== undefined)
58263
58468
  continue;
58264
- for (const entry of entries) {
58469
+ const matchedEntries = resolved && hops ? patternIndex.matching(hops, [stage.id, stage.name]).flatMap((pattern) => entriesByPattern[pattern]).sort((left, right) => left - right) : ownEntries;
58470
+ for (const index of matchedEntries) {
58471
+ const entry = entries[index];
58265
58472
  const target = entry.targetPath ?? entry.stageKey;
58266
- const parsed = parseWorkflowStageTarget(target);
58267
- if (!parsed || parsed.rootRunId !== rootRunId)
58268
- continue;
58269
- if (resolved && hops && !stageMatchesPathPattern(parsed.segments, hops, [stage.id, stage.name]))
58270
- continue;
58271
- const receipts = (entry.deliveries ?? []).filter((delivery) => delivery.runId === run.id && delivery.stageId === stage.id);
58473
+ const receipts = entryReceipts(index, run.id, stage.id);
58272
58474
  const delivered = backend?.hasCachedPendingStageDeliveryReceipt?.(rootRunId, entry.id, {
58273
58475
  runId: run.id,
58274
58476
  stageId: stage.id,
@@ -58586,20 +58788,27 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
58586
58788
  if (isTerminalRunStatus(rootRun.status))
58587
58789
  return [];
58588
58790
  const stickyQueued = (rootRun.pendingStageMessages ?? []).filter((entry) => entry.sticky === true && entry.status === "queued");
58791
+ const segmentsByTarget = new Map;
58589
58792
  const stickySegments = (entry) => {
58590
- const parsed = parseWorkflowStageTarget(entry.targetPath ?? entry.stageKey);
58591
- return parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
58793
+ const target = entry.targetPath ?? entry.stageKey;
58794
+ if (segmentsByTarget.has(target))
58795
+ return segmentsByTarget.get(target);
58796
+ const parsed = parseWorkflowStageTarget(target);
58797
+ const segments = parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
58798
+ segmentsByTarget.set(target, segments);
58799
+ return segments;
58592
58800
  };
58593
58801
  const scanEntries = stickyQueued.filter((entry) => {
58594
58802
  const segments = stickySegments(entry);
58595
58803
  return !(segments !== undefined && segments.length === 1 && segments[0] === "**");
58596
58804
  });
58805
+ const liveStageMatches = materializedStageMatcher(runs, rootRunId);
58597
58806
  const rows = [];
58598
58807
  for (const scanEntry of rootRun.possibleStages ?? []) {
58599
58808
  const rowSegments = splitStagePathSegments(scanEntry);
58600
58809
  if (rowSegments.length === 0 || rowSegments.some((segment) => segment.length === 0))
58601
58810
  continue;
58602
- if (!rowSegments.some((segment) => segment.includes("*")) && materializedStageMatches(runs, rootRunId, rowSegments)) {
58811
+ if (!rowSegments.some((segment) => segment.includes("*")) && liveStageMatches(rowSegments)) {
58603
58812
  continue;
58604
58813
  }
58605
58814
  rows.push({
@@ -58620,28 +58829,43 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
58620
58829
  }).length
58621
58830
  });
58622
58831
  const statuses = stickyStageDeliveryStatuses(runs, rootRunId, backend);
58623
- for (const target of new Set(statuses.map((status) => status.target))) {
58624
- if (rows.some((row) => row.target === target))
58832
+ const statusesByTarget = new Map;
58833
+ for (const status of statuses) {
58834
+ const forTarget = statusesByTarget.get(status.target);
58835
+ if (forTarget === undefined)
58836
+ statusesByTarget.set(status.target, [status]);
58837
+ else
58838
+ forTarget.push(status);
58839
+ }
58840
+ const queuedByTarget = new Map;
58841
+ for (const entry of stickyQueued) {
58842
+ const target = entry.targetPath ?? entry.stageKey;
58843
+ queuedByTarget.set(target, (queuedByTarget.get(target) ?? 0) + 1);
58844
+ }
58845
+ const rowTargets = new Set(rows.map((row) => row.target));
58846
+ for (const target of statusesByTarget.keys()) {
58847
+ if (rowTargets.has(target))
58625
58848
  continue;
58626
- rows.push({
58627
- target,
58628
- queuedCount: stickyQueued.filter((entry) => (entry.targetPath ?? entry.stageKey) === target).length,
58629
- deliveryOnly: true
58630
- });
58849
+ rowTargets.add(target);
58850
+ rows.push({ target, queuedCount: queuedByTarget.get(target) ?? 0, deliveryOnly: true });
58631
58851
  }
58632
58852
  for (let index = 0;index < rows.length; index++) {
58633
58853
  const row = rows[index];
58634
- const deliveryStates = statuses.filter((status) => status.target === row.target);
58635
- if (deliveryStates.length > 0)
58854
+ const deliveryStates = statusesByTarget.get(row.target);
58855
+ if (deliveryStates !== undefined)
58636
58856
  rows[index] = { ...row, deliveryStates };
58637
58857
  }
58638
58858
  return rows;
58639
58859
  }
58640
- function materializedStageMatches(runs, rootRunId, entrySegments) {
58641
- for (const run of runs) {
58642
- if (durableRootRunIdForRun(runs, run.id) !== rootRunId)
58643
- continue;
58644
- const hops = workflowBoundaryHops(runs, run.id);
58860
+ function materializedStageMatcher(runs, rootRunId) {
58861
+ const runById = new Map(runs.map((run) => [run.id, run]));
58862
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58863
+ const invocationRuns = runs.filter((run) => reciprocalWorkflowRootRunId(runById, run.id) === rootRunId);
58864
+ return (entrySegments) => materializedStageMatches(invocationRuns, hopsFor, entrySegments);
58865
+ }
58866
+ function materializedStageMatches(invocationRuns, hopsFor, entrySegments) {
58867
+ for (const run of invocationRuns) {
58868
+ const hops = hopsFor(run.id);
58645
58869
  if (hops === undefined)
58646
58870
  continue;
58647
58871
  for (const stage of run.stages) {
@@ -58916,10 +59140,12 @@ async function recordConfirmedStickyDeliveries(activeStore, event) {
58916
59140
  }
58917
59141
  function matchingLiveStages(runs, rootRunId, patternSegments) {
58918
59142
  const matches = [];
59143
+ const runById = new Map(runs.map((run) => [run.id, run]));
59144
+ const hopsFor = createWorkflowBoundaryHopsResolver(runs);
58919
59145
  for (const run of runs) {
58920
- if (durableRootRunIdForRun(runs, run.id) !== rootRunId)
59146
+ if (reciprocalWorkflowRootRunId(runById, run.id) !== rootRunId)
58921
59147
  continue;
58922
- const hops = workflowBoundaryHops(runs, run.id);
59148
+ const hops = hopsFor(run.id);
58923
59149
  if (hops === undefined)
58924
59150
  continue;
58925
59151
  for (const stage of run.stages) {
@@ -59055,11 +59281,26 @@ function writeMessage(socket, msg, callback) {
59055
59281
  }
59056
59282
  function createMessageReader(onMessage, onError) {
59057
59283
  let buffer = Buffer.alloc(0);
59284
+ let pending = [];
59285
+ let pendingLength = 0;
59286
+ let awaitedLength = 0;
59058
59287
  return (data) => {
59059
- buffer = Buffer.concat([buffer, data]);
59288
+ if (pendingLength + data.length < awaitedLength) {
59289
+ pending.push(data);
59290
+ pendingLength += data.length;
59291
+ return;
59292
+ }
59293
+ buffer = pending.length === 0 ? Buffer.concat([buffer, data]) : Buffer.concat([...pending, data]);
59294
+ pending = [];
59295
+ pendingLength = 0;
59296
+ awaitedLength = 0;
59060
59297
  while (buffer.length >= 4) {
59061
59298
  const length = buffer.readUInt32BE(0);
59062
59299
  if (buffer.length < 4 + length) {
59300
+ pending = [buffer];
59301
+ pendingLength = buffer.length;
59302
+ awaitedLength = 4 + length;
59303
+ buffer = Buffer.alloc(0);
59063
59304
  break;
59064
59305
  }
59065
59306
  const payload = buffer.subarray(4, 4 + length);