@powerhousedao/reactor 6.2.3-dev.10 → 6.2.3-dev.12

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.
@@ -1268,6 +1268,18 @@ var DocumentMetaCache = class DocumentMetaCache {
1268
1268
  };
1269
1269
  }
1270
1270
  };
1271
+ /** Bind slots per statement: 16-bit on the wire, read signed in-process. */
1272
+ const MAX_BIND_PARAMETERS = 32767;
1273
+ /** Splits rows into runs that each bind at most MAX_BIND_PARAMETERS. */
1274
+ function chunkRows(rows) {
1275
+ if (rows.length === 0) return [];
1276
+ const columnsPerRow = Math.max(1, Object.keys(rows[0]).length);
1277
+ const perChunk = Math.max(1, Math.floor(MAX_BIND_PARAMETERS / columnsPerRow));
1278
+ if (rows.length <= perChunk) return [rows];
1279
+ const chunks = [];
1280
+ for (let i = 0; i < rows.length; i += perChunk) chunks.push(rows.slice(i, i + perChunk));
1281
+ return chunks;
1282
+ }
1271
1283
  var KyselyOperationIndexTxn = class {
1272
1284
  collections = [];
1273
1285
  collectionMemberships = [];
@@ -1389,7 +1401,7 @@ var KyselyOperationIndex = class KyselyOperationIndex {
1389
1401
  leftOrdinal: null
1390
1402
  }));
1391
1403
  for (const collectionId of collections) kyselyTxn.recordMembershipInvalidation(collectionId);
1392
- await trx.insertInto("document_collections").values(collectionRows).onConflict((oc) => oc.doNothing()).execute();
1404
+ for (const chunk of chunkRows(collectionRows)) await trx.insertInto("document_collections").values(chunk).onConflict((oc) => oc.doNothing()).execute();
1393
1405
  }
1394
1406
  let operationOrdinals = [];
1395
1407
  if (operations.length > 0) {
@@ -1407,7 +1419,10 @@ var KyselyOperationIndex = class KyselyOperationIndex {
1407
1419
  deniedReason: op.deniedReason ?? null,
1408
1420
  sourceRemote: op.sourceRemote
1409
1421
  }));
1410
- operationOrdinals = (await trx.insertInto("operation_index_operations").values(operationRows).returning("ordinal").execute()).map((row) => row.ordinal);
1422
+ for (const chunk of chunkRows(operationRows)) {
1423
+ const insertedOps = await trx.insertInto("operation_index_operations").values(chunk).returning("ordinal").execute();
1424
+ operationOrdinals = operationOrdinals.concat(insertedOps.map((row) => row.ordinal));
1425
+ }
1411
1426
  }
1412
1427
  if (memberships.length > 0) for (const m of memberships) {
1413
1428
  const ordinal = operationOrdinals[m.operationIndex];
@@ -4847,6 +4862,14 @@ var KyselyOperationStore = class KyselyOperationStore {
4847
4862
  }
4848
4863
  return false;
4849
4864
  }
4865
+ /**
4866
+ * The paging cursor here encodes the index to resume from (one past the
4867
+ * last row returned), not the last row's own index. This keeps "0" an
4868
+ * unambiguous start-of-stream sentinel even when a page ends at index 0
4869
+ * (e.g. `limit: 1` on a fresh stream), which would otherwise make
4870
+ * `nextCursor` equal the start cursor and loop a caller that walks pages
4871
+ * forever.
4872
+ */
4850
4873
  async getSince(documentId, scope, branch, revision, filter, paging, signal) {
4851
4874
  throwIfAborted(signal);
4852
4875
  let query = this.queryExecutor.selectFrom("Operation").selectAll().where("documentId", "=", documentId).where("scope", "=", scope).where("branch", "=", branch).where("index", ">", revision).orderBy("index", "asc");
@@ -4861,10 +4884,10 @@ var KyselyOperationStore = class KyselyOperationStore {
4861
4884
  }
4862
4885
  if (paging) {
4863
4886
  const cursorValue = Number.parseInt(paging.cursor, 10);
4864
- if (cursorValue > 0) query = query.where("index", ">", cursorValue);
4887
+ if (Number.isFinite(cursorValue) && cursorValue > 0) query = query.where("index", ">=", cursorValue);
4865
4888
  if (paging.limit) query = query.limit(paging.limit + 1);
4866
4889
  }
4867
- return paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getSince(documentId, scope, branch, revision, filter, {
4890
+ return paginateRows(await query.execute(), paging, (row) => row.index + 1, (row) => this.rowToOperation(row), (cursor, limit) => this.getSince(documentId, scope, branch, revision, filter, {
4868
4891
  cursor,
4869
4892
  limit
4870
4893
  }, signal));
@@ -4882,26 +4905,28 @@ var KyselyOperationStore = class KyselyOperationStore {
4882
4905
  limit
4883
4906
  }, signal));
4884
4907
  }
4908
+ /**
4909
+ * The paging cursor here encodes the index to resume from (one past the
4910
+ * last row returned), not the last row's own index, for the same reason as
4911
+ * `getSince`: a page ending at index 0 must not produce a cursor that is
4912
+ * indistinguishable from the start-of-stream sentinel.
4913
+ */
4885
4914
  async getConflicting(documentId, scope, branch, minTimestamp, paging, signal) {
4886
4915
  throwIfAborted(signal);
4887
4916
  let query = this.queryExecutor.selectFrom("Operation").selectAll().where("documentId", "=", documentId).where("scope", "=", scope).where("branch", "=", branch).where("timestampUtcMs", ">=", new Date(minTimestamp)).orderBy("index", "asc");
4888
4917
  if (paging) {
4889
4918
  const cursorValue = Number.parseInt(paging.cursor, 10);
4890
- if (cursorValue > 0) query = query.where("index", ">", cursorValue);
4919
+ if (Number.isFinite(cursorValue) && cursorValue > 0) query = query.where("index", ">=", cursorValue);
4891
4920
  if (paging.limit) query = query.limit(paging.limit + 1);
4892
4921
  }
4893
- return paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getConflicting(documentId, scope, branch, minTimestamp, {
4922
+ return paginateRows(await query.execute(), paging, (row) => row.index + 1, (row) => this.rowToOperation(row), (cursor, limit) => this.getConflicting(documentId, scope, branch, minTimestamp, {
4894
4923
  cursor,
4895
4924
  limit
4896
4925
  }, signal));
4897
4926
  }
4898
4927
  async getRevisions(documentId, branch, signal) {
4899
4928
  throwIfAborted(signal);
4900
- const scopeRevisions = await this.queryExecutor.selectFrom("Operation as o1").select([
4901
- "o1.scope",
4902
- "o1.index",
4903
- "o1.timestampUtcMs"
4904
- ]).where("o1.documentId", "=", documentId).where("o1.branch", "=", branch).where((eb) => eb("o1.index", "=", eb.selectFrom("Operation as o2").select((eb2) => eb2.fn.max("o2.index").as("maxIndex")).where("o2.documentId", "=", eb.ref("o1.documentId")).where("o2.branch", "=", eb.ref("o1.branch")).where("o2.scope", "=", eb.ref("o1.scope")))).execute();
4929
+ const scopeRevisions = await this.queryExecutor.selectFrom("Operation").select("scope").select((eb) => eb.fn.max("index").as("index")).where("documentId", "=", documentId).where("branch", "=", branch).groupBy("scope").execute();
4905
4930
  const latest = await this.queryExecutor.selectFrom("Operation").select((eb) => eb.fn.max("timestampUtcMs").as("latestTimestamp")).where("documentId", "=", documentId).where("branch", "=", branch).executeTakeFirst();
4906
4931
  const revision = {};
4907
4932
  for (const row of scopeRevisions) revision[row.scope] = row.index + 1;
@@ -5007,8 +5032,8 @@ function createForwardingPoolInstrumentation(name) {
5007
5032
  }
5008
5033
  //#endregion
5009
5034
  //#region src/storage/migrations/001_create_operation_table.ts
5010
- var _001_create_operation_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$18 });
5011
- async function up$18(db) {
5035
+ var _001_create_operation_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$19 });
5036
+ async function up$19(db) {
5012
5037
  await db.schema.createTable("Operation").addColumn("id", "serial", (col) => col.primaryKey()).addColumn("jobId", "text", (col) => col.notNull()).addColumn("opId", "text", (col) => col.notNull()).addColumn("prevOpId", "text", (col) => col.notNull()).addColumn("writeTimestampUtcMs", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("documentId", "text", (col) => col.notNull()).addColumn("documentType", "text", (col) => col.notNull()).addColumn("scope", "text", (col) => col.notNull()).addColumn("branch", "text", (col) => col.notNull()).addColumn("timestampUtcMs", "timestamptz", (col) => col.notNull()).addColumn("index", "integer", (col) => col.notNull()).addColumn("action", "jsonb", (col) => col.notNull()).addColumn("skip", "integer", (col) => col.notNull()).addColumn("error", "text").addColumn("hash", "text", (col) => col.notNull()).addUniqueConstraint("unique_revision", [
5013
5038
  "documentId",
5014
5039
  "scope",
@@ -5033,8 +5058,8 @@ async function up$18(db) {
5033
5058
  }
5034
5059
  //#endregion
5035
5060
  //#region src/storage/migrations/002_create_keyframe_table.ts
5036
- var _002_create_keyframe_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$17 });
5037
- async function up$17(db) {
5061
+ var _002_create_keyframe_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$18 });
5062
+ async function up$18(db) {
5038
5063
  await db.schema.createTable("Keyframe").addColumn("id", "serial", (col) => col.primaryKey()).addColumn("documentId", "text", (col) => col.notNull()).addColumn("documentType", "text", (col) => col.notNull()).addColumn("scope", "text", (col) => col.notNull()).addColumn("branch", "text", (col) => col.notNull()).addColumn("revision", "integer", (col) => col.notNull()).addColumn("document", "jsonb", (col) => col.notNull()).addColumn("createdAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint("unique_keyframe", [
5039
5064
  "documentId",
5040
5065
  "scope",
@@ -5050,14 +5075,14 @@ async function up$17(db) {
5050
5075
  }
5051
5076
  //#endregion
5052
5077
  //#region src/storage/migrations/003_create_document_table.ts
5053
- var _003_create_document_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$16 });
5054
- async function up$16(db) {
5078
+ var _003_create_document_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$17 });
5079
+ async function up$17(db) {
5055
5080
  await db.schema.createTable("Document").addColumn("id", "text", (col) => col.primaryKey()).addColumn("createdAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("updatedAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
5056
5081
  }
5057
5082
  //#endregion
5058
5083
  //#region src/storage/migrations/004_create_document_relationship_table.ts
5059
- var _004_create_document_relationship_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$15 });
5060
- async function up$15(db) {
5084
+ var _004_create_document_relationship_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$16 });
5085
+ async function up$16(db) {
5061
5086
  await db.schema.createTable("DocumentRelationship").addColumn("id", "text", (col) => col.primaryKey()).addColumn("sourceId", "text", (col) => col.notNull().references("Document.id").onDelete("cascade")).addColumn("targetId", "text", (col) => col.notNull().references("Document.id").onDelete("cascade")).addColumn("relationshipType", "text", (col) => col.notNull()).addColumn("metadata", "jsonb").addColumn("createdAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("updatedAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint("unique_source_target_type", [
5062
5087
  "sourceId",
5063
5088
  "targetId",
@@ -5069,14 +5094,14 @@ async function up$15(db) {
5069
5094
  }
5070
5095
  //#endregion
5071
5096
  //#region src/storage/migrations/005_create_indexer_state_table.ts
5072
- var _005_create_indexer_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$14 });
5073
- async function up$14(db) {
5097
+ var _005_create_indexer_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$15 });
5098
+ async function up$15(db) {
5074
5099
  await db.schema.createTable("IndexerState").addColumn("id", "integer", (col) => col.primaryKey().generatedAlwaysAsIdentity()).addColumn("lastOperationId", "integer", (col) => col.notNull()).addColumn("lastOperationTimestamp", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
5075
5100
  }
5076
5101
  //#endregion
5077
5102
  //#region src/storage/migrations/006_create_document_snapshot_table.ts
5078
- var _006_create_document_snapshot_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$13 });
5079
- async function up$13(db) {
5103
+ var _006_create_document_snapshot_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$14 });
5104
+ async function up$14(db) {
5080
5105
  await db.schema.createTable("DocumentSnapshot").addColumn("id", "text", (col) => col.primaryKey()).addColumn("documentId", "text", (col) => col.notNull()).addColumn("slug", "text").addColumn("name", "text").addColumn("scope", "text", (col) => col.notNull()).addColumn("branch", "text", (col) => col.notNull()).addColumn("content", "jsonb", (col) => col.notNull()).addColumn("documentType", "text", (col) => col.notNull()).addColumn("lastOperationIndex", "integer", (col) => col.notNull()).addColumn("lastOperationHash", "text", (col) => col.notNull()).addColumn("lastUpdatedAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("snapshotVersion", "integer", (col) => col.notNull().defaultTo(1)).addColumn("identifiers", "jsonb").addColumn("metadata", "jsonb").addColumn("isDeleted", "boolean", (col) => col.notNull().defaultTo(false)).addColumn("deletedAt", "timestamptz").addUniqueConstraint("unique_doc_scope_branch", [
5081
5106
  "documentId",
5082
5107
  "scope",
@@ -5097,8 +5122,8 @@ async function up$13(db) {
5097
5122
  }
5098
5123
  //#endregion
5099
5124
  //#region src/storage/migrations/007_create_slug_mapping_table.ts
5100
- var _007_create_slug_mapping_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$12 });
5101
- async function up$12(db) {
5125
+ var _007_create_slug_mapping_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$13 });
5126
+ async function up$13(db) {
5102
5127
  await db.schema.createTable("SlugMapping").addColumn("slug", "text", (col) => col.primaryKey()).addColumn("documentId", "text", (col) => col.notNull()).addColumn("scope", "text", (col) => col.notNull()).addColumn("branch", "text", (col) => col.notNull()).addColumn("createdAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("updatedAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint("unique_docid_scope_branch", [
5103
5128
  "documentId",
5104
5129
  "scope",
@@ -5108,14 +5133,14 @@ async function up$12(db) {
5108
5133
  }
5109
5134
  //#endregion
5110
5135
  //#region src/storage/migrations/008_create_view_state_table.ts
5111
- var _008_create_view_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$11 });
5112
- async function up$11(db) {
5136
+ var _008_create_view_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$12 });
5137
+ async function up$12(db) {
5113
5138
  await db.schema.createTable("ViewState").addColumn("readModelId", "text", (col) => col.primaryKey()).addColumn("lastOrdinal", "integer", (col) => col.notNull().defaultTo(0)).addColumn("lastOperationTimestamp", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
5114
5139
  }
5115
5140
  //#endregion
5116
5141
  //#region src/storage/migrations/009_create_operation_index_tables.ts
5117
- var _009_create_operation_index_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$10 });
5118
- async function up$10(db) {
5142
+ var _009_create_operation_index_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$11 });
5143
+ async function up$11(db) {
5119
5144
  await db.schema.createTable("document_collections").addColumn("documentId", "text", (col) => col.notNull()).addColumn("collectionId", "text", (col) => col.notNull()).addColumn("joinedOrdinal", "bigint", (col) => col.notNull().defaultTo(0)).addColumn("leftOrdinal", "bigint").addPrimaryKeyConstraint("document_collections_pkey", ["documentId", "collectionId"]).execute();
5120
5145
  await db.schema.createIndex("idx_document_collections_collectionId").on("document_collections").column("collectionId").execute();
5121
5146
  await db.schema.createIndex("idx_doc_collections_collection_range").on("document_collections").columns(["collectionId", "joinedOrdinal"]).execute();
@@ -5129,8 +5154,8 @@ async function up$10(db) {
5129
5154
  }
5130
5155
  //#endregion
5131
5156
  //#region src/storage/migrations/010_create_sync_tables.ts
5132
- var _010_create_sync_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$9 });
5133
- async function up$9(db) {
5157
+ var _010_create_sync_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$10 });
5158
+ async function up$10(db) {
5134
5159
  await db.schema.createTable("sync_remotes").addColumn("name", "text", (col) => col.primaryKey()).addColumn("collection_id", "text", (col) => col.notNull()).addColumn("channel_type", "text", (col) => col.notNull()).addColumn("channel_id", "text", (col) => col.notNull().defaultTo("")).addColumn("remote_name", "text", (col) => col.notNull().defaultTo("")).addColumn("channel_parameters", "jsonb", (col) => col.notNull().defaultTo(sql`'{}'::jsonb`)).addColumn("filter_document_ids", "jsonb").addColumn("filter_scopes", "jsonb").addColumn("filter_branch", "text", (col) => col.notNull().defaultTo("main")).addColumn("push_state", "text", (col) => col.notNull().defaultTo("idle")).addColumn("push_last_success_utc_ms", "text").addColumn("push_last_failure_utc_ms", "text").addColumn("push_failure_count", "integer", (col) => col.notNull().defaultTo(0)).addColumn("pull_state", "text", (col) => col.notNull().defaultTo("idle")).addColumn("pull_last_success_utc_ms", "text").addColumn("pull_last_failure_utc_ms", "text").addColumn("pull_failure_count", "integer", (col) => col.notNull().defaultTo(0)).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
5135
5160
  await db.schema.createIndex("idx_sync_remotes_collection").on("sync_remotes").column("collection_id").execute();
5136
5161
  await db.schema.createTable("sync_cursors").addColumn("remote_name", "text", (col) => col.primaryKey().references("sync_remotes.name").onDelete("cascade")).addColumn("cursor_ordinal", "bigint", (col) => col.notNull().defaultTo(0)).addColumn("last_synced_at_utc_ms", "text").addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
@@ -5138,8 +5163,8 @@ async function up$9(db) {
5138
5163
  }
5139
5164
  //#endregion
5140
5165
  //#region src/storage/migrations/011_add_cursor_type_column.ts
5141
- var _011_add_cursor_type_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$8 });
5142
- async function up$8(db) {
5166
+ var _011_add_cursor_type_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$9 });
5167
+ async function up$9(db) {
5143
5168
  await db.deleteFrom("sync_cursors").where("remote_name", "like", "outbox::%").execute();
5144
5169
  await db.deleteFrom("sync_remotes").where("name", "like", "outbox::%").execute();
5145
5170
  await db.schema.dropTable("sync_cursors").execute();
@@ -5148,64 +5173,64 @@ async function up$8(db) {
5148
5173
  }
5149
5174
  //#endregion
5150
5175
  //#region src/storage/migrations/012_add_source_remote_column.ts
5151
- var _012_add_source_remote_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$7 });
5152
- async function up$7(db) {
5176
+ var _012_add_source_remote_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$8 });
5177
+ async function up$8(db) {
5153
5178
  await db.schema.alterTable("operation_index_operations").addColumn("sourceRemote", "text", (col) => col.notNull().defaultTo("")).execute();
5154
5179
  }
5155
5180
  //#endregion
5156
5181
  //#region src/storage/migrations/013_create_sync_dead_letters_table.ts
5157
- var _013_create_sync_dead_letters_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$6 });
5158
- async function up$6(db) {
5182
+ var _013_create_sync_dead_letters_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$7 });
5183
+ async function up$7(db) {
5159
5184
  await db.schema.createTable("sync_dead_letters").addColumn("ordinal", "serial", (col) => col.primaryKey()).addColumn("id", "text", (col) => col.unique().notNull()).addColumn("job_id", "text", (col) => col.notNull()).addColumn("job_dependencies", "jsonb", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn("remote_name", "text", (col) => col.notNull().references("sync_remotes.name").onDelete("cascade")).addColumn("document_id", "text", (col) => col.notNull()).addColumn("scopes", "jsonb", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn("branch", "text", (col) => col.notNull()).addColumn("operations", "jsonb", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn("error_source", "text", (col) => col.notNull()).addColumn("error_message", "text", (col) => col.notNull()).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
5160
5185
  await db.schema.createIndex("idx_sync_dead_letters_remote").on("sync_dead_letters").column("remote_name").execute();
5161
5186
  }
5162
5187
  //#endregion
5163
5188
  //#region src/storage/migrations/014_create_processor_cursor_table.ts
5164
- var _014_create_processor_cursor_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$5 });
5165
- async function up$5(db) {
5189
+ var _014_create_processor_cursor_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$6 });
5190
+ async function up$6(db) {
5166
5191
  await db.schema.createTable("ProcessorCursor").addColumn("processorId", "text", (col) => col.primaryKey()).addColumn("factoryId", "text", (col) => col.notNull()).addColumn("driveId", "text", (col) => col.notNull()).addColumn("processorIndex", "integer", (col) => col.notNull()).addColumn("lastOrdinal", "integer", (col) => col.notNull().defaultTo(sql`0`)).addColumn("status", "text", (col) => col.notNull().defaultTo(sql`'active'`)).addColumn("lastError", "text").addColumn("lastErrorTimestamp", "timestamptz").addColumn("createdAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn("updatedAt", "timestamptz", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();
5167
5192
  }
5168
5193
  //#endregion
5169
5194
  //#region src/storage/migrations/015_add_operation_denied_reason.ts
5170
5195
  var _015_add_operation_denied_reason_exports = /* @__PURE__ */ __exportAll({
5171
- down: () => down$4,
5172
- up: () => up$4
5196
+ down: () => down$5,
5197
+ up: () => up$5
5173
5198
  });
5174
5199
  /**
5175
5200
  * Records why authorization refused an operation. Separate from `error` so a
5176
5201
  * denial is distinguishable from a reducer failure without matching on a
5177
5202
  * message. Null for every operation written before decisions were enforced.
5178
5203
  */
5179
- async function up$4(db) {
5204
+ async function up$5(db) {
5180
5205
  await db.schema.alterTable("Operation").addColumn("deniedReason", "text").execute();
5181
5206
  await db.schema.alterTable("operation_index_operations").addColumn("deniedReason", "text").execute();
5182
5207
  }
5183
- async function down$4(db) {
5208
+ async function down$5(db) {
5184
5209
  await db.schema.alterTable("operation_index_operations").dropColumn("deniedReason").execute();
5185
5210
  await db.schema.alterTable("Operation").dropColumn("deniedReason").execute();
5186
5211
  }
5187
5212
  //#endregion
5188
5213
  //#region src/storage/migrations/016_add_dead_letter_error_type.ts
5189
5214
  var _016_add_dead_letter_error_type_exports = /* @__PURE__ */ __exportAll({
5190
- down: () => down$3,
5191
- up: () => up$3
5215
+ down: () => down$4,
5216
+ up: () => up$4
5192
5217
  });
5193
5218
  /**
5194
5219
  * The classification a dead letter falls into, stored because it decides whether
5195
5220
  * the document stays quarantined and the in-memory error is gone after a restart.
5196
5221
  * Defaulted rather than nullable, so a pre-existing row rehydrates.
5197
5222
  */
5198
- async function up$3(db) {
5223
+ async function up$4(db) {
5199
5224
  await db.schema.alterTable("sync_dead_letters").addColumn("error_type", "text", (col) => col.notNull().defaultTo("UNCLASSIFIED")).execute();
5200
5225
  }
5201
- async function down$3(db) {
5226
+ async function down$4(db) {
5202
5227
  await db.schema.alterTable("sync_dead_letters").dropColumn("error_type").execute();
5203
5228
  }
5204
5229
  //#endregion
5205
5230
  //#region src/storage/migrations/017_create_group_references.ts
5206
5231
  var _017_create_group_references_exports = /* @__PURE__ */ __exportAll({
5207
- down: () => down$2,
5208
- up: () => up$2
5232
+ down: () => down$3,
5233
+ up: () => up$3
5209
5234
  });
5210
5235
  /**
5211
5236
  * One row per (document, group) reference ever discovered from an auth
@@ -5216,18 +5241,18 @@ var _017_create_group_references_exports = /* @__PURE__ */ __exportAll({
5216
5241
  * requires (sync), and by groupId for the documents a group change affects
5217
5242
  * (re-evaluation).
5218
5243
  */
5219
- async function up$2(db) {
5244
+ async function up$3(db) {
5220
5245
  await db.schema.createTable("group_references").addColumn("documentId", "text", (col) => col.notNull()).addColumn("groupId", "text", (col) => col.notNull()).addPrimaryKeyConstraint("group_references_pkey", ["documentId", "groupId"]).execute();
5221
5246
  await db.schema.createIndex("idx_group_references_groupId").on("group_references").column("groupId").execute();
5222
5247
  }
5223
- async function down$2(db) {
5248
+ async function down$3(db) {
5224
5249
  await db.schema.dropTable("group_references").execute();
5225
5250
  }
5226
5251
  //#endregion
5227
5252
  //#region src/storage/migrations/018_add_sync_remote_bound_address.ts
5228
5253
  var _018_add_sync_remote_bound_address_exports = /* @__PURE__ */ __exportAll({
5229
- down: () => down$1,
5230
- up: () => up$1
5254
+ down: () => down$2,
5255
+ up: () => up$2
5231
5256
  });
5232
5257
  /**
5233
5258
  * The address a sync channel is bound to, so a channel created by one subject
@@ -5238,17 +5263,17 @@ var _018_add_sync_remote_bound_address_exports = /* @__PURE__ */ __exportAll({
5238
5263
  * until its first authenticated poll adopts it. A default would claim them all
5239
5264
  * for one address.
5240
5265
  */
5241
- async function up$1(db) {
5266
+ async function up$2(db) {
5242
5267
  await db.schema.alterTable("sync_remotes").addColumn("bound_address", "text").execute();
5243
5268
  }
5244
- async function down$1(db) {
5269
+ async function down$2(db) {
5245
5270
  await db.schema.alterTable("sync_remotes").dropColumn("bound_address").execute();
5246
5271
  }
5247
5272
  //#endregion
5248
5273
  //#region src/storage/migrations/019_require_action_id.ts
5249
5274
  var _019_require_action_id_exports = /* @__PURE__ */ __exportAll({
5250
- down: () => down,
5251
- up: () => up
5275
+ down: () => down$1,
5276
+ up: () => up$1
5252
5277
  });
5253
5278
  /**
5254
5279
  * Makes an operation whose action carries no id physically unstorable.
@@ -5275,7 +5300,7 @@ var _019_require_action_id_exports = /* @__PURE__ */ __exportAll({
5275
5300
  * The empty string is rejected alongside null. It derives the same colliding
5276
5301
  * operation id as an absent id, so admitting it would leave the hole open.
5277
5302
  */
5278
- async function up(db) {
5303
+ async function up$1(db) {
5279
5304
  await db.updateTable("Operation").set({ action: sql`jsonb_set(action, '{id}', to_jsonb(gen_random_uuid()::text))` }).where(sql`jsonb_typeof(action) = 'object' and coalesce(action->>'id', '') = ''`).execute();
5280
5305
  await db.updateTable("operation_index_operations as oio").from("Operation as op").set({ action: sql`jsonb_set(oio.action, '{id}', to_jsonb(op.action->>'id'))` }).whereRef("oio.opId", "=", "op.opId").whereRef("oio.index", "=", "op.index").whereRef("oio.skip", "=", "op.skip").where(sql`jsonb_typeof(oio.action) = 'object' and coalesce(oio.action->>'id', '') = ''`).where(sql`coalesce(op.action->>'id', '') <> ''`).execute();
5281
5306
  await db.updateTable("operation_index_operations").set({ action: sql`jsonb_set(action, '{id}', to_jsonb(gen_random_uuid()::text))` }).where(sql`jsonb_typeof(action) = 'object' and coalesce(action->>'id', '') = ''`).execute();
@@ -5287,11 +5312,24 @@ async function up(db) {
5287
5312
  * their operations are now known by, and reverting them would reintroduce the
5288
5313
  * collision the migration removed.
5289
5314
  */
5290
- async function down(db) {
5315
+ async function down$1(db) {
5291
5316
  await db.schema.alterTable("operation_index_operations").dropConstraint("action_must_have_id").execute();
5292
5317
  await db.schema.alterTable("Operation").dropConstraint("action_must_have_id").execute();
5293
5318
  }
5294
5319
  //#endregion
5320
+ //#region src/storage/migrations/020_add_snapshot_operation_ordinal.ts
5321
+ var _020_add_snapshot_operation_ordinal_exports = /* @__PURE__ */ __exportAll({
5322
+ down: () => down,
5323
+ up: () => up
5324
+ });
5325
+ /** Orders header row writes across scopes; `lastOperationIndex` is per scope. */
5326
+ async function up(db) {
5327
+ await db.schema.alterTable("DocumentSnapshot").addColumn("lastOperationOrdinal", "integer", (col) => col.notNull().defaultTo(0)).execute();
5328
+ }
5329
+ async function down(db) {
5330
+ await db.schema.alterTable("DocumentSnapshot").dropColumn("lastOperationOrdinal").execute();
5331
+ }
5332
+ //#endregion
5295
5333
  //#region src/storage/migrations/migrator.ts
5296
5334
  const REACTOR_SCHEMA = "reactor";
5297
5335
  const migrations = {
@@ -5313,7 +5351,8 @@ const migrations = {
5313
5351
  "016_add_dead_letter_error_type": _016_add_dead_letter_error_type_exports,
5314
5352
  "017_create_group_references": _017_create_group_references_exports,
5315
5353
  "018_add_sync_remote_bound_address": _018_add_sync_remote_bound_address_exports,
5316
- "019_require_action_id": _019_require_action_id_exports
5354
+ "019_require_action_id": _019_require_action_id_exports,
5355
+ "020_add_snapshot_operation_ordinal": _020_add_snapshot_operation_ordinal_exports
5317
5356
  };
5318
5357
  var ProgrammaticMigrationProvider = class {
5319
5358
  getMigrations() {
@@ -5373,6 +5412,6 @@ async function getMigrationStatus(db, schema = REACTOR_SCHEMA) {
5373
5412
  //#region src/core/drive-container-types.ts
5374
5413
  const DEFAULT_DRIVE_CONTAINER_TYPES = new Set(["powerhouse/document-drive", "powerhouse/reactor-drive"]);
5375
5414
  //#endregion
5376
- export { parsePagingOptions as $, targetDocumentId as A, DuplicateOperationError as B, InvalidModuleError as C, createEmptyConsistencyToken as D, createConsistencyToken as E, buildDecisionModel as F, AuthorizationDeniedError as G, RevisionMismatchError as H, APPEND_CONDITION_FAILED_PREFIX as I, ExcessiveReshuffleError as J, DocumentDeletedError as K, AppendConditionFailedError as L, selectDecisionModel as M, documentDecisionModel as N, submittedActionIds as O, authDecisionModel as P, matchesScope as Q, DocumentAlreadyExistsError as R, DuplicateModuleError as S, GATED_DOCUMENT_ACTIONS as T, AuthEnforcementDisabledError as U, OptimisticLockError as V, AuthTimestampNotMonotonicError as W, RelationshipNotFoundError as X, InvalidOperationTimestampError as Y, UpgradePreconditionFailedError as Z, DocumentMetaCache as _, createForwardingPoolInstrumentation as a, JobExecutorEventTypes as b, KyselyKeyframeStore as c, DriveCollectionId as d, throwIfAborted as et, KyselyExecutionScope as f, KyselyOperationIndex as g, KyselyWriteCache as h, runMigrations as i, decideAtHead as j, summarizeSubmittedActions as k, DocumentModelRegistry as l, EventBus as m, REACTOR_SCHEMA as n, instrumentPgPool as o, resolveFeatureFlags as p, DocumentNotFoundError as q, getMigrationStatus as r, KyselyOperationStore as s, DEFAULT_DRIVE_CONTAINER_TYPES as t, __exportAll as tt, SimpleJobExecutor as u, CollectionMembershipCache as v, ModuleNotFoundError as w, DuplicateManifestError as x, DEFAULT_DEFERRED_JOB_TTL_MS as y, DocumentExistence as z };
5415
+ export { parsePagingOptions as $, targetDocumentId as A, DuplicateOperationError as B, InvalidModuleError as C, createEmptyConsistencyToken as D, createConsistencyToken as E, buildDecisionModel as F, AuthorizationDeniedError as G, RevisionMismatchError as H, APPEND_CONDITION_FAILED_PREFIX as I, ExcessiveReshuffleError as J, DocumentDeletedError as K, AppendConditionFailedError as L, selectDecisionModel as M, documentDecisionModel as N, submittedActionIds as O, authDecisionModel as P, matchesScope as Q, DocumentAlreadyExistsError as R, DuplicateModuleError as S, GATED_DOCUMENT_ACTIONS as T, AuthEnforcementDisabledError as U, OptimisticLockError as V, AuthTimestampNotMonotonicError as W, RelationshipNotFoundError as X, InvalidOperationTimestampError as Y, UpgradePreconditionFailedError as Z, DocumentMetaCache as _, createForwardingPoolInstrumentation as a, JobExecutorEventTypes as b, KyselyKeyframeStore as c, DriveCollectionId as d, throwIfAborted as et, KyselyExecutionScope as f, KyselyOperationIndex as g, KyselyWriteCache as h, runMigrations as i, decideAtHead as j, summarizeSubmittedActions as k, DocumentModelRegistry as l, EventBus as m, REACTOR_SCHEMA as n, __exportAll as nt, instrumentPgPool as o, resolveFeatureFlags as p, DocumentNotFoundError as q, getMigrationStatus as r, KyselyOperationStore as s, DEFAULT_DRIVE_CONTAINER_TYPES as t, yieldToMain as tt, SimpleJobExecutor as u, CollectionMembershipCache as v, ModuleNotFoundError as w, DuplicateManifestError as x, DEFAULT_DEFERRED_JOB_TTL_MS as y, DocumentExistence as z };
5377
5416
 
5378
- //# sourceMappingURL=drive-container-types-CE7dxz0_.js.map
5417
+ //# sourceMappingURL=drive-container-types-CS5IxDiA.js.map