@bastani/atomic 0.9.62 → 0.9.63-alpha.1

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.
Files changed (29) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/builtin/intercom/package.json +1 -1
  3. package/dist/builtin/mcp/package.json +1 -1
  4. package/dist/builtin/subagents/package.json +1 -1
  5. package/dist/builtin/web-access/package.json +1 -1
  6. package/dist/builtin/workflows/builtin/{chunk-vzbec50q.js → chunk-95r61ve5.js} +1 -1
  7. package/dist/builtin/workflows/builtin/{chunk-a2j0x1a6.js → chunk-qbthhjjk.js} +1 -1
  8. package/dist/builtin/workflows/builtin/{chunk-zhyqnf5g.js → chunk-rv4xxwd6.js} +69 -26
  9. package/dist/builtin/workflows/builtin/goal.js +2 -2
  10. package/dist/builtin/workflows/builtin/index.js +3 -3
  11. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  12. package/dist/builtin/workflows/package.json +1 -1
  13. package/dist/builtin/workflows/src/durable/journal/internal.d.ts +11 -1
  14. package/dist/builtin/workflows/src/durable/journal/sql-run-journal.d.ts +2 -0
  15. package/dist/builtin/workflows/src/extension/index.bundle.mjs +106 -50
  16. package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +106 -50
  17. package/dist/builtin/workflows/src/index.js +106 -50
  18. package/dist/builtin/workflows/src/local-worker-entry.mjs +106 -50
  19. package/dist/core/storage/database.d.ts +11 -1
  20. package/dist/core/storage/database.d.ts.map +1 -1
  21. package/dist/core/storage/database.js.map +1 -1
  22. package/dist/core/storage/index.d.ts +1 -1
  23. package/dist/core/storage/index.d.ts.map +1 -1
  24. package/dist/core/storage/index.js.map +1 -1
  25. package/dist/core/storage/node-sqlite.d.ts.map +1 -1
  26. package/dist/core/storage/node-sqlite.js +194 -23
  27. package/dist/core/storage/node-sqlite.js.map +1 -1
  28. package/npm-shrinkwrap.json +32 -32
  29. package/package.json +3 -3
@@ -188,9 +188,10 @@ function registerSqlPoolStorage(journal, storage) {
188
188
  function sqlPoolStorage(journal) {
189
189
  return poolStorage.get(journal);
190
190
  }
191
- var JOURNAL_READ_PAGE_SIZE = 256, NON_SNAPSHOT_EVENT_TYPES, poolStorage;
191
+ var JOURNAL_READ_PAGE_SIZE = 256, JOURNAL_TRANSACTION, NON_SNAPSHOT_EVENT_TYPES, poolStorage;
192
192
  var init_internal = __esm(() => {
193
193
  init_types();
194
+ JOURNAL_TRANSACTION = { lockWaitMs: 10 * 60000 };
194
195
  NON_SNAPSHOT_EVENT_TYPES = [
195
196
  RUN_EVENT_TYPES.checkpointRecorded,
196
197
  RUN_EVENT_TYPES.messageSettled,
@@ -3211,7 +3212,7 @@ class LegacyJournalRuns {
3211
3212
  return;
3212
3213
  await tx.exec(`CREATE TABLE IF NOT EXISTS ${CURRENT.legacyDeleted}(${JOURNAL_COLUMNS.runId} TEXT PRIMARY KEY, deleted_at INTEGER NOT NULL)`);
3213
3214
  return new LegacyJournalRuns;
3214
- });
3215
+ }, JOURNAL_TRANSACTION);
3215
3216
  } catch {
3216
3217
  return;
3217
3218
  }
@@ -3251,6 +3252,7 @@ class LegacyJournalRuns {
3251
3252
  }
3252
3253
  var CURRENT, COPIED_ALL_MARKER = "unprefixed-journal-tables", LEGACY_COLUMNS, PENDING_LEGACY_RUNS;
3253
3254
  var init_legacy_journal_tables = __esm(() => {
3255
+ init_internal();
3254
3256
  init_types();
3255
3257
  CURRENT = renderStorageIdentifiers("journal", {
3256
3258
  ...JOURNAL_TABLES,
@@ -3301,7 +3303,7 @@ class SqlRunJournal {
3301
3303
  this.tables = tables;
3302
3304
  this.legacy = legacy;
3303
3305
  registerSqlPoolStorage(this, {
3304
- transaction: (body) => this.operation(() => this.database.transaction(body)),
3306
+ transaction: (body) => this.operation(() => this.transaction(body)),
3305
3307
  read: (body) => this.operation(() => body(this.database)),
3306
3308
  withAppendGuard: (guard, action) => this.appendGuard.run(guard, action),
3307
3309
  tables: this.tables
@@ -3341,7 +3343,7 @@ class SqlRunJournal {
3341
3343
  ${JOURNAL_COLUMNS.holderId} TEXT, ${JOURNAL_COLUMNS.epoch} INTEGER NOT NULL, ${JOURNAL_COLUMNS.renewedAt} INTEGER NOT NULL
3342
3344
  );
3343
3345
  `);
3344
- });
3346
+ }, JOURNAL_TRANSACTION);
3345
3347
  const legacy = options.prefix ? undefined : await LegacyJournalRuns.open(database);
3346
3348
  return new SqlRunJournal(database, t, legacy);
3347
3349
  }
@@ -3355,6 +3357,9 @@ class SqlRunJournal {
3355
3357
  if (this.closed)
3356
3358
  throw new StorageUnavailableError2(this.descriptor, new JournalClosedError);
3357
3359
  }
3360
+ transaction(body) {
3361
+ return this.database.transaction(body, JOURNAL_TRANSACTION);
3362
+ }
3358
3363
  operation(action) {
3359
3364
  this.assertOpen();
3360
3365
  const result = action();
@@ -3381,7 +3386,7 @@ class SqlRunJournal {
3381
3386
  return this.operation(async () => {
3382
3387
  if (await this.legacy?.find(this.database, header.runId))
3383
3388
  return "exists";
3384
- const result = await this.database.run(`INSERT INTO ${runs} VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(${JOURNAL_COLUMNS.runId}) DO NOTHING`, header.runId, header.name, header.cwd, header.createdAt, header.status, json);
3389
+ const result = await this.transaction((tx) => tx.run(`INSERT INTO ${runs} VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(${JOURNAL_COLUMNS.runId}) DO NOTHING`, header.runId, header.name, header.cwd, header.createdAt, header.status, json));
3385
3390
  return result.changes === 1 ? "created" : "exists";
3386
3391
  });
3387
3392
  }
@@ -3473,7 +3478,7 @@ class SqlRunJournal {
3473
3478
  this.assertOpen();
3474
3479
  validateText("runId", runId);
3475
3480
  validateText("holderId", holderId);
3476
- return this.operation(() => this.database.transaction(async (tx) => {
3481
+ return this.operation(() => this.transaction(async (tx) => {
3477
3482
  await this.requireRun(tx, runId);
3478
3483
  const current = await this.leaseRow(tx, runId);
3479
3484
  if (current?.[JOURNAL_COLUMNS.holderId] === holderId)
@@ -3488,7 +3493,7 @@ class SqlRunJournal {
3488
3493
  validateText("runId", runId);
3489
3494
  validateText("holderId", holderId);
3490
3495
  validateText("expectedHolder", expectedHolder);
3491
- return this.operation(() => this.database.transaction(async (tx) => {
3496
+ return this.operation(() => this.transaction(async (tx) => {
3492
3497
  await this.requireRun(tx, runId);
3493
3498
  const current = await this.leaseRow(tx, runId);
3494
3499
  if (current?.[JOURNAL_COLUMNS.holderId] !== expectedHolder)
@@ -3518,7 +3523,7 @@ class SqlRunJournal {
3518
3523
  this.assertOpen();
3519
3524
  validateText("runId", runId);
3520
3525
  validateText("holderId", holderId);
3521
- return this.operation(() => this.database.transaction(async (tx) => {
3526
+ return this.operation(() => this.transaction(async (tx) => {
3522
3527
  await this.requireRun(tx, runId);
3523
3528
  const current = await this.leaseRow(tx, runId);
3524
3529
  if (current?.[JOURNAL_COLUMNS.holderId] === holderId)
@@ -3542,7 +3547,7 @@ class SqlRunJournal {
3542
3547
  validateText("runId", lease.runId);
3543
3548
  validateText("holderId", lease.holderId);
3544
3549
  const owned = { ...lease };
3545
- return this.operation(() => this.database.transaction(async (tx) => {
3550
+ return this.operation(() => this.transaction(async (tx) => {
3546
3551
  await this.checkLease(tx, owned);
3547
3552
  await tx.run(`UPDATE ${this.tables.leases} SET ${JOURNAL_COLUMNS.renewedAt} = ${STORE_NOW} WHERE ${JOURNAL_COLUMNS.runId} = ?`, owned.runId);
3548
3553
  }));
@@ -3552,7 +3557,7 @@ class SqlRunJournal {
3552
3557
  validateText("runId", lease.runId);
3553
3558
  validateText("holderId", lease.holderId);
3554
3559
  const owned = { ...lease };
3555
- return this.operation(() => this.database.transaction(async (tx) => {
3560
+ return this.operation(() => this.transaction(async (tx) => {
3556
3561
  await this.checkLease(tx, owned);
3557
3562
  await tx.run(`UPDATE ${this.tables.leases} SET ${JOURNAL_COLUMNS.holderId} = ? WHERE ${JOURNAL_COLUMNS.runId} = ?`, JOURNAL_LEASE.unheld, owned.runId);
3558
3563
  }));
@@ -3568,7 +3573,7 @@ class SqlRunJournal {
3568
3573
  const owned = { ...lease };
3569
3574
  const prepared = this.prepare(event, options?.key, this.appendGuard.getStore());
3570
3575
  const expected = options?.expectSeq;
3571
- return this.operation(() => this.database.transaction(async (tx) => {
3576
+ return this.operation(() => this.transaction(async (tx) => {
3572
3577
  await this.checkLease(tx, owned);
3573
3578
  return this.insert(tx, owned, prepared, expected);
3574
3579
  }));
@@ -3588,7 +3593,7 @@ class SqlRunJournal {
3588
3593
  const batch = this.database.batch?.bind(this.database);
3589
3594
  if (batch && prepared.every((append) => append instanceof Error || append.guard === undefined && typeof append.payload === "string"))
3590
3595
  return this.operation(() => this.appendInOneRequest(batch, owned, prepared));
3591
- return this.operation(() => this.database.transaction(async (tx) => {
3596
+ return this.operation(() => this.transaction(async (tx) => {
3592
3597
  await this.checkLease(tx, owned);
3593
3598
  const results = [];
3594
3599
  for (const append of prepared) {
@@ -3739,14 +3744,14 @@ class SqlRunJournal {
3739
3744
  async deleteRun(runId) {
3740
3745
  this.assertOpen();
3741
3746
  validateText("runId", runId);
3742
- return this.operation(() => this.database.transaction((tx) => this.deleteRunData(tx, runId)));
3747
+ return this.operation(() => this.transaction((tx) => this.deleteRunData(tx, runId)));
3743
3748
  }
3744
3749
  async deleteOwnedRun(lease, expectSeq) {
3745
3750
  this.assertOpen();
3746
3751
  validateText("runId", lease.runId);
3747
3752
  validateText("holderId", lease.holderId);
3748
3753
  const owned = { ...lease };
3749
- return this.operation(() => this.database.transaction(async (tx) => {
3754
+ return this.operation(() => this.transaction(async (tx) => {
3750
3755
  await this.checkLease(tx, owned);
3751
3756
  if (expectSeq !== undefined) {
3752
3757
  const actual = await this.sequence(tx, owned.runId);
@@ -7105,13 +7110,13 @@ class WorkflowObservationRuntime {
7105
7110
  return run.rootRunId;
7106
7111
  if (run.parentRunId === undefined)
7107
7112
  return run.id;
7108
- const parent = this.runs().find((candidate) => candidate.id === run.parentRunId);
7113
+ const parent = this.runs.find(run.parentRunId);
7109
7114
  return parent ? this.rootRunId(parent) : run.parentRunId;
7110
7115
  }
7111
7116
  lifecycle(target, attribution = "unknown") {
7112
7117
  if (this.recovering && !this.liveRunIds.has(target.runId))
7113
7118
  return;
7114
- const run = this.runs().find((candidate) => candidate.id === target.runId);
7119
+ const run = this.runs.find(target.runId);
7115
7120
  if (!run)
7116
7121
  return;
7117
7122
  const rootRunId = this.rootRunId(run);
@@ -7132,7 +7137,7 @@ class WorkflowObservationRuntime {
7132
7137
  });
7133
7138
  }
7134
7139
  control(runId, action, attribution = "unknown") {
7135
- const run = this.runs().find((candidate) => candidate.id === runId);
7140
+ const run = this.runs.find(runId);
7136
7141
  if (!run)
7137
7142
  return;
7138
7143
  if ((action === "quit" || action === "kill" || action === "pause") && this.liveRunIds.has(runId))
@@ -7143,7 +7148,7 @@ class WorkflowObservationRuntime {
7143
7148
  this.invalidate({ runId });
7144
7149
  }
7145
7150
  heartbeat(runId, scheduledAt, intervalMinutes) {
7146
- const run = this.runs().find((candidate) => candidate.id === runId);
7151
+ const run = this.runs.find(runId);
7147
7152
  if (run)
7148
7153
  this.emit({
7149
7154
  kind: "heartbeat",
@@ -7169,7 +7174,7 @@ class WorkflowObservationRuntime {
7169
7174
  if (changes === undefined) {
7170
7175
  const next = new Map;
7171
7176
  const nextOwners = new Map;
7172
- for (const run of this.runs()) {
7177
+ for (const run of this.runs.all()) {
7173
7178
  const owners = nextOwners.get(run.id) ?? new Map;
7174
7179
  nextOwners.set(run.id, owners);
7175
7180
  this.captureRun(run, this.previous.has(`run:${run.id}`), next, owners);
@@ -7196,10 +7201,15 @@ class WorkflowObservationRuntime {
7196
7201
  nodes.tools.add(change.toolNodeId);
7197
7202
  changed.set(change.runId, nodes);
7198
7203
  }
7199
- for (const run of this.runs()) {
7200
- const change = changed.get(run.id);
7201
- if (change === undefined)
7204
+ const ordered = [...changed.keys()].flatMap((runId) => {
7205
+ const position = this.runs.position(runId);
7206
+ return position === undefined ? [] : [{ runId, position }];
7207
+ }).sort((left, right) => left.position - right.position);
7208
+ for (const { runId } of ordered) {
7209
+ const run = this.runs.find(runId);
7210
+ if (run === undefined)
7202
7211
  continue;
7212
+ const change = changed.get(runId);
7203
7213
  const existing = this.previous.has(`run:${run.id}`);
7204
7214
  const nodes = change === "run" || !existing ? undefined : change;
7205
7215
  const next = new Map;
@@ -7237,7 +7247,7 @@ class WorkflowObservationRuntime {
7237
7247
  keys.push(key);
7238
7248
  const previous = this.previous.get(key);
7239
7249
  if (!historical && this.liveRunIds.has(target.runId) && previous?.status !== target.status) {
7240
- this.lifecycle(previous && previous.kind !== "prompt" && target.kind !== "prompt" ? { ...target, previousStatus: previous.status } : target, this.runs().find((candidate) => candidate.id === target.runId)?.origin);
7250
+ this.lifecycle(previous && previous.kind !== "prompt" && target.kind !== "prompt" ? { ...target, previousStatus: previous.status } : target, this.runs.find(target.runId)?.origin);
7241
7251
  }
7242
7252
  };
7243
7253
  visit("run", `run:${run.id}`, { kind: "run", runId: run.id, status: run.status });
@@ -7366,6 +7376,7 @@ function applyRunEndMetadata(run, metadata) {
7366
7376
  function createStoreState() {
7367
7377
  return {
7368
7378
  runs: [],
7379
+ runPositions: new Map,
7369
7380
  notices: [],
7370
7381
  listeners: new Set,
7371
7382
  invalidationListeners: new Set,
@@ -7375,11 +7386,27 @@ function createStoreState() {
7375
7386
  version: 0
7376
7387
  };
7377
7388
  }
7389
+ function reindexRuns(state) {
7390
+ state.runPositions.clear();
7391
+ state.runs.forEach((run, position) => {
7392
+ if (!state.runPositions.has(run.id))
7393
+ state.runPositions.set(run.id, position);
7394
+ });
7395
+ }
7396
+ function runPosition(state, runId) {
7397
+ const position = state.runPositions.get(runId);
7398
+ if (position !== undefined && state.runs[position]?.id === runId)
7399
+ return position;
7400
+ if (position === undefined && state.runPositions.size === state.runs.length)
7401
+ return;
7402
+ reindexRuns(state);
7403
+ return state.runPositions.get(runId);
7404
+ }
7378
7405
  function createStoreContext(state = createStoreState()) {
7379
7406
  let cachedGraphVersion = -1;
7380
7407
  let cachedGraphSnapshot;
7381
7408
  const graphBuilder = new GraphStoreSnapshotBuilder;
7382
- const observation = new WorkflowObservationRuntime(() => state.runs, bumpAndNotify);
7409
+ const observation = new WorkflowObservationRuntime({ all: () => state.runs, find: findRun, position: (runId) => runPosition(state, runId) }, bumpAndNotify);
7383
7410
  function snapshot() {
7384
7411
  return JSON.parse(JSON.stringify({ runs: state.runs, notices: state.notices, version: state.version }));
7385
7412
  }
@@ -7393,7 +7420,7 @@ function createStoreContext(state = createStoreState()) {
7393
7420
  function graphRun(runId) {
7394
7421
  if (cachedGraphSnapshot !== undefined && cachedGraphVersion === state.version)
7395
7422
  return findSnapshotRun(cachedGraphSnapshot.runs, runId);
7396
- const run = state.runs.find((candidate) => candidate.id === runId);
7423
+ const run = findRun(runId);
7397
7424
  return run === undefined ? undefined : graphBuilder.buildRun(run);
7398
7425
  }
7399
7426
  let batchDepth = 0;
@@ -7447,7 +7474,29 @@ function createStoreContext(state = createStoreState()) {
7447
7474
  }
7448
7475
  }
7449
7476
  function findRun(runId) {
7450
- return state.runs.find((r) => r.id === runId);
7477
+ const position = runPosition(state, runId);
7478
+ return position === undefined ? undefined : state.runs[position];
7479
+ }
7480
+ function placeRun(run) {
7481
+ const position = runPosition(state, run.id);
7482
+ if (position !== undefined) {
7483
+ state.runs[position] = run;
7484
+ return;
7485
+ }
7486
+ state.runPositions.set(run.id, state.runs.length);
7487
+ state.runs.push(run);
7488
+ }
7489
+ function removeRunAt(position) {
7490
+ const [removed] = state.runs.splice(position, 1);
7491
+ if (removed === undefined)
7492
+ return;
7493
+ state.runPositions.delete(removed.id);
7494
+ for (let index = position;index < state.runs.length; index++)
7495
+ state.runPositions.set(state.runs[index].id, index);
7496
+ }
7497
+ function clearRuns() {
7498
+ state.runs.length = 0;
7499
+ state.runPositions.clear();
7451
7500
  }
7452
7501
  function findStage(run, stageId) {
7453
7502
  return run.stages.find((s) => s.id === stageId);
@@ -7503,6 +7552,10 @@ function createStoreContext(state = createStoreState()) {
7503
7552
  batch,
7504
7553
  bumpAndNotify,
7505
7554
  findRun,
7555
+ runPosition: (runId) => runPosition(state, runId),
7556
+ placeRun,
7557
+ removeRunAt,
7558
+ clearRuns,
7506
7559
  findStage,
7507
7560
  rejectPrompt,
7508
7561
  rejectStagePrompt,
@@ -8584,6 +8637,9 @@ function createRunStoreMethods(context) {
8584
8637
  runs() {
8585
8638
  return state.runs;
8586
8639
  },
8640
+ run(runId) {
8641
+ return context.findRun(runId);
8642
+ },
8587
8643
  notices() {
8588
8644
  return state.notices;
8589
8645
  },
@@ -8603,11 +8659,7 @@ function createRunStoreMethods(context) {
8603
8659
  return null;
8604
8660
  },
8605
8661
  recordRunStart(run) {
8606
- const index = state.runs.findIndex((existing) => existing.id === run.id);
8607
- if (index === -1)
8608
- state.runs.push(run);
8609
- else
8610
- state.runs[index] = run;
8662
+ context.placeRun(run);
8611
8663
  context.bumpAndNotify({ runId: run.id });
8612
8664
  },
8613
8665
  recordRunSummary(runId, summary, summarizedThrough) {
@@ -8748,17 +8800,13 @@ function createRunStoreMethods(context) {
8748
8800
  restored.result = metadata.result;
8749
8801
  if (metadata.budgetState !== undefined)
8750
8802
  restored.budgetState = metadata.budgetState;
8751
- const index = state.runs.findIndex((candidate) => candidate.id === source.id);
8752
- if (index < 0)
8753
- state.runs.push(restored);
8754
- else
8755
- state.runs[index] = restored;
8803
+ context.placeRun(restored);
8756
8804
  context.bumpAndNotify();
8757
8805
  return true;
8758
8806
  },
8759
8807
  removeRun(runId) {
8760
- const index = state.runs.findIndex((r) => r.id === runId);
8761
- if (index < 0)
8808
+ const index = context.runPosition(runId);
8809
+ if (index === undefined)
8762
8810
  return false;
8763
8811
  const run = state.runs[index];
8764
8812
  const pending = run.pendingPrompt;
@@ -8770,7 +8818,7 @@ function createRunStoreMethods(context) {
8770
8818
  for (const stage of run.stages) {
8771
8819
  state.stagePromptAnswers.delete(context.stagePromptAnswerKey(runId, stage.id));
8772
8820
  }
8773
- state.runs.splice(index, 1);
8821
+ context.removeRunAt(index);
8774
8822
  for (let i = state.notices.length - 1;i >= 0; i--) {
8775
8823
  if (state.notices[i]?.runId === runId)
8776
8824
  state.notices.splice(i, 1);
@@ -8862,7 +8910,7 @@ function createRunStoreMethods(context) {
8862
8910
  clear() {
8863
8911
  if (state.runs.length === 0 && state.notices.length === 0 && state.resolvers.size === 0 && state.stagePromptAnswers.size === 0 && state.stagePromptDrafts.size === 0)
8864
8912
  return;
8865
- state.runs.length = 0;
8913
+ context.clearRuns();
8866
8914
  state.notices.length = 0;
8867
8915
  for (const entry of state.resolvers.values()) {
8868
8916
  entry.reject(new Error("atomic-workflows: store cleared"));
@@ -67665,16 +67713,25 @@ class PoolStageHandoff {
67665
67713
  throw outside2(run.id);
67666
67714
  }
67667
67715
  };
67668
- const before = new Map(this.store.runs().map((run) => [run.id, run]));
67716
+ const before = this.known(subtree);
67669
67717
  owned(before);
67670
67718
  if (subtree.some((run) => before.get(run.id) === undefined))
67671
67719
  await this.backend.catchUpWorkflow(root);
67672
67720
  await this.queue.assertCurrent(this.lease, work);
67673
67721
  return () => this.commit(work, subtree, owned);
67674
67722
  }
67723
+ known(subtree) {
67724
+ const known = new Map;
67725
+ for (const run of subtree) {
67726
+ const existing = this.store.run(run.id);
67727
+ if (existing !== undefined)
67728
+ known.set(run.id, existing);
67729
+ }
67730
+ return known;
67731
+ }
67675
67732
  commit(work, subtree, owned) {
67676
67733
  const root = this.lease.runId;
67677
- const known = new Map(this.store.runs().map((run) => [run.id, run]));
67734
+ const known = this.known(subtree);
67678
67735
  owned(known);
67679
67736
  const attempt = this.enter(work);
67680
67737
  const execution = {
@@ -67708,7 +67765,7 @@ class PoolStageHandoff {
67708
67765
  else
67709
67766
  attempt.sessions.set(key, stage.sessionId);
67710
67767
  }
67711
- const previous = this.store.runs().find((candidate) => candidate.id === run.id);
67768
+ const previous = this.store.run(run.id);
67712
67769
  for (const stage of run.stages)
67713
67770
  if (previous?.stages.find((candidate) => candidate.id === stage.id)?.attached === true)
67714
67771
  stage.attached = true;
@@ -67727,7 +67784,7 @@ class PoolStageHandoff {
67727
67784
  }
67728
67785
  if (runs.length === 0)
67729
67786
  return [];
67730
- const rootRun = this.store.runs().find((run) => run.id === root);
67787
+ const rootRun = this.store.run(root);
67731
67788
  const boundary = rootRun?.stages.find((stage) => stage.id === work.boundaryId);
67732
67789
  if (authoritativeWorkflowChildRunId(boundary) !== work.childRunId)
67733
67790
  throw new Error(`Pool work boundary ${work.boundaryId} is not linked to ${work.childRunId} in the root run`);
@@ -67792,7 +67849,7 @@ class PoolStageHandoff {
67792
67849
  for (const id of attempt.runs)
67793
67850
  rotateWorkflowPendingStageRouteCapability(this.store, id);
67794
67851
  for (const id of attempt.runs) {
67795
- const run = this.store.runs().find((candidate) => candidate.id === id);
67852
+ const run = this.store.run(id);
67796
67853
  if (run?.stages.some((stage) => isLive(stage)) !== true)
67797
67854
  continue;
67798
67855
  this.store.recordRunStart({
@@ -69488,7 +69545,7 @@ class LocalWorkerPool {
69488
69545
  return false;
69489
69546
  }
69490
69547
  applyHeldAnswer(runId, stageId, heldGeneration) {
69491
- const stage = this.store?.runs().find((run) => run.id === runId)?.stages.find((candidate) => candidate.id === stageId);
69548
+ const stage = this.store?.run(runId)?.stages.find((candidate) => candidate.id === stageId);
69492
69549
  if (stage === undefined || this.closed)
69493
69550
  return;
69494
69551
  const generation = stage.workerExecution?.generation ?? 0;
@@ -69544,7 +69601,7 @@ class LocalWorkerPool {
69544
69601
  const key = JSON.stringify([runId, stageId]);
69545
69602
  let view = this.stageViews.get(key);
69546
69603
  if (view === undefined) {
69547
- const stageName = this.store?.runs().find((run) => run.id === runId)?.stages.find((stage) => stage.id === stageId)?.name ?? stageId;
69604
+ const stageName = this.store?.run(runId)?.stages.find((stage) => stage.id === stageId)?.name ?? stageId;
69548
69605
  const created = { key, holders: 0, opening: Promise.resolve(undefined) };
69549
69606
  const transport = this.stageTransport((reason) => {
69550
69607
  tracePooledWatch("root.view.watch-ended", { key, reason, current: this.stageViews.get(key) === created });
@@ -69610,10 +69667,9 @@ class LocalWorkerPool {
69610
69667
  };
69611
69668
  }
69612
69669
  reconnectStageViews() {
69613
- const runs = this.store?.runs() ?? [];
69614
69670
  const stageOf = (key) => {
69615
69671
  const [runId, stageId] = JSON.parse(key);
69616
- const run = runs.find((candidate) => candidate.id === runId);
69672
+ const run = this.store?.run(runId);
69617
69673
  return { runId, stageId, run, stage: run?.stages.find((candidate) => candidate.id === stageId) };
69618
69674
  };
69619
69675
  const ended = (key) => {
@@ -69694,7 +69750,7 @@ class LocalWorkerPool {
69694
69750
  };
69695
69751
  }
69696
69752
  rootProjection() {
69697
- const run = this.store?.runs().find((candidate) => candidate.id === this.root);
69753
+ const run = this.root === undefined ? undefined : this.store?.run(this.root);
69698
69754
  return run === undefined ? undefined : projectRootRun(run);
69699
69755
  }
69700
69756
  rootRun() {
@@ -18,9 +18,19 @@ export interface SqliteStatement {
18
18
  readonly sql: string;
19
19
  readonly params: readonly SqliteValue[];
20
20
  }
21
+ /** How one write transaction waits for the database's write lock. */
22
+ export interface SqliteTransactionOptions {
23
+ /**
24
+ * How long the transaction keeps waiting for the write lock while it is held and no other connection commits,
25
+ * instead of the connection's own lock wait. A writer whose work must not fail because another process stalled
26
+ * with the lock held (starved of CPU, paused by garbage collection, stopped by a signal) waits longer: the holder
27
+ * still commits or rolls back once it runs again. Adapters without a lock wait of their own ignore it.
28
+ */
29
+ readonly lockWaitMs?: number;
30
+ }
21
31
  export interface SqliteDatabase extends SqliteExecutor {
22
32
  readonly descriptor: StorageDescriptor;
23
- transaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;
33
+ transaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>, options?: SqliteTransactionOptions): Promise<T>;
24
34
  /**
25
35
  * Runs the statements in order, in one write transaction, as one call to the database: all of them commit or none
26
36
  * do. Resolves with each statement's rows. Present only when the driver can send a batch in one request, which
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/storage/database.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AACvE,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACjG,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACvF;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACrD,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClF;;;;OAIG;IACH,KAAK,CAAC,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/storage/database.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AACvE,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACjG,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACvF;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACxC;AAED,qEAAqE;AACrE,MAAM,WAAW,wBAAwB;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACrD,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,WAAW,CAAC,CAAC,EACZ,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,EACrD,OAAO,CAAC,EAAE,wBAAwB,GAChC,OAAO,CAAC,CAAC,CAAC,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/core/storage/database.ts"],"names":[],"mappings":"","sourcesContent":["export type SqliteValue = null | number | bigint | string | Uint8Array;\nexport type SqliteRow = Readonly<Record<string, SqliteValue>>;\n\nexport interface SqliteRunResult {\n\treadonly changes: number;\n}\n\nexport interface SqliteExecutor {\n\texec(sql: string): Promise<void>;\n\trun(sql: string, ...params: readonly SqliteValue[]): Promise<SqliteRunResult>;\n\tget<T extends SqliteRow>(sql: string, ...params: readonly SqliteValue[]): Promise<T | undefined>;\n\tall<T extends SqliteRow>(sql: string, ...params: readonly SqliteValue[]): Promise<T[]>;\n}\n\nexport interface StorageDescriptor {\n\treadonly adapter: string;\n\treadonly location: string;\n}\n\n/** One statement of a batch: SQL with positional `?` parameters. */\nexport interface SqliteStatement {\n\treadonly sql: string;\n\treadonly params: readonly SqliteValue[];\n}\n\nexport interface SqliteDatabase extends SqliteExecutor {\n\treadonly descriptor: StorageDescriptor;\n\ttransaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;\n\t/**\n\t * Runs the statements in order, in one write transaction, as one call to the database: all of them commit or none\n\t * do. Resolves with each statement's rows. Present only when the driver can send a batch in one request, which\n\t * saves a round trip per statement against a remote database.\n\t */\n\tbatch?(statements: readonly SqliteStatement[]): Promise<SqliteRow[][]>;\n\tclose(): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/core/storage/database.ts"],"names":[],"mappings":"","sourcesContent":["export type SqliteValue = null | number | bigint | string | Uint8Array;\nexport type SqliteRow = Readonly<Record<string, SqliteValue>>;\n\nexport interface SqliteRunResult {\n\treadonly changes: number;\n}\n\nexport interface SqliteExecutor {\n\texec(sql: string): Promise<void>;\n\trun(sql: string, ...params: readonly SqliteValue[]): Promise<SqliteRunResult>;\n\tget<T extends SqliteRow>(sql: string, ...params: readonly SqliteValue[]): Promise<T | undefined>;\n\tall<T extends SqliteRow>(sql: string, ...params: readonly SqliteValue[]): Promise<T[]>;\n}\n\nexport interface StorageDescriptor {\n\treadonly adapter: string;\n\treadonly location: string;\n}\n\n/** One statement of a batch: SQL with positional `?` parameters. */\nexport interface SqliteStatement {\n\treadonly sql: string;\n\treadonly params: readonly SqliteValue[];\n}\n\n/** How one write transaction waits for the database's write lock. */\nexport interface SqliteTransactionOptions {\n\t/**\n\t * How long the transaction keeps waiting for the write lock while it is held and no other connection commits,\n\t * instead of the connection's own lock wait. A writer whose work must not fail because another process stalled\n\t * with the lock held (starved of CPU, paused by garbage collection, stopped by a signal) waits longer: the holder\n\t * still commits or rolls back once it runs again. Adapters without a lock wait of their own ignore it.\n\t */\n\treadonly lockWaitMs?: number;\n}\n\nexport interface SqliteDatabase extends SqliteExecutor {\n\treadonly descriptor: StorageDescriptor;\n\ttransaction<T>(\n\t\tcallback: (transaction: SqliteExecutor) => Promise<T>,\n\t\toptions?: SqliteTransactionOptions,\n\t): Promise<T>;\n\t/**\n\t * Runs the statements in order, in one write transaction, as one call to the database: all of them commit or none\n\t * do. Resolves with each statement's rows. Present only when the driver can send a batch in one request, which\n\t * saves a round trip per statement against a remote database.\n\t */\n\tbatch?(statements: readonly SqliteStatement[]): Promise<SqliteRow[][]>;\n\tclose(): Promise<void>;\n}\n"]}
@@ -1,4 +1,4 @@
1
- export type { SqliteDatabase, SqliteExecutor, SqliteRow, SqliteRunResult, SqliteStatement, SqliteValue, StorageDescriptor, } from "./database.js";
1
+ export type { SqliteDatabase, SqliteExecutor, SqliteRow, SqliteRunResult, SqliteStatement, SqliteTransactionOptions, SqliteValue, StorageDescriptor, } from "./database.js";
2
2
  export * from "./errors.js";
3
3
  export { openNodeSqliteDatabase, wrapNodeSqliteDatabase } from "./node-sqlite.js";
4
4
  export { renderStorageIdentifiers, validateStoragePrefix } from "./prefix.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/storage/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,GACjB,MAAM,eAAe,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC9E,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/storage/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,EACf,eAAe,EACf,wBAAwB,EACxB,WAAW,EACX,iBAAiB,GACjB,MAAM,eAAe,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC9E,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,cAAc,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/storage/index.ts"],"names":[],"mappings":"AASA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC9E,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,oBAAoB,CAAC","sourcesContent":["export type {\n\tSqliteDatabase,\n\tSqliteExecutor,\n\tSqliteRow,\n\tSqliteRunResult,\n\tSqliteStatement,\n\tSqliteValue,\n\tStorageDescriptor,\n} from \"./database.js\";\nexport * from \"./errors.js\";\nexport { openNodeSqliteDatabase, wrapNodeSqliteDatabase } from \"./node-sqlite.js\";\nexport { renderStorageIdentifiers, validateStoragePrefix } from \"./prefix.js\";\nexport * from \"./provider.js\";\nexport * from \"./run-journal.js\";\nexport { assertStorageSchemaVersion } from \"./schema.js\";\nexport * from \"./selection.js\";\nexport type { SessionStore } from \"./session/types.js\";\nexport * from \"./sqlite-facade.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/storage/index.ts"],"names":[],"mappings":"AAUA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC9E,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,oBAAoB,CAAC","sourcesContent":["export type {\n\tSqliteDatabase,\n\tSqliteExecutor,\n\tSqliteRow,\n\tSqliteRunResult,\n\tSqliteStatement,\n\tSqliteTransactionOptions,\n\tSqliteValue,\n\tStorageDescriptor,\n} from \"./database.js\";\nexport * from \"./errors.js\";\nexport { openNodeSqliteDatabase, wrapNodeSqliteDatabase } from \"./node-sqlite.js\";\nexport { renderStorageIdentifiers, validateStoragePrefix } from \"./prefix.js\";\nexport * from \"./provider.js\";\nexport * from \"./run-journal.js\";\nexport { assertStorageSchemaVersion } from \"./schema.js\";\nexport * from \"./selection.js\";\nexport type { SessionStore } from \"./session/types.js\";\nexport * from \"./sqlite-facade.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"node-sqlite.d.ts","sourceRoot":"","sources":["../../../src/core/storage/node-sqlite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAA6D,MAAM,eAAe,CAAC;AAyjB/G,wBAAsB,sBAAsB,CAC3C,IAAI,EAAE,MAAM,EACZ,EACC,aAAoB,EACpB,UAA6C,EAC7C,QAAgB,GAChB,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACzE,OAAO,CAAC,cAAc,CAAC,CA2BzB;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,YAAY,GAAG,cAAc,CAW/E"}
1
+ {"version":3,"file":"node-sqlite.d.ts","sourceRoot":"","sources":["../../../src/core/storage/node-sqlite.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EACX,cAAc,EAMd,MAAM,eAAe,CAAC;AAsuBvB,wBAAsB,sBAAsB,CAC3C,IAAI,EAAE,MAAM,EACZ,EACC,aAAoB,EACpB,UAA6C,EAC7C,QAAgB,GAChB,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACzE,OAAO,CAAC,cAAc,CAAC,CA2BzB;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,YAAY,GAAG,cAAc,CAW/E"}