@stigmer/server 3.25.0 → 3.27.0

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 (254) hide show
  1. package/dist/authorization/evaluator.d.ts +4 -1
  2. package/dist/authorization/evaluator.d.ts.map +1 -1
  3. package/dist/authorization/evaluator.js +8 -0
  4. package/dist/authorization/evaluator.js.map +1 -1
  5. package/dist/authorization/model/agent.d.ts.map +1 -1
  6. package/dist/authorization/model/agent.js +4 -2
  7. package/dist/authorization/model/agent.js.map +1 -1
  8. package/dist/authorization/model/agent_channel.d.ts.map +1 -1
  9. package/dist/authorization/model/agent_channel.js +5 -4
  10. package/dist/authorization/model/agent_channel.js.map +1 -1
  11. package/dist/authorization/model/agent_instance.d.ts.map +1 -1
  12. package/dist/authorization/model/agent_instance.js +3 -2
  13. package/dist/authorization/model/agent_instance.js.map +1 -1
  14. package/dist/authorization/model/mcp_server.d.ts.map +1 -1
  15. package/dist/authorization/model/mcp_server.js +3 -2
  16. package/dist/authorization/model/mcp_server.js.map +1 -1
  17. package/dist/authorization/model/organization.d.ts.map +1 -1
  18. package/dist/authorization/model/organization.js +3 -0
  19. package/dist/authorization/model/organization.js.map +1 -1
  20. package/dist/authorization/model/plugin.d.ts.map +1 -1
  21. package/dist/authorization/model/plugin.js +4 -2
  22. package/dist/authorization/model/plugin.js.map +1 -1
  23. package/dist/authorization/model/rewrite.d.ts +25 -7
  24. package/dist/authorization/model/rewrite.d.ts.map +1 -1
  25. package/dist/authorization/model/rewrite.js +40 -1
  26. package/dist/authorization/model/rewrite.js.map +1 -1
  27. package/dist/authorization/model/schedule.d.ts.map +1 -1
  28. package/dist/authorization/model/schedule.js +8 -3
  29. package/dist/authorization/model/schedule.js.map +1 -1
  30. package/dist/authorization/model/skill.d.ts.map +1 -1
  31. package/dist/authorization/model/skill.js +3 -2
  32. package/dist/authorization/model/skill.js.map +1 -1
  33. package/dist/authorization/model/workflow.d.ts.map +1 -1
  34. package/dist/authorization/model/workflow.js +3 -2
  35. package/dist/authorization/model/workflow.js.map +1 -1
  36. package/dist/authorization/model/workflow_execution.d.ts.map +1 -1
  37. package/dist/authorization/model/workflow_execution.js +4 -3
  38. package/dist/authorization/model/workflow_execution.js.map +1 -1
  39. package/dist/authorization/model/workflow_instance.d.ts.map +1 -1
  40. package/dist/authorization/model/workflow_instance.js +5 -1
  41. package/dist/authorization/model/workflow_instance.js.map +1 -1
  42. package/dist/boot/compose.d.ts.map +1 -1
  43. package/dist/boot/compose.js +13 -8
  44. package/dist/boot/compose.js.map +1 -1
  45. package/dist/boot/list-indexes.d.ts +3 -0
  46. package/dist/boot/list-indexes.d.ts.map +1 -0
  47. package/dist/boot/list-indexes.js +24 -0
  48. package/dist/boot/list-indexes.js.map +1 -0
  49. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  50. package/dist/domain/agentexecution/controller.js +6 -8
  51. package/dist/domain/agentexecution/controller.js.map +1 -1
  52. package/dist/domain/agentexecution/list-index.d.ts +2 -0
  53. package/dist/domain/agentexecution/list-index.d.ts.map +1 -0
  54. package/dist/domain/agentexecution/list-index.js +23 -0
  55. package/dist/domain/agentexecution/list-index.js.map +1 -0
  56. package/dist/domain/agentexecution/steps.d.ts +17 -33
  57. package/dist/domain/agentexecution/steps.d.ts.map +1 -1
  58. package/dist/domain/agentexecution/steps.js +94 -95
  59. package/dist/domain/agentexecution/steps.js.map +1 -1
  60. package/dist/domain/agentexecution/usage.d.ts.map +1 -1
  61. package/dist/domain/agentexecution/usage.js +37 -14
  62. package/dist/domain/agentexecution/usage.js.map +1 -1
  63. package/dist/domain/artifact/controller.d.ts.map +1 -1
  64. package/dist/domain/artifact/controller.js +27 -15
  65. package/dist/domain/artifact/controller.js.map +1 -1
  66. package/dist/domain/artifact/list-index.d.ts +2 -0
  67. package/dist/domain/artifact/list-index.d.ts.map +1 -0
  68. package/dist/domain/artifact/list-index.js +21 -0
  69. package/dist/domain/artifact/list-index.js.map +1 -0
  70. package/dist/domain/iampolicy/access-lists.d.ts +5 -3
  71. package/dist/domain/iampolicy/access-lists.d.ts.map +1 -1
  72. package/dist/domain/iampolicy/access-lists.js +72 -19
  73. package/dist/domain/iampolicy/access-lists.js.map +1 -1
  74. package/dist/domain/iampolicy/constants.d.ts +32 -6
  75. package/dist/domain/iampolicy/constants.d.ts.map +1 -1
  76. package/dist/domain/iampolicy/constants.js +41 -6
  77. package/dist/domain/iampolicy/constants.js.map +1 -1
  78. package/dist/domain/iampolicy/controller.d.ts +6 -0
  79. package/dist/domain/iampolicy/controller.d.ts.map +1 -1
  80. package/dist/domain/iampolicy/controller.js +16 -7
  81. package/dist/domain/iampolicy/controller.js.map +1 -1
  82. package/dist/domain/iampolicy/resource-store.d.ts.map +1 -1
  83. package/dist/domain/iampolicy/resource-store.js +2 -6
  84. package/dist/domain/iampolicy/resource-store.js.map +1 -1
  85. package/dist/domain/iampolicy/steps.d.ts.map +1 -1
  86. package/dist/domain/iampolicy/steps.js +49 -7
  87. package/dist/domain/iampolicy/steps.js.map +1 -1
  88. package/dist/domain/session/list-index.d.ts +4 -0
  89. package/dist/domain/session/list-index.d.ts.map +1 -0
  90. package/dist/domain/session/list-index.js +26 -0
  91. package/dist/domain/session/list-index.js.map +1 -0
  92. package/dist/domain/session/steps.d.ts +7 -8
  93. package/dist/domain/session/steps.d.ts.map +1 -1
  94. package/dist/domain/session/steps.js +76 -78
  95. package/dist/domain/session/steps.js.map +1 -1
  96. package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -0
  97. package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
  98. package/dist/domain/workflowexecution/controller.js +53 -55
  99. package/dist/domain/workflowexecution/controller.js.map +1 -1
  100. package/dist/domain/workflowexecution/execution-filter.d.ts +4 -0
  101. package/dist/domain/workflowexecution/execution-filter.d.ts.map +1 -1
  102. package/dist/domain/workflowexecution/execution-filter.js +11 -5
  103. package/dist/domain/workflowexecution/execution-filter.js.map +1 -1
  104. package/dist/domain/workflowexecution/get-execution-summary.d.ts.map +1 -1
  105. package/dist/domain/workflowexecution/get-execution-summary.js +23 -17
  106. package/dist/domain/workflowexecution/get-execution-summary.js.map +1 -1
  107. package/dist/domain/workflowexecution/list-index.d.ts +2 -0
  108. package/dist/domain/workflowexecution/list-index.d.ts.map +1 -0
  109. package/dist/domain/workflowexecution/list-index.js +21 -0
  110. package/dist/domain/workflowexecution/list-index.js.map +1 -0
  111. package/dist/domain/workflowexecution/list-pending-approvals.d.ts.map +1 -1
  112. package/dist/domain/workflowexecution/list-pending-approvals.js +69 -32
  113. package/dist/domain/workflowexecution/list-pending-approvals.js.map +1 -1
  114. package/dist/domain/workflowexecution/queries.d.ts +30 -4
  115. package/dist/domain/workflowexecution/queries.d.ts.map +1 -1
  116. package/dist/domain/workflowexecution/queries.js +76 -22
  117. package/dist/domain/workflowexecution/queries.js.map +1 -1
  118. package/dist/extensions/drivers.d.ts +12 -0
  119. package/dist/extensions/drivers.d.ts.map +1 -1
  120. package/dist/extensions/gate-slots.d.ts +10 -1
  121. package/dist/extensions/gate-slots.d.ts.map +1 -1
  122. package/dist/extensions/gate-slots.js +1 -0
  123. package/dist/extensions/gate-slots.js.map +1 -1
  124. package/dist/extensions/list-read-scope.d.ts +9 -12
  125. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  126. package/dist/extensions/list-read-scope.js.map +1 -1
  127. package/dist/extensions/principal-display.d.ts +34 -0
  128. package/dist/extensions/principal-display.d.ts.map +1 -0
  129. package/dist/extensions/principal-display.js +2 -0
  130. package/dist/extensions/principal-display.js.map +1 -0
  131. package/dist/extensions/registry.d.ts +6 -0
  132. package/dist/extensions/registry.d.ts.map +1 -1
  133. package/dist/extensions/registry.js +10 -0
  134. package/dist/extensions/registry.js.map +1 -1
  135. package/dist/index.d.ts +4 -2
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +6 -1
  138. package/dist/index.js.map +1 -1
  139. package/dist/pipeline/apiresource-meta.d.ts +10 -0
  140. package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
  141. package/dist/pipeline/apiresource-meta.js +16 -0
  142. package/dist/pipeline/apiresource-meta.js.map +1 -1
  143. package/dist/pipeline/steps/list-page.d.ts +63 -0
  144. package/dist/pipeline/steps/list-page.d.ts.map +1 -0
  145. package/dist/pipeline/steps/list-page.js +187 -0
  146. package/dist/pipeline/steps/list-page.js.map +1 -0
  147. package/dist/query/activity/handler.d.ts +6 -7
  148. package/dist/query/activity/handler.d.ts.map +1 -1
  149. package/dist/query/activity/handler.js +42 -59
  150. package/dist/query/activity/handler.js.map +1 -1
  151. package/dist/store/interface.d.ts +29 -0
  152. package/dist/store/interface.d.ts.map +1 -1
  153. package/dist/store/interface.js.map +1 -1
  154. package/dist/store/list-index.d.ts +123 -0
  155. package/dist/store/list-index.d.ts.map +1 -0
  156. package/dist/store/list-index.js +277 -0
  157. package/dist/store/list-index.js.map +1 -0
  158. package/dist/store/logger.d.ts +3 -0
  159. package/dist/store/logger.d.ts.map +1 -1
  160. package/dist/store/logger.js +5 -1
  161. package/dist/store/logger.js.map +1 -1
  162. package/dist/store/postgres/migrations.d.ts +10 -6
  163. package/dist/store/postgres/migrations.d.ts.map +1 -1
  164. package/dist/store/postgres/migrations.js +64 -6
  165. package/dist/store/postgres/migrations.js.map +1 -1
  166. package/dist/store/postgres/store.d.ts +26 -5
  167. package/dist/store/postgres/store.d.ts.map +1 -1
  168. package/dist/store/postgres/store.js +377 -22
  169. package/dist/store/postgres/store.js.map +1 -1
  170. package/dist/store/sqlite/migrations.d.ts +11 -5
  171. package/dist/store/sqlite/migrations.d.ts.map +1 -1
  172. package/dist/store/sqlite/migrations.js +50 -4
  173. package/dist/store/sqlite/migrations.js.map +1 -1
  174. package/dist/store/sqlite/store.d.ts +18 -3
  175. package/dist/store/sqlite/store.d.ts.map +1 -1
  176. package/dist/store/sqlite/store.js +321 -15
  177. package/dist/store/sqlite/store.js.map +1 -1
  178. package/package.json +6 -6
  179. package/src/authorization/__tests__/drivers.ts +6 -1
  180. package/src/authorization/__tests__/evaluator.test.ts +127 -2
  181. package/src/authorization/evaluator.ts +12 -1
  182. package/src/authorization/model/__tests__/registry.test.ts +64 -2
  183. package/src/authorization/model/agent.ts +4 -1
  184. package/src/authorization/model/agent_channel.ts +11 -3
  185. package/src/authorization/model/agent_instance.ts +3 -1
  186. package/src/authorization/model/mcp_server.ts +3 -1
  187. package/src/authorization/model/organization.ts +3 -0
  188. package/src/authorization/model/plugin.ts +4 -1
  189. package/src/authorization/model/rewrite.ts +65 -8
  190. package/src/authorization/model/schedule.ts +11 -2
  191. package/src/authorization/model/skill.ts +3 -1
  192. package/src/authorization/model/workflow.ts +3 -1
  193. package/src/authorization/model/workflow_execution.ts +4 -2
  194. package/src/authorization/model/workflow_instance.ts +5 -0
  195. package/src/boot/__tests__/list-indexes.test.ts +65 -0
  196. package/src/boot/compose.ts +25 -13
  197. package/src/boot/list-indexes.ts +25 -0
  198. package/src/domain/agentexecution/__tests__/agentexecution.test.ts +85 -3
  199. package/src/domain/agentexecution/controller.ts +8 -10
  200. package/src/domain/agentexecution/list-index.ts +24 -0
  201. package/src/domain/agentexecution/steps.ts +118 -115
  202. package/src/domain/agentexecution/usage.ts +38 -17
  203. package/src/domain/artifact/controller.ts +28 -18
  204. package/src/domain/artifact/list-index.ts +22 -0
  205. package/src/domain/iampolicy/__tests__/access-lists.test.ts +120 -6
  206. package/src/domain/iampolicy/__tests__/constants.test.ts +26 -4
  207. package/src/domain/iampolicy/__tests__/controller.test.ts +55 -1
  208. package/src/domain/iampolicy/__tests__/grant-path.test.ts +3 -3
  209. package/src/domain/iampolicy/__tests__/steps.test.ts +123 -1
  210. package/src/domain/iampolicy/access-lists.ts +98 -23
  211. package/src/domain/iampolicy/constants.ts +50 -6
  212. package/src/domain/iampolicy/controller.ts +30 -7
  213. package/src/domain/iampolicy/resource-store.ts +3 -6
  214. package/src/domain/iampolicy/steps.ts +89 -7
  215. package/src/domain/session/list-index.ts +28 -0
  216. package/src/domain/session/steps.ts +108 -123
  217. package/src/domain/workflow/registry/data/task-kind-registry.json +1 -0
  218. package/src/domain/workflowexecution/__tests__/list-read-scope-summaries.test.ts +155 -99
  219. package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +193 -31
  220. package/src/domain/workflowexecution/controller.ts +54 -82
  221. package/src/domain/workflowexecution/execution-filter.ts +20 -7
  222. package/src/domain/workflowexecution/get-execution-summary.ts +31 -24
  223. package/src/domain/workflowexecution/list-index.ts +22 -0
  224. package/src/domain/workflowexecution/list-pending-approvals.ts +82 -25
  225. package/src/domain/workflowexecution/queries.ts +134 -23
  226. package/src/extensions/__tests__/iam-policy-points.test.ts +30 -0
  227. package/src/extensions/__tests__/registry.test.ts +3 -0
  228. package/src/extensions/drivers.ts +12 -0
  229. package/src/extensions/gate-slots.ts +10 -0
  230. package/src/extensions/list-read-scope.ts +9 -12
  231. package/src/extensions/principal-display.ts +37 -0
  232. package/src/extensions/registry.ts +19 -0
  233. package/src/index.ts +19 -1
  234. package/src/pipeline/apiresource-meta.ts +21 -0
  235. package/src/pipeline/steps/__tests__/list-page.test.ts +186 -0
  236. package/src/pipeline/steps/list-page.ts +284 -0
  237. package/src/query/activity/handler.ts +57 -78
  238. package/src/store/README.md +51 -32
  239. package/src/store/__tests__/list-index.measure.test.ts +293 -0
  240. package/src/store/__tests__/list-index.test.ts +328 -0
  241. package/src/store/__tests__/store-contract.ts +346 -3
  242. package/src/store/interface.ts +39 -0
  243. package/src/store/list-index.ts +465 -0
  244. package/src/store/logger.ts +8 -1
  245. package/src/store/postgres/__tests__/list-index-repair.test.ts +133 -0
  246. package/src/store/postgres/__tests__/migrations.test.ts +27 -19
  247. package/src/store/postgres/__tests__/store-contract.test.ts +50 -3
  248. package/src/store/postgres/migrations.ts +69 -7
  249. package/src/store/postgres/store.ts +485 -29
  250. package/src/store/sqlite/__tests__/migrations.test.ts +51 -7
  251. package/src/store/sqlite/__tests__/store-contract.test.ts +70 -16
  252. package/src/store/sqlite/__tests__/support.ts +12 -3
  253. package/src/store/sqlite/migrations.ts +57 -6
  254. package/src/store/sqlite/store.ts +462 -21
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Versioned schema migrations — ports the inline chain in
3
3
  * backend/libs/go/store/sqlite/store.go (v1–v6, DDL character-faithful),
4
- * adds v7, the OD-3 consolidation (D2 §3), and v8, the by-resource
5
- * oauth_grant index (the channel teardown's query pattern, C3 Stage 6).
4
+ * adds v7, the OD-3 consolidation (D2 §3), v8, the by-resource
5
+ * oauth_grant index (the channel teardown's query pattern, C3 Stage 6),
6
+ * and the later steps each named at its constant below.
6
7
  *
7
8
  * Schema continuity across cutover is the design point: a database the Go
8
9
  * server created at any version migrates forward through the SAME steps Go
@@ -45,10 +46,15 @@ export declare const SCHEMA_VERSION_8 = 8;
45
46
  export declare const SCHEMA_VERSION_9 = 9;
46
47
  /** v10: every row holding the retired public visibility level moved to org. */
47
48
  export declare const SCHEMA_VERSION_10 = 10;
49
+ /** v11: the list index's columns, key table and indexes (DDL only). */
50
+ export declare const SCHEMA_VERSION_11 = 11;
48
51
  /** Target version for new databases. */
49
- export declare const CURRENT_SCHEMA_VERSION = 10;
50
- /** Applies all pending migrations in order. */
51
- export declare function runMigrations(db: DatabaseSync): void;
52
+ export declare const CURRENT_SCHEMA_VERSION = 11;
53
+ /**
54
+ * Applies every pending migration up to `targetVersion` in order — all of
55
+ * them unless a test builds the database a given step starts from.
56
+ */
57
+ export declare function runMigrations(db: DatabaseSync, targetVersion?: number): void;
52
58
  /** Current schema version; 0 when none has been recorded yet. */
53
59
  export declare function getSchemaVersion(db: DatabaseSync): number;
54
60
  //# sourceMappingURL=migrations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/store/sqlite/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,KAAoB,CAAC;AAExD,+CAA+C;AAC/C,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA4BpD;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM,CAKzD"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/store/sqlite/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,KAAoB,CAAC;AAExD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,YAAY,EAChB,aAAa,GAAE,MAA+B,GAC7C,IAAI,CA6BN;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM,CAKzD"}
@@ -13,10 +13,15 @@ export const SCHEMA_VERSION_8 = 8;
13
13
  export const SCHEMA_VERSION_9 = 9;
14
14
  /** v10: every row holding the retired public visibility level moved to org. */
15
15
  export const SCHEMA_VERSION_10 = 10;
16
+ /** v11: the list index's columns, key table and indexes (DDL only). */
17
+ export const SCHEMA_VERSION_11 = 11;
16
18
  /** Target version for new databases. */
17
- export const CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_10;
18
- /** Applies all pending migrations in order. */
19
- export function runMigrations(db) {
19
+ export const CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_11;
20
+ /**
21
+ * Applies every pending migration up to `targetVersion` in order — all of
22
+ * them unless a test builds the database a given step starts from.
23
+ */
24
+ export function runMigrations(db, targetVersion = CURRENT_SCHEMA_VERSION) {
20
25
  db.exec(`
21
26
  CREATE TABLE IF NOT EXISTS schema_version (
22
27
  version INTEGER PRIMARY KEY,
@@ -35,9 +40,10 @@ export function runMigrations(db) {
35
40
  [SCHEMA_VERSION_8, migrateToV8],
36
41
  [SCHEMA_VERSION_9, migrateToV9],
37
42
  [SCHEMA_VERSION_10, migrateToV10],
43
+ [SCHEMA_VERSION_11, migrateToV11],
38
44
  ];
39
45
  for (const [version, migrate] of chain) {
40
- if (currentVersion < version) {
46
+ if (currentVersion < version && version <= targetVersion) {
41
47
  applyInTransaction(db, version, migrate);
42
48
  }
43
49
  }
@@ -344,4 +350,44 @@ function migrateToV10(db) {
344
350
  }
345
351
  }
346
352
  }
353
+ /**
354
+ * v11: the list index (../list-index.ts) — schema only, the Postgres
355
+ * driver's v6 in this engine's terms (postgres/migrations.ts gives the
356
+ * reasons for every column and index). Existing rows, a Go-era database's
357
+ * included, arrive unproven and are derived by the store's reconciliation
358
+ * at open. sqlite compares text as bytes (BINARY) by default, the order
359
+ * list-index.ts merges in, so no collation is spelled here. The store now
360
+ * writes `updated_at` to the millisecond and the stamp from the same
361
+ * expression in the same statement; a writer that does not know the index
362
+ * writes `datetime('now')`, whole seconds, which can never equal a stamp.
363
+ */
364
+ function migrateToV11(db) {
365
+ db.exec(`
366
+ ALTER TABLE resources ADD COLUMN list_org TEXT;
367
+ ALTER TABLE resources ADD COLUMN list_created_at TEXT;
368
+ ALTER TABLE resources ADD COLUMN list_index_revision INTEGER;
369
+ ALTER TABLE resources ADD COLUMN list_indexed_at TEXT;
370
+
371
+ CREATE INDEX idx_resources_list_org
372
+ ON resources (kind, list_org, list_created_at, id);
373
+ CREATE INDEX idx_resources_list_created
374
+ ON resources (kind, list_created_at, id);
375
+ CREATE INDEX idx_resources_list_revision
376
+ ON resources (kind, list_index_revision);
377
+ CREATE INDEX idx_resources_list_unproven
378
+ ON resources (kind, id) WHERE list_indexed_at IS NOT updated_at;
379
+
380
+ CREATE TABLE resource_list_keys (
381
+ kind TEXT NOT NULL,
382
+ id TEXT NOT NULL,
383
+ key TEXT NOT NULL,
384
+ value TEXT NOT NULL,
385
+ created_at TEXT NOT NULL,
386
+ PRIMARY KEY (kind, id, key)
387
+ ) WITHOUT ROWID;
388
+
389
+ CREATE INDEX idx_resource_list_keys_lookup
390
+ ON resource_list_keys (kind, key, value, created_at, id);
391
+ `);
392
+ }
347
393
  //# sourceMappingURL=migrations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/store/sqlite/migrations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/store/sqlite/migrations.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { DescMessage, MessageShape } from "@bufbuild/protobuf";
2
2
  import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
3
- import type { AuditRecord, BootstrapStateStore, OAuthGrantStore, PendingOAuthStateStore, RawResourceDocument, ScheduleRunRecord, SearchIndexEntry, SearchIndexQuery, SearchIndexQueryResult, SignalDedupeStore, Store, WorkflowExecutionEventRecord } from "../interface.js";
3
+ import type { AuditRecord, BootstrapStateStore, OAuthGrantStore, PendingOAuthStateStore, RawResourceDocument, ScheduleRunRecord, SearchIndexEntry, SearchIndexQuery, SearchIndexQueryResult, SignalDedupeStore, Store, StoreOpenOptions, WorkflowExecutionEventRecord } from "../interface.js";
4
+ import type { ListIndexDeclaration, ListIndexQuery, ListIndexRow } from "../list-index.js";
4
5
  import type { StoreLogger } from "../logger.js";
5
6
  export type { StoreLogger } from "../logger.js";
6
7
  export declare class SqliteStore implements Store {
@@ -11,18 +12,21 @@ export declare class SqliteStore implements Store {
11
12
  private db;
12
13
  private readonly dbPath;
13
14
  private readonly logger;
15
+ private readonly listIndexes;
14
16
  private constructor();
15
17
  /**
16
18
  * Opens (or creates) the database at dbPath, applies the pragmas in Go's
17
- * order, and runs migrations — Go NewStore.
19
+ * order, runs migrations — Go NewStore — and reconciles the list index
20
+ * (derives the facts of every unproven row of a declared kind).
18
21
  */
19
- static open(dbPath: string, logger?: StoreLogger): SqliteStore;
22
+ static open(dbPath: string, logger?: StoreLogger, options?: StoreOpenOptions): SqliteStore;
20
23
  /** Filesystem path of the database file (Go Store.Path()). */
21
24
  path(): string;
22
25
  saveResource<Desc extends DescMessage>(kind: ApiResourceKind, id: string, schema: Desc, msg: MessageShape<Desc>): Promise<void>;
23
26
  getResource<Desc extends DescMessage>(kind: ApiResourceKind, id: string, schema: Desc): Promise<MessageShape<Desc>>;
24
27
  updateResource<Desc extends DescMessage>(kind: ApiResourceKind, id: string, schema: Desc, modify: (msg: MessageShape<Desc>) => void): Promise<MessageShape<Desc>>;
25
28
  listResources(kind: ApiResourceKind): Promise<Uint8Array[]>;
29
+ queryResources<K extends string>(declaration: ListIndexDeclaration<K>, query: ListIndexQuery<K>): Promise<ListIndexRow[]>;
26
30
  deleteResource(kind: ApiResourceKind, id: string): Promise<void>;
27
31
  findByField<Desc extends DescMessage>(kind: ApiResourceKind, fieldPath: string, value: string, schema: Desc): Promise<MessageShape<Desc>>;
28
32
  findAllByField(kind: ApiResourceKind, fieldPath: string, value: string): Promise<Uint8Array[]>;
@@ -31,6 +35,17 @@ export declare class SqliteStore implements Store {
31
35
  replaceResourceDataIfUnchanged(kind: ApiResourceKind, id: string, expectedData: Uint8Array, newData: Uint8Array): Promise<boolean>;
32
36
  deleteResourcesByKind(kind: ApiResourceKind): Promise<number>;
33
37
  deleteResourcesByIdPrefix(kind: ApiResourceKind, idPrefix: string): Promise<number>;
38
+ /**
39
+ * An unproven row's facts, derived from its bytes, and the row repaired
40
+ * when those bytes are still the stored ones. Undefined when the bytes
41
+ * do not decode; the row stays unproven and is skipped.
42
+ */
43
+ private deriveAndRepair;
44
+ /**
45
+ * Derives every unproven row of each declared kind and stamps every other
46
+ * kind's unstamped rows, so the unproven set is empty once open returns.
47
+ */
48
+ private reconcileListIndexes;
34
49
  saveAudit<Desc extends DescMessage>(kind: ApiResourceKind, resourceId: string, schema: Desc, msg: MessageShape<Desc>, versionHash: string, tag: string): Promise<void>;
35
50
  getAuditByHash<Desc extends DescMessage>(kind: ApiResourceKind, resourceId: string, versionHash: string, schema: Desc): Promise<MessageShape<Desc>>;
36
51
  getAuditByTag<Desc extends DescMessage>(kind: ApiResourceKind, resourceId: string, tag: string, schema: Desc): Promise<MessageShape<Desc>>;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/store/sqlite/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/store/sqlite/store.ts"],"names":[],"mappings":"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"}
@@ -31,11 +31,60 @@ import path from "node:path";
31
31
  import { DatabaseSync } from "node:sqlite";
32
32
  import { fromBinary, toBinary } from "@bufbuild/protobuf";
33
33
  import { AuditNotFoundError, DELIVERED_SIGNAL_DEDUPE_TTL_MS, PENDING_OAUTH_STATE_TTL_MS, ResourceNotFoundError, } from "../interface.js";
34
+ import { ListIndexRegistry, assertListIndexLimit, listIndexFactsOf, matchesListIndexQuery, mergeListIndexRows, sameListKeyRows, } from "../list-index.js";
34
35
  import { NOOP_STORE_LOGGER } from "../logger.js";
35
36
  import { apiResourceKindName, filterRowsByLabel, scanForFieldMatch, } from "../proto-fields.js";
36
37
  import { rfc3339Seconds } from "../rfc3339.js";
37
38
  import { normalizeBm25Score, renderFts5MatchExpression } from "./fts5.js";
38
39
  import { runMigrations } from "./migrations.js";
40
+ /**
41
+ * `updated_at` and the list index's stamp, to the millisecond. Evaluated
42
+ * twice in one statement it yields one value (sqlite fixes 'now' per
43
+ * statement step), so a row this driver writes is stamped with exactly its
44
+ * `updated_at`; a writer that does not know the index writes
45
+ * `datetime('now')`, whole seconds, which never equals a stamp.
46
+ */
47
+ const NOW = `strftime('%Y-%m-%d %H:%M:%f', 'now')`;
48
+ /** The one upsert every resource write goes through (postgres/store.ts's twin). */
49
+ const UPSERT_RESOURCE_SQL = `INSERT OR REPLACE INTO resources
50
+ (kind, id, data, updated_at, list_org, list_created_at, list_index_revision, list_indexed_at)
51
+ VALUES (?, ?, ?, ${NOW}, ?, ?, ?, ${NOW})`;
52
+ /**
53
+ * The rows of a kind whose facts are not proven current under a revision
54
+ * (list-index.ts; postgres/store.ts's twin). A row's list columns sit
55
+ * after its blob in the record and sqlite reaches them only by walking the
56
+ * blob's overflow pages, so any predicate checked per row of the kind
57
+ * costs a read of every blob (measured: 11 ms, and 72 ms for an OR over
58
+ * the revision, across 1,279 rows of 37 KB). Every arm is therefore one
59
+ * index range that fetches a row only when it matches, and names its
60
+ * index: without statistics the planner prefers the primary key for
61
+ * `kind = ?`, and `INDEXED BY` fails the statement rather than fall back
62
+ * to a scan. The arms overlap (an unstamped row has no revision either),
63
+ * so the caller keeps one row per id. Parameters: kind, kind, kind,
64
+ * revision, kind, revision.
65
+ */
66
+ const UNPROVEN_ROWS_SQL = `
67
+ SELECT id, data FROM resources INDEXED BY idx_resources_list_unproven
68
+ WHERE kind = ? AND list_indexed_at IS NOT updated_at
69
+ UNION ALL
70
+ SELECT id, data FROM resources INDEXED BY idx_resources_list_revision
71
+ WHERE kind = ? AND list_index_revision IS NULL
72
+ UNION ALL
73
+ SELECT id, data FROM resources INDEXED BY idx_resources_list_revision
74
+ WHERE kind = ? AND list_index_revision < ?
75
+ UNION ALL
76
+ SELECT id, data FROM resources INDEXED BY idx_resources_list_revision
77
+ WHERE kind = ? AND list_index_revision > ?`;
78
+ function unprovenRowsParams(kindName, revision) {
79
+ return [kindName, kindName, kindName, revision, kindName, revision];
80
+ }
81
+ /** Keeps the first row per id; the unproven arms overlap. */
82
+ function oneRowPerId(rows) {
83
+ const seen = new Set();
84
+ return rows.filter((row) => seen.has(row.id) ? false : (seen.add(row.id), true));
85
+ }
86
+ /** How many unproven rows the reconciliation at open decodes per statement. */
87
+ const RECONCILE_BATCH = 500;
39
88
  export class SqliteStore {
40
89
  bootstrapState;
41
90
  signalDedupe;
@@ -44,10 +93,12 @@ export class SqliteStore {
44
93
  db;
45
94
  dbPath;
46
95
  logger;
47
- constructor(db, dbPath, logger) {
96
+ listIndexes;
97
+ constructor(db, dbPath, logger, listIndexes) {
48
98
  this.db = db;
49
99
  this.dbPath = dbPath;
50
100
  this.logger = logger;
101
+ this.listIndexes = listIndexes;
51
102
  this.bootstrapState = new SqliteBootstrapStateStore(() => this.open());
52
103
  this.signalDedupe = new SqliteSignalDedupeStore(() => this.open(), logger);
53
104
  this.oauthGrants = new SqliteOAuthGrantStore(() => this.open());
@@ -55,9 +106,11 @@ export class SqliteStore {
55
106
  }
56
107
  /**
57
108
  * Opens (or creates) the database at dbPath, applies the pragmas in Go's
58
- * order, and runs migrations — Go NewStore.
109
+ * order, runs migrations — Go NewStore — and reconciles the list index
110
+ * (derives the facts of every unproven row of a declared kind).
59
111
  */
60
- static open(dbPath, logger = NOOP_STORE_LOGGER) {
112
+ static open(dbPath, logger = NOOP_STORE_LOGGER, options = {}) {
113
+ const listIndexes = new ListIndexRegistry(options.listIndexes ?? []);
61
114
  const dir = path.dirname(dbPath);
62
115
  if (dir !== "" && dir !== ".") {
63
116
  mkdirSync(dir, { recursive: true });
@@ -77,7 +130,15 @@ export class SqliteStore {
77
130
  db.close();
78
131
  throw error;
79
132
  }
80
- return new SqliteStore(db, dbPath, logger);
133
+ const store = new SqliteStore(db, dbPath, logger, listIndexes);
134
+ try {
135
+ store.reconcileListIndexes();
136
+ }
137
+ catch (error) {
138
+ db.close();
139
+ throw error;
140
+ }
141
+ return store;
81
142
  }
82
143
  /** Filesystem path of the database file (Go Store.Path()). */
83
144
  path() {
@@ -89,7 +150,22 @@ export class SqliteStore {
89
150
  async saveResource(kind, id, schema, msg) {
90
151
  const db = this.open();
91
152
  const data = toBinary(schema, msg);
92
- db.prepare(`INSERT OR REPLACE INTO resources (kind, id, data, updated_at) VALUES (?, ?, ?, datetime('now'))`).run(apiResourceKindName(kind), id, data);
153
+ const kindName = apiResourceKindName(kind);
154
+ const facts = this.listIndexes.factsOf(kind, msg);
155
+ if (facts === undefined) {
156
+ db.prepare(UPSERT_RESOURCE_SQL).run(kindName, id, data, null, null, null);
157
+ return;
158
+ }
159
+ db.exec("BEGIN");
160
+ try {
161
+ db.prepare(UPSERT_RESOURCE_SQL).run(kindName, id, data, facts.org, facts.createdAt, facts.revision);
162
+ replaceListKeys(db, kindName, id, facts);
163
+ db.exec("COMMIT");
164
+ }
165
+ catch (error) {
166
+ db.exec("ROLLBACK");
167
+ throw error;
168
+ }
93
169
  }
94
170
  async getResource(kind, id, schema) {
95
171
  const db = this.open();
@@ -113,15 +189,25 @@ export class SqliteStore {
113
189
  db.exec("BEGIN IMMEDIATE");
114
190
  try {
115
191
  const row = db
116
- .prepare(`SELECT data FROM resources WHERE kind = ? AND id = ?`)
192
+ .prepare(`SELECT data, list_indexed_at IS updated_at AS stamped, list_index_revision
193
+ FROM resources WHERE kind = ? AND id = ?`)
117
194
  .get(kindName, id);
118
195
  if (row === undefined) {
119
196
  throw new ResourceNotFoundError(`${kindName}/${id}`);
120
197
  }
121
198
  const msg = fromBinary(schema, row.data);
199
+ const before = this.listIndexes.factsOf(kind, msg);
122
200
  modify(msg);
201
+ const after = this.listIndexes.factsOf(kind, msg);
123
202
  const data = toBinary(schema, msg);
124
- db.prepare(`INSERT OR REPLACE INTO resources (kind, id, data, updated_at) VALUES (?, ?, ?, datetime('now'))`).run(kindName, id, data);
203
+ db.prepare(UPSERT_RESOURCE_SQL).run(kindName, id, data, after?.org ?? null, after?.createdAt ?? null, after?.revision ?? null);
204
+ if (after !== undefined &&
205
+ (row.stamped !== 1 ||
206
+ row.list_index_revision !== after.revision ||
207
+ before === undefined ||
208
+ !sameListKeyRows(before, after))) {
209
+ replaceListKeys(db, kindName, id, after);
210
+ }
125
211
  db.exec("COMMIT");
126
212
  return msg;
127
213
  }
@@ -139,9 +225,52 @@ export class SqliteStore {
139
225
  // copy is needed (Go copied because database/sql may reuse buffers).
140
226
  return rows.map((row) => row.data);
141
227
  }
228
+ async queryResources(declaration, query) {
229
+ this.listIndexes.require(declaration);
230
+ assertListIndexLimit(query.limit);
231
+ if (query.anyKey !== undefined && query.anyKey.length === 0) {
232
+ return [];
233
+ }
234
+ const db = this.open();
235
+ const kindName = apiResourceKindName(declaration.kind);
236
+ // A key read is driven from the key table (CROSS JOIN fixes sqlite's
237
+ // join order), so only the rows the key names are ever read; several
238
+ // keys are one such read each, merged below (postgres/store.ts's twin).
239
+ const reads = query.anyKey === undefined
240
+ ? [provenReadSql(kindName, declaration.revision, query, undefined)]
241
+ : query.anyKey.map((key) => provenReadSql(kindName, declaration.revision, query, key));
242
+ const proven = [];
243
+ for (const read of reads) {
244
+ const rows = db.prepare(read.sql).all(...read.params);
245
+ for (const row of rows) {
246
+ proven.push({
247
+ id: row.id,
248
+ data: row.data,
249
+ cursor: { createdAt: row.created_at, id: row.id },
250
+ });
251
+ }
252
+ }
253
+ const unproven = oneRowPerId(db
254
+ .prepare(UNPROVEN_ROWS_SQL)
255
+ .all(...unprovenRowsParams(kindName, declaration.revision)));
256
+ const unprovenRows = [];
257
+ for (const row of unproven) {
258
+ const facts = this.deriveAndRepair(declaration, row.id, row.data);
259
+ if (facts !== undefined && matchesListIndexQuery(row.id, facts, query)) {
260
+ unprovenRows.push({
261
+ id: row.id,
262
+ data: row.data,
263
+ cursor: { createdAt: facts.createdAt, id: row.id },
264
+ });
265
+ }
266
+ }
267
+ return mergeListIndexRows(proven, unprovenRows, query.limit);
268
+ }
142
269
  async deleteResource(kind, id) {
143
270
  const db = this.open();
144
- db.prepare(`DELETE FROM resources WHERE kind = ? AND id = ?`).run(apiResourceKindName(kind), id);
271
+ const kindName = apiResourceKindName(kind);
272
+ db.prepare(`DELETE FROM resources WHERE kind = ? AND id = ?`).run(kindName, id);
273
+ db.prepare(`DELETE FROM resource_list_keys WHERE kind = ? AND id = ?`).run(kindName, id);
145
274
  }
146
275
  async findByField(kind, fieldPath, value, schema) {
147
276
  const db = this.open();
@@ -185,28 +314,139 @@ export class SqliteStore {
185
314
  const db = this.open();
186
315
  // BLOB equality in the WHERE clause makes the compare-and-swap one
187
316
  // atomic statement: zero rows changed means the row moved on (or was
188
- // deleted) since the read — a lost swap, never an upsert.
189
- const result = db
190
- .prepare(`UPDATE resources SET data = ?, updated_at = datetime('now') WHERE kind = ? AND id = ? AND data = ?`)
191
- .run(newData, apiResourceKindName(kind), id, expectedData);
192
- return Number(result.changes) === 1;
317
+ // deleted) since the read — a lost swap, never an upsert. The new bytes'
318
+ // list facts ride the same statement; bytes a declared kind's schema
319
+ // cannot decode leave the row unproven (stamp NULL), for a read to skip.
320
+ const kindName = apiResourceKindName(kind);
321
+ const declaration = this.listIndexes.declarationOf(kind);
322
+ const facts = declaration === undefined
323
+ ? undefined
324
+ : factsOfBytes(declaration, newData);
325
+ const swap = () => Number(db
326
+ .prepare(`UPDATE resources SET data = ?, updated_at = ${NOW},
327
+ list_org = ?, list_created_at = ?, list_index_revision = ?,
328
+ list_indexed_at = CASE WHEN ? THEN ${NOW} ELSE NULL END
329
+ WHERE kind = ? AND id = ? AND data = ?`)
330
+ .run(newData, facts?.org ?? null, facts?.createdAt ?? null, facts?.revision ?? null, declaration === undefined || facts !== undefined ? 1 : 0, kindName, id, expectedData).changes) === 1;
331
+ if (facts === undefined) {
332
+ return swap();
333
+ }
334
+ db.exec("BEGIN");
335
+ try {
336
+ const swapped = swap();
337
+ if (swapped) {
338
+ replaceListKeys(db, kindName, id, facts);
339
+ }
340
+ db.exec("COMMIT");
341
+ return swapped;
342
+ }
343
+ catch (error) {
344
+ db.exec("ROLLBACK");
345
+ throw error;
346
+ }
193
347
  }
194
348
  async deleteResourcesByKind(kind) {
195
349
  const db = this.open();
350
+ const kindName = apiResourceKindName(kind);
196
351
  const result = db
197
352
  .prepare(`DELETE FROM resources WHERE kind = ?`)
198
- .run(apiResourceKindName(kind));
353
+ .run(kindName);
354
+ db.prepare(`DELETE FROM resource_list_keys WHERE kind = ?`).run(kindName);
199
355
  return Number(result.changes);
200
356
  }
201
357
  async deleteResourcesByIdPrefix(kind, idPrefix) {
202
358
  const db = this.open();
359
+ const kindName = apiResourceKindName(kind);
203
360
  // GLOB 'prefix*' uses the (kind, id) index where LIKE would not (Go).
204
361
  const result = db
205
362
  .prepare(`DELETE FROM resources WHERE kind = ? AND id GLOB ?`)
206
- .run(apiResourceKindName(kind), `${idPrefix}*`);
363
+ .run(kindName, `${idPrefix}*`);
364
+ db.prepare(`DELETE FROM resource_list_keys WHERE kind = ? AND id GLOB ?`).run(kindName, `${idPrefix}*`);
207
365
  return Number(result.changes);
208
366
  }
209
367
  // ---------------------------------------------------------------------------
368
+ // The list index's repair (list-index.ts; postgres/store.ts's twin)
369
+ // ---------------------------------------------------------------------------
370
+ /**
371
+ * An unproven row's facts, derived from its bytes, and the row repaired
372
+ * when those bytes are still the stored ones. Undefined when the bytes
373
+ * do not decode; the row stays unproven and is skipped.
374
+ */
375
+ deriveAndRepair(declaration, id, data) {
376
+ const kindName = apiResourceKindName(declaration.kind);
377
+ const facts = factsOfBytes(declaration, data);
378
+ if (facts === undefined) {
379
+ this.logger.warn("list index: an unproven row does not decode, skipping", {
380
+ kind: kindName,
381
+ id,
382
+ });
383
+ return undefined;
384
+ }
385
+ const db = this.open();
386
+ db.exec("BEGIN");
387
+ try {
388
+ const repaired = db
389
+ .prepare(`UPDATE resources SET list_org = ?, list_created_at = ?,
390
+ list_index_revision = ?, list_indexed_at = updated_at
391
+ WHERE kind = ? AND id = ? AND data = ?`)
392
+ .run(facts.org, facts.createdAt, facts.revision, kindName, id, data);
393
+ if (Number(repaired.changes) === 1) {
394
+ replaceListKeys(db, kindName, id, facts);
395
+ }
396
+ db.exec("COMMIT");
397
+ }
398
+ catch (error) {
399
+ db.exec("ROLLBACK");
400
+ this.logger.warn("list index: repairing a row failed", {
401
+ kind: kindName,
402
+ id,
403
+ error: error instanceof Error ? error.message : String(error),
404
+ });
405
+ }
406
+ return facts;
407
+ }
408
+ /**
409
+ * Derives every unproven row of each declared kind and stamps every other
410
+ * kind's unstamped rows, so the unproven set is empty once open returns.
411
+ */
412
+ reconcileListIndexes() {
413
+ const db = this.open();
414
+ const declarations = this.listIndexes.declarations();
415
+ for (const declaration of declarations) {
416
+ const kindName = apiResourceKindName(declaration.kind);
417
+ let after = "";
418
+ let derived = 0;
419
+ for (;;) {
420
+ // Duplicates from overlapping arms sit side by side in id order and
421
+ // the next batch starts after the last id, so none is repaired twice
422
+ // across batches and the count still ends the loop.
423
+ const rows = db
424
+ .prepare(`SELECT id, data FROM (${UNPROVEN_ROWS_SQL}) WHERE id > ?
425
+ ORDER BY id LIMIT ?`)
426
+ .all(...unprovenRowsParams(kindName, declaration.revision), after, RECONCILE_BATCH);
427
+ for (const row of oneRowPerId(rows)) {
428
+ if (this.deriveAndRepair(declaration, row.id, row.data) !== undefined) {
429
+ derived += 1;
430
+ }
431
+ after = row.id;
432
+ }
433
+ if (rows.length < RECONCILE_BATCH) {
434
+ break;
435
+ }
436
+ }
437
+ if (derived > 0) {
438
+ this.logger.info("list index reconciled", {
439
+ kind: kindName,
440
+ rows: derived,
441
+ });
442
+ }
443
+ }
444
+ const declared = declarations.map((d) => apiResourceKindName(d.kind));
445
+ db.prepare(`UPDATE resources SET list_indexed_at = updated_at
446
+ WHERE list_indexed_at IS NOT updated_at
447
+ AND kind NOT IN (${declared.map(() => "?").join(", ") || "''"})`).run(...declared);
448
+ }
449
+ // ---------------------------------------------------------------------------
210
450
  // Audit operations
211
451
  // ---------------------------------------------------------------------------
212
452
  async saveAudit(kind, resourceId, schema, msg, versionHash, tag) {
@@ -718,6 +958,72 @@ class SqliteSignalDedupeStore {
718
958
  }
719
959
  }
720
960
  /** Composite dedupe key: "{org}:{idempotency_key}" (Go buildDedupeKey). */
961
+ /**
962
+ * A row's key rows made equal to its facts, on the caller's open
963
+ * transaction (postgres/store.ts's twin).
964
+ */
965
+ function replaceListKeys(db, kindName, id, facts) {
966
+ db.prepare(`DELETE FROM resource_list_keys WHERE kind = ? AND id = ?`).run(kindName, id);
967
+ const insert = db.prepare(`INSERT INTO resource_list_keys (kind, id, key, value, created_at) VALUES (?, ?, ?, ?, ?)`);
968
+ for (const entry of facts.keys) {
969
+ insert.run(kindName, id, entry.key, entry.value, facts.createdAt);
970
+ }
971
+ }
972
+ /**
973
+ * One proven read of `queryResources` (postgres/store.ts's twin): through
974
+ * one key's index range when `key` is given, else through the organization
975
+ * index; only rows whose facts are proven current.
976
+ */
977
+ function provenReadSql(kindName, revision, query, key) {
978
+ const params = [];
979
+ const created = key === undefined ? "r.list_created_at" : "k.created_at";
980
+ const id = key === undefined ? "r.id" : "k.id";
981
+ const where = [];
982
+ let from = `resources AS r`;
983
+ if (key === undefined) {
984
+ where.push(`r.kind = ?`);
985
+ params.push(kindName);
986
+ }
987
+ else {
988
+ from = `resource_list_keys AS k CROSS JOIN resources AS r`;
989
+ where.push(`k.kind = ?`, `k.key = ?`, `k.value = ?`, `r.kind = k.kind`, `r.id = k.id`);
990
+ params.push(kindName, key.name, key.value);
991
+ }
992
+ where.push(`r.list_indexed_at = r.updated_at`, `r.list_index_revision = ?`);
993
+ params.push(revision);
994
+ if (query.org !== undefined && query.org !== "") {
995
+ where.push(`r.list_org = ?`);
996
+ params.push(query.org);
997
+ }
998
+ if (query.createdAtOrAfter !== undefined) {
999
+ where.push(`(${created} >= ? OR ${created} = '')`);
1000
+ params.push(query.createdAtOrAfter);
1001
+ }
1002
+ if (query.after !== undefined) {
1003
+ where.push(`(${created} < ? OR (${created} = ? AND ${id} < ?))`);
1004
+ params.push(query.after.createdAt, query.after.createdAt, query.after.id);
1005
+ }
1006
+ let limit = "";
1007
+ if (query.limit !== undefined) {
1008
+ limit = ` LIMIT ?`;
1009
+ params.push(query.limit);
1010
+ }
1011
+ return {
1012
+ sql: `SELECT r.id, r.data, ${created} AS created_at FROM ${from}
1013
+ WHERE ${where.join(" AND ")}
1014
+ ORDER BY ${created} DESC, ${id} DESC${limit}`,
1015
+ params,
1016
+ };
1017
+ }
1018
+ /** A declared kind's facts from stored bytes; undefined when they do not decode. */
1019
+ function factsOfBytes(declaration, data) {
1020
+ try {
1021
+ return listIndexFactsOf(declaration, fromBinary(declaration.schema, data));
1022
+ }
1023
+ catch {
1024
+ return undefined;
1025
+ }
1026
+ }
721
1027
  function buildDedupeKey(org, idempotencyKey) {
722
1028
  return `${org}:${idempotencyKey}`;
723
1029
  }