@iworkforces/tracelattice 2.0.7 → 2.1.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 (217) hide show
  1. package/README.md +88 -64
  2. package/dist/ServerConfig.d.ts +1 -1
  3. package/dist/ServerConfig.js.map +1 -1
  4. package/dist/cli.js +223 -254
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config/ConfigLoader.d.ts +29 -26
  7. package/dist/config/ConfigLoader.d.ts.map +1 -1
  8. package/dist/config/ConfigLoader.js +40 -36
  9. package/dist/config/ConfigLoader.js.map +1 -1
  10. package/dist/contracts/PersistenceBackend.d.ts +7 -108
  11. package/dist/contracts/PersistenceBackend.d.ts.map +1 -1
  12. package/dist/contracts/PersistenceBackend.js +1 -6
  13. package/dist/contracts/calibrator.d.ts +6 -6
  14. package/dist/contracts/calibrator.d.ts.map +1 -1
  15. package/dist/contracts/ids.d.ts +1 -8
  16. package/dist/contracts/ids.d.ts.map +1 -1
  17. package/dist/contracts/ids.js +2 -3
  18. package/dist/contracts/ids.js.map +1 -1
  19. package/dist/contracts/interfaces.d.ts +4 -6
  20. package/dist/contracts/interfaces.d.ts.map +1 -1
  21. package/dist/contracts/persistence-work.d.ts +2 -3
  22. package/dist/contracts/persistence-work.d.ts.map +1 -1
  23. package/dist/contracts/summary.d.ts +0 -1
  24. package/dist/contracts/summary.d.ts.map +1 -1
  25. package/dist/core/HistoryManager.d.ts +12 -16
  26. package/dist/core/HistoryManager.d.ts.map +1 -1
  27. package/dist/core/HistoryManager.js +19 -40
  28. package/dist/core/HistoryManager.js.map +1 -1
  29. package/dist/core/IHistoryManager.d.ts +22 -30
  30. package/dist/core/IHistoryManager.d.ts.map +1 -1
  31. package/dist/core/InputNormalizer.d.ts +7 -24
  32. package/dist/core/InputNormalizer.d.ts.map +1 -1
  33. package/dist/core/InputNormalizer.js +3 -9
  34. package/dist/core/InputNormalizer.js.map +1 -1
  35. package/dist/core/PersistenceBuffer.d.ts +3 -20
  36. package/dist/core/PersistenceBuffer.d.ts.map +1 -1
  37. package/dist/core/PersistenceBuffer.js +1 -4
  38. package/dist/core/PersistenceBuffer.js.map +1 -1
  39. package/dist/core/PersistenceRestore.d.ts +1 -1
  40. package/dist/core/PersistenceRestore.d.ts.map +1 -1
  41. package/dist/core/PersistenceRestore.js +4 -10
  42. package/dist/core/PersistenceRestore.js.map +1 -1
  43. package/dist/core/PersistenceWriter.d.ts.map +1 -1
  44. package/dist/core/PersistenceWriter.js +3 -12
  45. package/dist/core/PersistenceWriter.js.map +1 -1
  46. package/dist/core/SessionErrors.d.ts +0 -11
  47. package/dist/core/SessionErrors.d.ts.map +1 -1
  48. package/dist/core/SessionErrors.js +1 -14
  49. package/dist/core/SessionErrors.js.map +1 -1
  50. package/dist/core/SessionLock.d.ts +4 -5
  51. package/dist/core/SessionLock.d.ts.map +1 -1
  52. package/dist/core/SessionLock.js +5 -10
  53. package/dist/core/SessionLock.js.map +1 -1
  54. package/dist/core/SessionManager.d.ts +0 -2
  55. package/dist/core/SessionManager.d.ts.map +1 -1
  56. package/dist/core/SessionManager.js +3 -5
  57. package/dist/core/SessionManager.js.map +1 -1
  58. package/dist/core/SessionResetCoordinator.d.ts +10 -7
  59. package/dist/core/SessionResetCoordinator.d.ts.map +1 -1
  60. package/dist/core/SessionResetCoordinator.js +10 -28
  61. package/dist/core/SessionResetCoordinator.js.map +1 -1
  62. package/dist/core/ThoughtEvaluator.d.ts +5 -5
  63. package/dist/core/ThoughtEvaluator.d.ts.map +1 -1
  64. package/dist/core/ThoughtEvaluator.js +4 -40
  65. package/dist/core/ThoughtEvaluator.js.map +1 -1
  66. package/dist/core/ThoughtFormatter.js.map +1 -1
  67. package/dist/core/ThoughtProcessor.d.ts +10 -3
  68. package/dist/core/ThoughtProcessor.d.ts.map +1 -1
  69. package/dist/core/ThoughtProcessor.js +34 -38
  70. package/dist/core/ThoughtProcessor.js.map +1 -1
  71. package/dist/core/VerificationOutcomeAdmission.d.ts.map +1 -1
  72. package/dist/core/VerificationOutcomeAdmission.js +5 -7
  73. package/dist/core/VerificationOutcomeAdmission.js.map +1 -1
  74. package/dist/core/compression/CompressionService.d.ts +2 -1
  75. package/dist/core/compression/CompressionService.d.ts.map +1 -1
  76. package/dist/core/compression/CompressionService.js.map +1 -1
  77. package/dist/core/compression/DehydrationPolicy.d.ts.map +1 -1
  78. package/dist/core/compression/DehydrationPolicy.js.map +1 -1
  79. package/dist/core/compression/InMemorySummaryStore.d.ts +2 -1
  80. package/dist/core/compression/InMemorySummaryStore.d.ts.map +1 -1
  81. package/dist/core/compression/InMemorySummaryStore.js.map +1 -1
  82. package/dist/core/evaluator/Calibrator.d.ts +2 -2
  83. package/dist/core/evaluator/Calibrator.d.ts.map +1 -1
  84. package/dist/core/evaluator/Calibrator.js +2 -5
  85. package/dist/core/evaluator/Calibrator.js.map +1 -1
  86. package/dist/core/evaluator/SignalComputer.d.ts +2 -1
  87. package/dist/core/evaluator/SignalComputer.d.ts.map +1 -1
  88. package/dist/core/evaluator/SignalComputer.js.map +1 -1
  89. package/dist/core/evaluator/internals.d.ts +1 -5
  90. package/dist/core/evaluator/internals.d.ts.map +1 -1
  91. package/dist/core/evaluator/internals.js +1 -3
  92. package/dist/core/evaluator/internals.js.map +1 -1
  93. package/dist/core/graph/Edge.d.ts +1 -1
  94. package/dist/core/graph/EdgeEmitter.d.ts +2 -4
  95. package/dist/core/graph/EdgeEmitter.d.ts.map +1 -1
  96. package/dist/core/graph/EdgeEmitter.js +2 -4
  97. package/dist/core/graph/EdgeEmitter.js.map +1 -1
  98. package/dist/core/graph/GraphView.d.ts +13 -1
  99. package/dist/core/graph/GraphView.d.ts.map +1 -1
  100. package/dist/core/graph/GraphView.js +34 -0
  101. package/dist/core/graph/GraphView.js.map +1 -1
  102. package/dist/core/reasoning/OutcomeRecorder.d.ts +0 -1
  103. package/dist/core/reasoning/OutcomeRecorder.d.ts.map +1 -1
  104. package/dist/core/reasoning/OutcomeRecorder.js.map +1 -1
  105. package/dist/core/reasoning/strategies/SequentialStrategy.d.ts +3 -3
  106. package/dist/core/reasoning/strategies/SequentialStrategy.js.map +1 -1
  107. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts +6 -6
  108. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts.map +1 -1
  109. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js +16 -2
  110. package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js.map +1 -1
  111. package/dist/core/reasoning/strategies/totScoring.d.ts.map +1 -1
  112. package/dist/core/reasoning/strategies/totScoring.js.map +1 -1
  113. package/dist/core/reasoning.d.ts +1 -3
  114. package/dist/core/reasoning.d.ts.map +1 -1
  115. package/dist/core/thought.d.ts +3 -2
  116. package/dist/core/thought.d.ts.map +1 -1
  117. package/dist/errors.d.ts +4 -20
  118. package/dist/errors.d.ts.map +1 -1
  119. package/dist/errors.js +2 -28
  120. package/dist/errors.js.map +1 -1
  121. package/dist/lib.d.ts +31 -24
  122. package/dist/lib.d.ts.map +1 -1
  123. package/dist/lib.js +55 -10
  124. package/dist/lib.js.map +1 -1
  125. package/dist/logger/NullLogger.d.ts +9 -11
  126. package/dist/logger/NullLogger.d.ts.map +1 -1
  127. package/dist/logger/NullLogger.js.map +1 -1
  128. package/dist/persistence/FilePersistence.d.ts +3 -12
  129. package/dist/persistence/FilePersistence.d.ts.map +1 -1
  130. package/dist/persistence/FilePersistence.js +9 -61
  131. package/dist/persistence/FilePersistence.js.map +1 -1
  132. package/dist/persistence/FileSnapshotV2.d.ts +2 -2
  133. package/dist/persistence/FileSnapshotV2.js +2 -2
  134. package/dist/persistence/FileSnapshotV2.js.map +1 -1
  135. package/dist/persistence/FileWriter.d.ts +1 -0
  136. package/dist/persistence/FileWriter.d.ts.map +1 -1
  137. package/dist/persistence/FileWriter.js +3 -3
  138. package/dist/persistence/FileWriter.js.map +1 -1
  139. package/dist/persistence/MemoryPersistence.d.ts +5 -15
  140. package/dist/persistence/MemoryPersistence.d.ts.map +1 -1
  141. package/dist/persistence/MemoryPersistence.js +6 -40
  142. package/dist/persistence/MemoryPersistence.js.map +1 -1
  143. package/dist/persistence/PersistenceCodec.js +1 -3
  144. package/dist/persistence/PersistenceCodec.js.map +1 -1
  145. package/dist/persistence/PersistenceErrors.d.ts +0 -6
  146. package/dist/persistence/PersistenceErrors.d.ts.map +1 -1
  147. package/dist/persistence/PersistenceErrors.js +1 -9
  148. package/dist/persistence/PersistenceErrors.js.map +1 -1
  149. package/dist/persistence/PersistenceScope.d.ts.map +1 -1
  150. package/dist/persistence/PersistenceScope.js +2 -2
  151. package/dist/persistence/PersistenceScope.js.map +1 -1
  152. package/dist/persistence/SqlitePersistence.d.ts +3 -10
  153. package/dist/persistence/SqlitePersistence.d.ts.map +1 -1
  154. package/dist/persistence/SqlitePersistence.js +2 -26
  155. package/dist/persistence/SqlitePersistence.js.map +1 -1
  156. package/dist/persistence/SqliteSchemaV2.d.ts.map +1 -1
  157. package/dist/persistence/SqliteSchemaV2.js +3 -12
  158. package/dist/persistence/SqliteSchemaV2.js.map +1 -1
  159. package/dist/pool/ConnectionPool.d.ts +3 -12
  160. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  161. package/dist/pool/ConnectionPool.js +5 -8
  162. package/dist/pool/ConnectionPool.js.map +1 -1
  163. package/dist/pool/IConnectionPool.d.ts +3 -9
  164. package/dist/pool/IConnectionPool.d.ts.map +1 -1
  165. package/dist/registry/SkillRegistry.d.ts +1 -7
  166. package/dist/registry/SkillRegistry.d.ts.map +1 -1
  167. package/dist/registry/SkillRegistry.js +0 -15
  168. package/dist/registry/SkillRegistry.js.map +1 -1
  169. package/dist/registry/ToolRegistry.d.ts +1 -9
  170. package/dist/registry/ToolRegistry.d.ts.map +1 -1
  171. package/dist/registry/ToolRegistry.js +0 -21
  172. package/dist/registry/ToolRegistry.js.map +1 -1
  173. package/dist/schema.d.ts +2 -1
  174. package/dist/schema.d.ts.map +1 -1
  175. package/dist/schema.js +3 -3
  176. package/dist/schema.js.map +1 -1
  177. package/dist/transport/BaseTransport.d.ts +0 -9
  178. package/dist/transport/BaseTransport.d.ts.map +1 -1
  179. package/dist/transport/BaseTransport.js +0 -11
  180. package/dist/transport/BaseTransport.js.map +1 -1
  181. package/dist/transport/HttpHelpers.d.ts +4 -1
  182. package/dist/transport/HttpHelpers.d.ts.map +1 -1
  183. package/dist/transport/HttpHelpers.js +61 -11
  184. package/dist/transport/HttpHelpers.js.map +1 -1
  185. package/dist/transport/HttpRequestLifecycle.d.ts +15 -1
  186. package/dist/transport/HttpRequestLifecycle.d.ts.map +1 -1
  187. package/dist/transport/HttpRequestLifecycle.js +66 -4
  188. package/dist/transport/HttpRequestLifecycle.js.map +1 -1
  189. package/dist/transport/HttpTransport.d.ts +2 -0
  190. package/dist/transport/HttpTransport.d.ts.map +1 -1
  191. package/dist/transport/HttpTransport.js +75 -38
  192. package/dist/transport/HttpTransport.js.map +1 -1
  193. package/dist/transport/StreamableHttpTransport.d.ts +5 -29
  194. package/dist/transport/StreamableHttpTransport.d.ts.map +1 -1
  195. package/dist/transport/StreamableHttpTransport.js +74 -116
  196. package/dist/transport/StreamableHttpTransport.js.map +1 -1
  197. package/dist/watchers/SkillWatcher.d.ts.map +1 -1
  198. package/dist/watchers/SkillWatcher.js +1 -1
  199. package/dist/watchers/SkillWatcher.js.map +1 -1
  200. package/package.json +2 -2
  201. package/dist/contracts/PersistenceBackend.js.map +0 -1
  202. package/dist/persistence/FileLegacyImport.d.ts +0 -2
  203. package/dist/persistence/FileLegacyImport.d.ts.map +0 -1
  204. package/dist/persistence/FileLegacyImport.js +0 -183
  205. package/dist/persistence/FileLegacyImport.js.map +0 -1
  206. package/dist/persistence/SessionScopedPersistence.d.ts +0 -4
  207. package/dist/persistence/SessionScopedPersistence.d.ts.map +0 -1
  208. package/dist/persistence/SessionScopedPersistence.js +0 -9
  209. package/dist/persistence/SessionScopedPersistence.js.map +0 -1
  210. package/dist/persistence/SqliteLegacyImport.d.ts +0 -14
  211. package/dist/persistence/SqliteLegacyImport.d.ts.map +0 -1
  212. package/dist/persistence/SqliteLegacyImport.js +0 -136
  213. package/dist/persistence/SqliteLegacyImport.js.map +0 -1
  214. package/dist/persistence/SqliteLegacySchema.d.ts +0 -15
  215. package/dist/persistence/SqliteLegacySchema.d.ts.map +0 -1
  216. package/dist/persistence/SqliteLegacySchema.js +0 -72
  217. package/dist/persistence/SqliteLegacySchema.js.map +0 -1
@@ -1,4 +1,3 @@
1
- import type { SessionScopedPersistenceOperation } from '../contracts/PersistenceBackend.js';
2
1
  import type { BranchId, SessionId } from '../contracts/ids.js';
3
2
  import { SequentialThinkingError } from '../errors.js';
4
3
  /** Durable namespace associated with a persistence write. */
@@ -8,11 +7,6 @@ export type PersistenceScope = {
8
7
  };
9
8
  /** Operations whose payload ownership is validated before mutation. */
10
9
  export type PersistenceWriteOperation = 'saveThought' | 'saveThoughtForSession' | 'saveBranch' | 'saveBranchForSession' | 'saveEdges' | 'saveSummaries';
11
- /** Error raised when a custom backend lacks the complete scoped capability. */
12
- export declare class PersistenceCapabilityError extends SequentialThinkingError {
13
- readonly operation: SessionScopedPersistenceOperation;
14
- constructor(operation: SessionScopedPersistenceOperation);
15
- }
16
10
  /** Error raised before a write whose payload belongs to another namespace. */
17
11
  export declare class PersistenceScopeMismatchError extends SequentialThinkingError {
18
12
  readonly operation: PersistenceWriteOperation;
@@ -1 +1 @@
1
- {"version":3,"file":"PersistenceErrors.d.ts","sourceRoot":"","sources":["../../src/persistence/PersistenceErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AAC5F,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAe,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEpE,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC7B,CAAC;AAEF,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GAClC,aAAa,GACb,uBAAuB,GACvB,YAAY,GACZ,sBAAsB,GACtB,WAAW,GACX,eAAe,CAAC;AAEnB,+EAA+E;AAC/E,qBAAa,0BAA2B,SAAQ,uBAAuB;IACtE,SAAgB,SAAS,EAAE,iCAAiC,CAAC;gBAEjD,SAAS,EAAE,iCAAiC;CAQxD;AAED,8EAA8E;AAC9E,qBAAa,6BAA8B,SAAQ,uBAAuB;IACzE,SAAgB,SAAS,EAAE,yBAAyB,CAAC;IACrD,SAAgB,aAAa,EAAE,gBAAgB,CAAC;IAChD,SAAgB,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAC;gBAGzD,SAAS,EAAE,yBAAyB,EACpC,aAAa,EAAE,gBAAgB,EAC/B,YAAY,EAAE,SAAS,gBAAgB,EAAE;CAW1C"}
1
+ {"version":3,"file":"PersistenceErrors.d.ts","sourceRoot":"","sources":["../../src/persistence/PersistenceErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAe,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEpE,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC7B,CAAC;AAEF,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GAClC,aAAa,GACb,uBAAuB,GACvB,YAAY,GACZ,sBAAsB,GACtB,WAAW,GACX,eAAe,CAAC;AAEnB,8EAA8E;AAC9E,qBAAa,6BAA8B,SAAQ,uBAAuB;IACzE,SAAgB,SAAS,EAAE,yBAAyB,CAAC;IACrD,SAAgB,aAAa,EAAE,gBAAgB,CAAC;IAChD,SAAgB,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAC;gBAGzD,SAAS,EAAE,yBAAyB,EACpC,aAAa,EAAE,gBAAgB,EAC/B,YAAY,EAAE,SAAS,gBAAgB,EAAE;CAW1C"}
@@ -1,12 +1,4 @@
1
1
  import { ERROR_CODES, SequentialThinkingError } from "../errors.js";
2
- class PersistenceCapabilityError extends SequentialThinkingError {
3
- operation;
4
- constructor(operation){
5
- super(`Persistence backend does not support required session operation '${operation}'`, ERROR_CODES.PERSISTENCE_CAPABILITY_UNSUPPORTED);
6
- this.name = 'PersistenceCapabilityError';
7
- this.operation = operation;
8
- }
9
- }
10
2
  class PersistenceScopeMismatchError extends SequentialThinkingError {
11
3
  operation;
12
4
  expectedScope;
@@ -21,6 +13,6 @@ class PersistenceScopeMismatchError extends SequentialThinkingError {
21
13
  ];
22
14
  }
23
15
  }
24
- export { PersistenceCapabilityError, PersistenceScopeMismatchError };
16
+ export { PersistenceScopeMismatchError };
25
17
 
26
18
  //# sourceMappingURL=PersistenceErrors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/PersistenceErrors.js","sources":["../../src/persistence/PersistenceErrors.ts"],"sourcesContent":["import type { SessionScopedPersistenceOperation } from '../contracts/PersistenceBackend.js';\nimport type { BranchId, SessionId } from '../contracts/ids.js';\nimport { ERROR_CODES, SequentialThinkingError } from '../errors.js';\n\n/** Durable namespace associated with a persistence write. */\nexport type PersistenceScope = {\n\treadonly sessionId: SessionId;\n\treadonly branchId?: BranchId;\n};\n\n/** Operations whose payload ownership is validated before mutation. */\nexport type PersistenceWriteOperation =\n\t| 'saveThought'\n\t| 'saveThoughtForSession'\n\t| 'saveBranch'\n\t| 'saveBranchForSession'\n\t| 'saveEdges'\n\t| 'saveSummaries';\n\n/** Error raised when a custom backend lacks the complete scoped capability. */\nexport class PersistenceCapabilityError extends SequentialThinkingError {\n\tpublic readonly operation: SessionScopedPersistenceOperation;\n\n\tconstructor(operation: SessionScopedPersistenceOperation) {\n\t\tsuper(\n\t\t\t`Persistence backend does not support required session operation '${operation}'`,\n\t\t\tERROR_CODES.PERSISTENCE_CAPABILITY_UNSUPPORTED\n\t\t);\n\t\tthis.name = 'PersistenceCapabilityError';\n\t\tthis.operation = operation;\n\t}\n}\n\n/** Error raised before a write whose payload belongs to another namespace. */\nexport class PersistenceScopeMismatchError extends SequentialThinkingError {\n\tpublic readonly operation: PersistenceWriteOperation;\n\tpublic readonly expectedScope: PersistenceScope;\n\tpublic readonly actualScopes: readonly PersistenceScope[];\n\n\tconstructor(\n\t\toperation: PersistenceWriteOperation,\n\t\texpectedScope: PersistenceScope,\n\t\tactualScopes: readonly PersistenceScope[]\n\t) {\n\t\tsuper(\n\t\t\t`Persistence payload scope does not match '${expectedScope.sessionId}' for ${operation}`,\n\t\t\tERROR_CODES.PERSISTENCE_SCOPE_MISMATCH\n\t\t);\n\t\tthis.name = 'PersistenceScopeMismatchError';\n\t\tthis.operation = operation;\n\t\tthis.expectedScope = expectedScope;\n\t\tthis.actualScopes = [...actualScopes];\n\t}\n}\n"],"names":["PersistenceCapabilityError","SequentialThinkingError","operation","ERROR_CODES","PersistenceScopeMismatchError","expectedScope","actualScopes"],"mappings":";AAoBO,MAAMA,mCAAmCC;IAC/B,UAA6C;IAE7D,YAAYC,SAA4C,CAAE;QACzD,KAAK,CACJ,CAAC,iEAAiE,EAAEA,UAAU,CAAC,CAAC,EAChFC,YAAY,kCAAkC;QAE/C,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,SAAS,GAAGD;IAClB;AACD;AAGO,MAAME,sCAAsCH;IAClC,UAAqC;IACrC,cAAgC;IAChC,aAA0C;IAE1D,YACCC,SAAoC,EACpCG,aAA+B,EAC/BC,YAAyC,CACxC;QACD,KAAK,CACJ,CAAC,0CAA0C,EAAED,cAAc,SAAS,CAAC,MAAM,EAAEH,WAAW,EACxFC,YAAY,0BAA0B;QAEvC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,SAAS,GAAGD;QACjB,IAAI,CAAC,aAAa,GAAGG;QACrB,IAAI,CAAC,YAAY,GAAG;eAAIC;SAAa;IACtC;AACD"}
1
+ {"version":3,"file":"persistence/PersistenceErrors.js","sources":["../../src/persistence/PersistenceErrors.ts"],"sourcesContent":["import type { BranchId, SessionId } from '../contracts/ids.js';\nimport { ERROR_CODES, SequentialThinkingError } from '../errors.js';\n\n/** Durable namespace associated with a persistence write. */\nexport type PersistenceScope = {\n\treadonly sessionId: SessionId;\n\treadonly branchId?: BranchId;\n};\n\n/** Operations whose payload ownership is validated before mutation. */\nexport type PersistenceWriteOperation =\n\t| 'saveThought'\n\t| 'saveThoughtForSession'\n\t| 'saveBranch'\n\t| 'saveBranchForSession'\n\t| 'saveEdges'\n\t| 'saveSummaries';\n\n/** Error raised before a write whose payload belongs to another namespace. */\nexport class PersistenceScopeMismatchError extends SequentialThinkingError {\n\tpublic readonly operation: PersistenceWriteOperation;\n\tpublic readonly expectedScope: PersistenceScope;\n\tpublic readonly actualScopes: readonly PersistenceScope[];\n\n\tconstructor(\n\t\toperation: PersistenceWriteOperation,\n\t\texpectedScope: PersistenceScope,\n\t\tactualScopes: readonly PersistenceScope[]\n\t) {\n\t\tsuper(\n\t\t\t`Persistence payload scope does not match '${expectedScope.sessionId}' for ${operation}`,\n\t\t\tERROR_CODES.PERSISTENCE_SCOPE_MISMATCH\n\t\t);\n\t\tthis.name = 'PersistenceScopeMismatchError';\n\t\tthis.operation = operation;\n\t\tthis.expectedScope = expectedScope;\n\t\tthis.actualScopes = [...actualScopes];\n\t}\n}\n"],"names":["PersistenceScopeMismatchError","SequentialThinkingError","operation","expectedScope","actualScopes","ERROR_CODES"],"mappings":";AAmBO,MAAMA,sCAAsCC;IAClC,UAAqC;IACrC,cAAgC;IAChC,aAA0C;IAE1D,YACCC,SAAoC,EACpCC,aAA+B,EAC/BC,YAAyC,CACxC;QACD,KAAK,CACJ,CAAC,0CAA0C,EAAED,cAAc,SAAS,CAAC,MAAM,EAAED,WAAW,EACxFG,YAAY,0BAA0B;QAEvC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,SAAS,GAAGH;QACjB,IAAI,CAAC,aAAa,GAAGC;QACrB,IAAI,CAAC,YAAY,GAAG;eAAIC;SAAa;IACtC;AACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"PersistenceScope.d.ts","sourceRoot":"","sources":["../../src/persistence/PersistenceScope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAiC,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAInG,OAAO,EAGN,KAAK,yBAAyB,EAC9B,MAAM,wBAAwB,CAAC;AAIhC,KAAK,oBAAoB,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ,CAKpF;AAED,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,IAAI,SAAS,oBAAoB,EAAE,CAWrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,SAAS,0BAA0B,EAAE,EAClD,UAAU,EAAE,MAAM,GAChB,IAAI,CAqBN;AASD,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,OAAO,CAAC,yBAAyB,EAAE,aAAa,GAAG,uBAAuB,CAAC,EACtF,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,WAAW,GAClB,IAAI,CAKN;AAED,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,OAAO,CAAC,yBAAyB,EAAE,YAAY,GAAG,sBAAsB,CAAC,EACpF,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,IAAI,CAYN;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,CAOnF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAU7F;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,SAAS;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAC3C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,IAAI,CAWN;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,oBAAoB,CACnC,IAAI,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACzD,KAAK,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACxD,MAAM,CAER"}
1
+ {"version":3,"file":"PersistenceScope.d.ts","sourceRoot":"","sources":["../../src/persistence/PersistenceScope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAA2B,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE7F,OAAO,EAGN,KAAK,yBAAyB,EAC9B,MAAM,wBAAwB,CAAC;AAIhC,KAAK,oBAAoB,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ,CAKpF;AAED,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,IAAI,SAAS,oBAAoB,EAAE,CAWrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,SAAS,0BAA0B,EAAE,EAClD,UAAU,EAAE,MAAM,GAChB,IAAI,CAqBN;AASD,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,OAAO,CAAC,yBAAyB,EAAE,aAAa,GAAG,uBAAuB,CAAC,EACtF,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,WAAW,GAClB,IAAI,CAKN;AAED,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,OAAO,CAAC,yBAAyB,EAAE,YAAY,GAAG,sBAAsB,CAAC,EACpF,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,IAAI,CAYN;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,CAOnF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAU7F;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,SAAS;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAC3C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,IAAI,CAWN;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,oBAAoB,CACnC,IAAI,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACzD,KAAK,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACxD,MAAM,CAER"}
@@ -1,5 +1,5 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
- import { GLOBAL_SESSION_ID, asBranchId } from "../contracts/ids.js";
2
+ import { asBranchId, asSessionId } from "../contracts/ids.js";
3
3
  import { PersistenceCompatibilityError } from "../errors.js";
4
4
  import { PersistenceScopeMismatchError } from "./PersistenceErrors.js";
5
5
  const BRANCH_ID_PATTERN = /^[A-Za-z0-9_-]{1,50}$/;
@@ -34,7 +34,7 @@ function assertPersistableThoughtCollections(collections, sourcePath) {
34
34
  }
35
35
  function thoughtScope(thought) {
36
36
  return {
37
- sessionId: thought.session_id ?? GLOBAL_SESSION_ID,
37
+ sessionId: asSessionId(thought.session_id),
38
38
  ...void 0 === thought.branch_id ? {} : {
39
39
  branchId: thought.branch_id
40
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/PersistenceScope.js","sources":["../../src/persistence/PersistenceScope.ts"],"sourcesContent":["import { isDeepStrictEqual } from 'node:util';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport { asBranchId, GLOBAL_SESSION_ID, type BranchId, type SessionId } from '../contracts/ids.js';\nimport {\n\tPersistenceCompatibilityError,\n} from '../errors.js';\nimport {\n\tPersistenceScopeMismatchError,\n\ttype PersistenceScope,\n\ttype PersistenceWriteOperation,\n} from './PersistenceErrors.js';\n\nconst BRANCH_ID_PATTERN = /^[A-Za-z0-9_-]{1,50}$/;\n\ntype PersistedThoughtData = ThoughtData & { readonly id: string };\n\nexport interface PersistedThoughtCollection {\n\treadonly sessionId: SessionId;\n\treadonly thoughts: readonly ThoughtData[];\n}\n\nexport function parsePersistenceBranchId(value: string, sourcePath: string): BranchId {\n\tif (!BRANCH_ID_PATTERN.test(value)) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, `invalid branch id '${value}'`);\n\t}\n\treturn asBranchId(value);\n}\n\nexport function assertPersistableThoughts(\n\tthoughts: readonly ThoughtData[],\n\tsourcePath: string\n): asserts thoughts is readonly PersistedThoughtData[] {\n\tconst identifiers = new Set<string>();\n\tfor (const thought of thoughts) {\n\t\tif (thought.id === undefined || thought.id.length === 0) {\n\t\t\tthrow new PersistenceCompatibilityError(sourcePath, 'persisted thoughts require an id');\n\t\t}\n\t\tif (identifiers.has(thought.id)) {\n\t\t\tthrow new PersistenceCompatibilityError(sourcePath, `duplicate thought id '${thought.id}'`);\n\t\t}\n\t\tidentifiers.add(thought.id);\n\t}\n}\n\n/**\n * Enforces thought identity across session-tagged persisted arrays.\n *\n * Each array must contain unique IDs. Reuse between arrays is valid only for deeply equal\n * payloads in the same session; equal identifiers in different sessions are independent.\n *\n * @param collections - History and branch arrays tagged with their owning session.\n * @param sourcePath - Persistence location included in compatibility errors.\n * @returns Nothing when all collection identities are compatible.\n */\nexport function assertPersistableThoughtCollections(\n\tcollections: readonly PersistedThoughtCollection[],\n\tsourcePath: string\n): void {\n\tconst payloadsBySession = new Map<SessionId, Map<string, ThoughtData>>();\n\tfor (const collection of collections) {\n\t\tassertPersistableThoughts(collection.thoughts, sourcePath);\n\t\tlet sessionPayloads = payloadsBySession.get(collection.sessionId);\n\t\tif (sessionPayloads === undefined) {\n\t\t\tsessionPayloads = new Map<string, ThoughtData>();\n\t\t\tpayloadsBySession.set(collection.sessionId, sessionPayloads);\n\t\t}\n\t\tfor (const thought of collection.thoughts) {\n\t\t\tconst identifier = thought.id;\n\t\t\tconst existing = sessionPayloads.get(identifier);\n\t\t\tif (existing !== undefined && !isDeepStrictEqual(existing, thought)) {\n\t\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\t\tsourcePath,\n\t\t\t\t\t`conflicting thought id '${identifier}'`\n\t\t\t\t);\n\t\t\t}\n\t\t\tsessionPayloads.set(identifier, thought);\n\t\t}\n\t}\n}\n\nfunction thoughtScope(thought: ThoughtData): PersistenceScope {\n\treturn {\n\t\tsessionId: thought.session_id ?? GLOBAL_SESSION_ID,\n\t\t...(thought.branch_id === undefined ? {} : { branchId: thought.branch_id }),\n\t};\n}\n\nexport function assertThoughtScope(\n\toperation: Extract<PersistenceWriteOperation, 'saveThought' | 'saveThoughtForSession'>,\n\tsessionId: SessionId,\n\tthought: ThoughtData\n): void {\n\tconst actualScope = thoughtScope(thought);\n\tif (actualScope.sessionId !== sessionId) {\n\t\tthrow new PersistenceScopeMismatchError(operation, { sessionId }, [actualScope]);\n\t}\n}\n\nexport function assertBranchScope(\n\toperation: Extract<PersistenceWriteOperation, 'saveBranch' | 'saveBranchForSession'>,\n\tsessionId: SessionId,\n\tbranchId: BranchId,\n\tthoughts: readonly ThoughtData[]\n): void {\n\tconst expectedScope = { sessionId, branchId } satisfies PersistenceScope;\n\tconst mismatches = thoughts\n\t\t.map(thoughtScope)\n\t\t.filter(\n\t\t\t(scope) =>\n\t\t\t\tscope.sessionId !== expectedScope.sessionId ||\n\t\t\t\t(scope.branchId !== undefined && scope.branchId !== expectedScope.branchId)\n\t\t);\n\tif (mismatches.length > 0) {\n\t\tthrow new PersistenceScopeMismatchError(operation, expectedScope, mismatches);\n\t}\n}\n\nexport function assertEdgeScopes(sessionId: SessionId, edges: readonly Edge[]): void {\n\tconst actualScopes = edges\n\t\t.filter((edge) => edge.sessionId !== sessionId)\n\t\t.map((edge) => ({ sessionId: edge.sessionId }));\n\tif (actualScopes.length > 0) {\n\t\tthrow new PersistenceScopeMismatchError('saveEdges', { sessionId }, actualScopes);\n\t}\n}\n\nexport function assertSummaryScopes(sessionId: SessionId, summaries: readonly Summary[]): void {\n\tconst actualScopes = summaries\n\t\t.filter((summary) => summary.sessionId !== sessionId)\n\t\t.map((summary) => ({\n\t\t\tsessionId: summary.sessionId,\n\t\t\t...(summary.branchId === undefined ? {} : { branchId: summary.branchId }),\n\t\t}));\n\tif (actualScopes.length > 0) {\n\t\tthrow new PersistenceScopeMismatchError('saveSummaries', { sessionId }, actualScopes);\n\t}\n}\n\nexport function assertUniqueRecordIds(\n\trecords: readonly { readonly id: string }[],\n\tsourcePath: string,\n\trecordKind: 'edge' | 'summary'\n): void {\n\tconst identifiers = new Set<string>();\n\tfor (const record of records) {\n\t\tif (identifiers.has(record.id)) {\n\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\tsourcePath,\n\t\t\t\t`duplicate ${recordKind} id '${record.id}'`\n\t\t\t);\n\t\t}\n\t\tidentifiers.add(record.id);\n\t}\n}\n\nexport function compareCodePoint(left: string, right: string): number {\n\treturn left < right ? -1 : left > right ? 1 : 0;\n}\n\nexport function compareCreatedThenId(\n\tleft: { readonly createdAt: number; readonly id: string },\n\tright: { readonly createdAt: number; readonly id: string }\n): number {\n\treturn left.createdAt - right.createdAt || compareCodePoint(left.id, right.id);\n}\n"],"names":["BRANCH_ID_PATTERN","parsePersistenceBranchId","value","sourcePath","PersistenceCompatibilityError","asBranchId","assertPersistableThoughts","thoughts","identifiers","Set","thought","undefined","assertPersistableThoughtCollections","collections","payloadsBySession","Map","collection","sessionPayloads","identifier","existing","isDeepStrictEqual","thoughtScope","GLOBAL_SESSION_ID","assertThoughtScope","operation","sessionId","actualScope","PersistenceScopeMismatchError","assertBranchScope","branchId","expectedScope","mismatches","scope","assertEdgeScopes","edges","actualScopes","edge","assertSummaryScopes","summaries","summary","assertUniqueRecordIds","records","recordKind","record","compareCodePoint","left","right","compareCreatedThenId"],"mappings":"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"}
1
+ {"version":3,"file":"persistence/PersistenceScope.js","sources":["../../src/persistence/PersistenceScope.ts"],"sourcesContent":["import { isDeepStrictEqual } from 'node:util';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport { asBranchId, asSessionId, type BranchId, type SessionId } from '../contracts/ids.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport {\n\tPersistenceScopeMismatchError,\n\ttype PersistenceScope,\n\ttype PersistenceWriteOperation,\n} from './PersistenceErrors.js';\n\nconst BRANCH_ID_PATTERN = /^[A-Za-z0-9_-]{1,50}$/;\n\ntype PersistedThoughtData = ThoughtData & { readonly id: string };\n\nexport interface PersistedThoughtCollection {\n\treadonly sessionId: SessionId;\n\treadonly thoughts: readonly ThoughtData[];\n}\n\nexport function parsePersistenceBranchId(value: string, sourcePath: string): BranchId {\n\tif (!BRANCH_ID_PATTERN.test(value)) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, `invalid branch id '${value}'`);\n\t}\n\treturn asBranchId(value);\n}\n\nexport function assertPersistableThoughts(\n\tthoughts: readonly ThoughtData[],\n\tsourcePath: string\n): asserts thoughts is readonly PersistedThoughtData[] {\n\tconst identifiers = new Set<string>();\n\tfor (const thought of thoughts) {\n\t\tif (thought.id === undefined || thought.id.length === 0) {\n\t\t\tthrow new PersistenceCompatibilityError(sourcePath, 'persisted thoughts require an id');\n\t\t}\n\t\tif (identifiers.has(thought.id)) {\n\t\t\tthrow new PersistenceCompatibilityError(sourcePath, `duplicate thought id '${thought.id}'`);\n\t\t}\n\t\tidentifiers.add(thought.id);\n\t}\n}\n\n/**\n * Enforces thought identity across session-tagged persisted arrays.\n *\n * Each array must contain unique IDs. Reuse between arrays is valid only for deeply equal\n * payloads in the same session; equal identifiers in different sessions are independent.\n *\n * @param collections - History and branch arrays tagged with their owning session.\n * @param sourcePath - Persistence location included in compatibility errors.\n * @returns Nothing when all collection identities are compatible.\n */\nexport function assertPersistableThoughtCollections(\n\tcollections: readonly PersistedThoughtCollection[],\n\tsourcePath: string\n): void {\n\tconst payloadsBySession = new Map<SessionId, Map<string, ThoughtData>>();\n\tfor (const collection of collections) {\n\t\tassertPersistableThoughts(collection.thoughts, sourcePath);\n\t\tlet sessionPayloads = payloadsBySession.get(collection.sessionId);\n\t\tif (sessionPayloads === undefined) {\n\t\t\tsessionPayloads = new Map<string, ThoughtData>();\n\t\t\tpayloadsBySession.set(collection.sessionId, sessionPayloads);\n\t\t}\n\t\tfor (const thought of collection.thoughts) {\n\t\t\tconst identifier = thought.id;\n\t\t\tconst existing = sessionPayloads.get(identifier);\n\t\t\tif (existing !== undefined && !isDeepStrictEqual(existing, thought)) {\n\t\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\t\tsourcePath,\n\t\t\t\t\t`conflicting thought id '${identifier}'`\n\t\t\t\t);\n\t\t\t}\n\t\t\tsessionPayloads.set(identifier, thought);\n\t\t}\n\t}\n}\n\nfunction thoughtScope(thought: ThoughtData): PersistenceScope {\n\treturn {\n\t\tsessionId: asSessionId(thought.session_id),\n\t\t...(thought.branch_id === undefined ? {} : { branchId: thought.branch_id }),\n\t};\n}\n\nexport function assertThoughtScope(\n\toperation: Extract<PersistenceWriteOperation, 'saveThought' | 'saveThoughtForSession'>,\n\tsessionId: SessionId,\n\tthought: ThoughtData\n): void {\n\tconst actualScope = thoughtScope(thought);\n\tif (actualScope.sessionId !== sessionId) {\n\t\tthrow new PersistenceScopeMismatchError(operation, { sessionId }, [actualScope]);\n\t}\n}\n\nexport function assertBranchScope(\n\toperation: Extract<PersistenceWriteOperation, 'saveBranch' | 'saveBranchForSession'>,\n\tsessionId: SessionId,\n\tbranchId: BranchId,\n\tthoughts: readonly ThoughtData[]\n): void {\n\tconst expectedScope = { sessionId, branchId } satisfies PersistenceScope;\n\tconst mismatches = thoughts\n\t\t.map(thoughtScope)\n\t\t.filter(\n\t\t\t(scope) =>\n\t\t\t\tscope.sessionId !== expectedScope.sessionId ||\n\t\t\t\t(scope.branchId !== undefined && scope.branchId !== expectedScope.branchId)\n\t\t);\n\tif (mismatches.length > 0) {\n\t\tthrow new PersistenceScopeMismatchError(operation, expectedScope, mismatches);\n\t}\n}\n\nexport function assertEdgeScopes(sessionId: SessionId, edges: readonly Edge[]): void {\n\tconst actualScopes = edges\n\t\t.filter((edge) => edge.sessionId !== sessionId)\n\t\t.map((edge) => ({ sessionId: edge.sessionId }));\n\tif (actualScopes.length > 0) {\n\t\tthrow new PersistenceScopeMismatchError('saveEdges', { sessionId }, actualScopes);\n\t}\n}\n\nexport function assertSummaryScopes(sessionId: SessionId, summaries: readonly Summary[]): void {\n\tconst actualScopes = summaries\n\t\t.filter((summary) => summary.sessionId !== sessionId)\n\t\t.map((summary) => ({\n\t\t\tsessionId: summary.sessionId,\n\t\t\t...(summary.branchId === undefined ? {} : { branchId: summary.branchId }),\n\t\t}));\n\tif (actualScopes.length > 0) {\n\t\tthrow new PersistenceScopeMismatchError('saveSummaries', { sessionId }, actualScopes);\n\t}\n}\n\nexport function assertUniqueRecordIds(\n\trecords: readonly { readonly id: string }[],\n\tsourcePath: string,\n\trecordKind: 'edge' | 'summary'\n): void {\n\tconst identifiers = new Set<string>();\n\tfor (const record of records) {\n\t\tif (identifiers.has(record.id)) {\n\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\tsourcePath,\n\t\t\t\t`duplicate ${recordKind} id '${record.id}'`\n\t\t\t);\n\t\t}\n\t\tidentifiers.add(record.id);\n\t}\n}\n\nexport function compareCodePoint(left: string, right: string): number {\n\treturn left < right ? -1 : left > right ? 1 : 0;\n}\n\nexport function compareCreatedThenId(\n\tleft: { readonly createdAt: number; readonly id: string },\n\tright: { readonly createdAt: number; readonly id: string }\n): number {\n\treturn left.createdAt - right.createdAt || compareCodePoint(left.id, right.id);\n}\n"],"names":["BRANCH_ID_PATTERN","parsePersistenceBranchId","value","sourcePath","PersistenceCompatibilityError","asBranchId","assertPersistableThoughts","thoughts","identifiers","Set","thought","undefined","assertPersistableThoughtCollections","collections","payloadsBySession","Map","collection","sessionPayloads","identifier","existing","isDeepStrictEqual","thoughtScope","asSessionId","assertThoughtScope","operation","sessionId","actualScope","PersistenceScopeMismatchError","assertBranchScope","branchId","expectedScope","mismatches","scope","assertEdgeScopes","edges","actualScopes","edge","assertSummaryScopes","summaries","summary","assertUniqueRecordIds","records","recordKind","record","compareCodePoint","left","right","compareCreatedThenId"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import type { PersistenceConfig, SessionScopedPersistenceBackend } from '../contracts/PersistenceBackend.js';
1
+ import type { PersistenceConfig, PersistenceBackend } from '../contracts/PersistenceBackend.js';
2
2
  import { type BranchId, type SessionId } from '../contracts/ids.js';
3
3
  import type { Summary } from '../core/compression/Summary.js';
4
4
  import type { Edge } from '../core/graph/Edge.js';
5
5
  import type { ThoughtData } from '../core/thought.js';
6
6
  import type { SqliteDatabase } from './SqliteDriver.js';
7
7
  type SqliteOptions = PersistenceConfig['options'];
8
- export declare class SqlitePersistence implements SessionScopedPersistenceBackend {
8
+ export declare class SqlitePersistence implements PersistenceBackend {
9
9
  private readonly _db;
10
10
  private readonly _sourcePath;
11
11
  private readonly _maxHistorySize;
@@ -13,26 +13,19 @@ export declare class SqlitePersistence implements SessionScopedPersistenceBacken
13
13
  private constructor();
14
14
  static createWithDatabase(database: SqliteDatabase, options?: SqliteOptions, sourcePath?: string): SqlitePersistence;
15
15
  static create(options?: SqliteOptions): Promise<SqlitePersistence>;
16
- saveThought(thought: ThoughtData): Promise<void>;
17
16
  saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void>;
18
17
  private _saveThought;
19
- loadHistory(): Promise<ThoughtData[]>;
20
18
  loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]>;
21
- saveBranch(branchId: BranchId, thoughts: ThoughtData[]): Promise<void>;
22
19
  saveBranchForSession(sessionId: SessionId, branchId: BranchId, thoughts: readonly ThoughtData[]): Promise<void>;
23
20
  private _saveBranch;
24
- deleteBranch(branchId: BranchId): Promise<void>;
25
21
  deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void>;
26
- loadBranch(branchId: BranchId): Promise<ThoughtData[] | undefined>;
27
22
  loadBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<ThoughtData[] | undefined>;
28
- listBranches(): Promise<BranchId[]>;
29
23
  listBranchesForSession(sessionId: SessionId): Promise<BranchId[]>;
30
24
  listSessions(): Promise<SessionId[]>;
31
- clear(): Promise<void>;
25
+ clearAll(): Promise<void>;
32
26
  clearSession(sessionId: SessionId): Promise<void>;
33
27
  saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void>;
34
28
  loadEdges(sessionId: SessionId): Promise<Edge[]>;
35
- listEdgeSessions(): Promise<SessionId[]>;
36
29
  saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void>;
37
30
  loadSummaries(sessionId: SessionId): Promise<Summary[]>;
38
31
  healthy(): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"SqlitePersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/SqlitePersistence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SqlitePersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/SqlitePersistence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAe,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAA6B,MAAM,mBAAmB,CAAC;AAsBnF,KAAK,aAAa,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAOlD,qBAAa,iBAAkB,YAAW,kBAAkB;IAE1D,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAJlC,OAAO;WAOO,kBAAkB,CAC/B,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,aAAkB,EAC3B,UAAU,SAAwB,GAChC,iBAAiB;WAUA,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgClE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7F,OAAO,CAAC,YAAY;IAwBP,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAQnE,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;IAOhB,OAAO,CAAC,WAAW;IAoBN,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/E,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IASxB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAUjE,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAUpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtE,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAUhD,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBjF,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAUvD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAU3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,QAAQ,IAAI;QAClB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACxB;IAcD,OAAO,CAAC,0BAA0B;IAoDlC,OAAO,CAAC,eAAe;CAMvB"}
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
- import { GLOBAL_SESSION_ID, asSessionId } from "../contracts/ids.js";
4
+ import { asSessionId } from "../contracts/ids.js";
5
5
  import { PersistenceCompatibilityError, PersistenceCorruptionError } from "../errors.js";
6
6
  import { runSqliteReadTransaction, runSqliteTransaction } from "./SqliteDriver.js";
7
7
  import { decodeEdgeRow, decodeSummaryRow, decodeThoughtRow, numberField, stringField } from "./SqlitePayload.js";
@@ -47,10 +47,6 @@ class SqlitePersistence {
47
47
  throw error;
48
48
  }
49
49
  }
50
- async saveThought(thought) {
51
- assertThoughtScope('saveThought', GLOBAL_SESSION_ID, thought);
52
- this._saveThought(GLOBAL_SESSION_ID, thought);
53
- }
54
50
  async saveThoughtForSession(sessionId, thought) {
55
51
  const validatedSessionId = asSessionId(sessionId);
56
52
  assertThoughtScope('saveThoughtForSession', validatedSessionId, thought);
@@ -69,18 +65,10 @@ class SqlitePersistence {
69
65
  }
70
66
  });
71
67
  }
72
- async loadHistory() {
73
- return await this.loadHistoryForSession(GLOBAL_SESSION_ID);
74
- }
75
68
  async loadHistoryForSession(sessionId) {
76
69
  const validatedSessionId = asSessionId(sessionId);
77
70
  return runSqliteReadTransaction(this._db, ()=>this._loadValidatedThoughtState(validatedSessionId).history);
78
71
  }
79
- async saveBranch(branchId, thoughts) {
80
- const validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);
81
- assertBranchScope('saveBranch', GLOBAL_SESSION_ID, validatedBranchId, thoughts);
82
- this._saveBranch(GLOBAL_SESSION_ID, validatedBranchId, thoughts);
83
- }
84
72
  async saveBranchForSession(sessionId, branchId, thoughts) {
85
73
  const validatedSessionId = asSessionId(sessionId);
86
74
  const validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);
@@ -95,9 +83,6 @@ class SqlitePersistence {
95
83
  this._db.prepare('INSERT OR REPLACE INTO branches (session_id, branch_id, data) VALUES (?, ?, ?)').run(sessionId, branchId, JSON.stringify(thoughts));
96
84
  });
97
85
  }
98
- async deleteBranch(branchId) {
99
- await this.deleteBranchForSession(GLOBAL_SESSION_ID, branchId);
100
- }
101
86
  async deleteBranchForSession(sessionId, branchId) {
102
87
  if (!this._persistBranches) return;
103
88
  const validatedSessionId = asSessionId(sessionId);
@@ -106,18 +91,12 @@ class SqlitePersistence {
106
91
  this._db.prepare('DELETE FROM branches WHERE session_id = ? AND branch_id = ?').run(validatedSessionId, validatedBranchId);
107
92
  });
108
93
  }
109
- async loadBranch(branchId) {
110
- return await this.loadBranchForSession(GLOBAL_SESSION_ID, branchId);
111
- }
112
94
  async loadBranchForSession(sessionId, branchId) {
113
95
  if (!this._persistBranches) return;
114
96
  const validatedSessionId = asSessionId(sessionId);
115
97
  const validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);
116
98
  return runSqliteReadTransaction(this._db, ()=>this._loadValidatedThoughtState(validatedSessionId).branches.get(validatedBranchId));
117
99
  }
118
- async listBranches() {
119
- return await this.listBranchesForSession(GLOBAL_SESSION_ID);
120
- }
121
100
  async listBranchesForSession(sessionId) {
122
101
  if (!this._persistBranches) return [];
123
102
  return this._db.prepare('SELECT branch_id FROM branches WHERE session_id = ? ORDER BY branch_id ASC').all(asSessionId(sessionId)).map((row)=>parsePersistenceBranchId(stringField(row, 'branch_id', this._sourcePath), this._sourcePath));
@@ -125,7 +104,7 @@ class SqlitePersistence {
125
104
  async listSessions() {
126
105
  return this._db.prepare('SELECT session_id FROM thoughts UNION SELECT session_id FROM branches UNION SELECT session_id FROM edges UNION SELECT session_id FROM summaries').all().map((row)=>asSessionId(stringField(row, 'session_id', this._sourcePath))).sort(compareCodePoint);
127
106
  }
128
- async clear() {
107
+ async clearAll() {
129
108
  runSqliteTransaction(this._db, ()=>{
130
109
  for (const table of [
131
110
  'thoughts',
@@ -159,9 +138,6 @@ class SqlitePersistence {
159
138
  const validatedSessionId = asSessionId(sessionId);
160
139
  return this._db.prepare('SELECT id, session_id, from_id, to_id, kind, created_at, metadata FROM edges WHERE session_id = ? ORDER BY created_at ASC, id ASC').all(validatedSessionId).map((row, index)=>decodeEdgeRow(row, `${this._sourcePath}:edges:${index}`));
161
140
  }
162
- async listEdgeSessions() {
163
- return this._db.prepare('SELECT DISTINCT session_id FROM edges ORDER BY session_id ASC').all().map((row)=>asSessionId(stringField(row, 'session_id', this._sourcePath)));
164
- }
165
141
  async saveSummaries(sessionId, summaries) {
166
142
  const validatedSessionId = asSessionId(sessionId);
167
143
  assertSummaryScopes(validatedSessionId, summaries);
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/SqlitePersistence.js","sources":["../../src/persistence/SqlitePersistence.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type {\n\tPersistenceConfig,\n\tSessionScopedPersistenceBackend,\n} from '../contracts/PersistenceBackend.js';\nimport { asSessionId, GLOBAL_SESSION_ID, type BranchId, type SessionId } from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError, PersistenceCorruptionError } from '../errors.js';\nimport type { SqliteDatabase, SqliteDatabaseConstructor } from './SqliteDriver.js';\nimport { runSqliteReadTransaction, runSqliteTransaction } from './SqliteDriver.js';\nimport {\n\tdecodeEdgeRow,\n\tdecodeSummaryRow,\n\tdecodeThoughtRow,\n\tnumberField,\n\tstringField,\n} from './SqlitePayload.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertPersistableThoughts,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tcompareCodePoint,\n\tparsePersistenceBranchId,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\nimport { initializeOrValidateSqliteV2 } from './SqliteSchemaV2.js';\n\ntype SqliteOptions = PersistenceConfig['options'];\n\ntype ValidatedThoughtState = {\n\treadonly history: ThoughtData[];\n\treadonly branches: ReadonlyMap<BranchId, ThoughtData[]>;\n};\n\nexport class SqlitePersistence implements SessionScopedPersistenceBackend {\n\tprivate constructor(\n\t\tprivate readonly _db: SqliteDatabase,\n\t\tprivate readonly _sourcePath: string,\n\t\tprivate readonly _maxHistorySize: number,\n\t\tprivate readonly _persistBranches: boolean\n\t) {}\n\n\tpublic static createWithDatabase(\n\t\tdatabase: SqliteDatabase,\n\t\toptions: SqliteOptions = {},\n\t\tsourcePath = '<structural-sqlite>'\n\t): SqlitePersistence {\n\t\tinitializeOrValidateSqliteV2(database, sourcePath);\n\t\treturn new SqlitePersistence(\n\t\t\tdatabase,\n\t\t\tsourcePath,\n\t\t\toptions?.maxHistorySize ?? 10000,\n\t\t\toptions?.persistBranches ?? true\n\t\t);\n\t}\n\n\tpublic static async create(options?: SqliteOptions): Promise<SqlitePersistence> {\n\t\tconst defaultDataDir = existsSync('.claude/data')\n\t\t\t? '.claude/data'\n\t\t\t: join(homedir(), '.claude/data');\n\t\tconst dbPath = options?.dbPath ?? join(defaultDataDir, 'history.db');\n\t\tlet Database: SqliteDatabaseConstructor;\n\t\ttry {\n\t\t\tconst module = await import('better-sqlite3');\n\t\t\tDatabase = module.default;\n\t\t} catch (error) {\n\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\tdbPath,\n\t\t\t\t\"SQLite persistence requires the optional 'better-sqlite3' package\",\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t\tconst database = new Database(dbPath);\n\t\ttry {\n\t\t\tconst persistence = SqlitePersistence.createWithDatabase(database, options, dbPath);\n\t\t\tif (options?.enableWAL !== false) database.pragma('journal_mode = WAL');\n\t\t\tdatabase.pragma('synchronous = NORMAL');\n\t\t\tdatabase.pragma('foreign_keys = ON');\n\t\t\tdatabase.pragma('busy_timeout = 5000');\n\t\t\tdatabase.pragma('cache_size = -64000');\n\t\t\tdatabase.pragma('temp_store = MEMORY');\n\t\t\treturn persistence;\n\t\t} catch (error) {\n\t\t\tdatabase.close();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async saveThought(thought: ThoughtData): Promise<void> {\n\t\tassertThoughtScope('saveThought', GLOBAL_SESSION_ID, thought);\n\t\tthis._saveThought(GLOBAL_SESSION_ID, thought);\n\t}\n\n\tpublic async saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope('saveThoughtForSession', validatedSessionId, thought);\n\t\tthis._saveThought(validatedSessionId, thought);\n\t}\n\n\tprivate _saveThought(sessionId: SessionId, thought: ThoughtData): void {\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._loadValidatedThoughtState(sessionId, [thought]);\n\t\t\tthis._db\n\t\t\t\t.prepare('INSERT INTO thoughts (session_id, data) VALUES (?, ?)')\n\t\t\t\t.run(sessionId, JSON.stringify(thought));\n\t\t\tif (this._maxHistorySize > 0) {\n\t\t\t\tconst countRow = this._db\n\t\t\t\t\t.prepare('SELECT COUNT(*) AS count FROM thoughts WHERE session_id = ?')\n\t\t\t\t\t.get(sessionId);\n\t\t\t\tconst excess =\n\t\t\t\t\tnumberField(countRow, 'count', `${this._sourcePath}:thought-count`) -\n\t\t\t\t\tthis._maxHistorySize;\n\t\t\t\tif (excess > 0) {\n\t\t\t\t\tthis._db\n\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t'DELETE FROM thoughts WHERE id IN (SELECT id FROM thoughts WHERE session_id = ? ORDER BY id ASC LIMIT ?)'\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.run(sessionId, excess);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic async loadHistory(): Promise<ThoughtData[]> {\n\t\treturn await this.loadHistoryForSession(GLOBAL_SESSION_ID);\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn runSqliteReadTransaction(\n\t\t\tthis._db,\n\t\t\t() => this._loadValidatedThoughtState(validatedSessionId).history\n\t\t);\n\t}\n\n\tpublic async saveBranch(branchId: BranchId, thoughts: ThoughtData[]): Promise<void> {\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\tassertBranchScope('saveBranch', GLOBAL_SESSION_ID, validatedBranchId, thoughts);\n\t\tthis._saveBranch(GLOBAL_SESSION_ID, validatedBranchId, thoughts);\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tthis._saveBranch(validatedSessionId, validatedBranchId, thoughts);\n\t}\n\n\tprivate _saveBranch(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): void {\n\t\tassertPersistableThoughts(thoughts, `${this._sourcePath}:branch:${branchId}`);\n\t\tif (!this._persistBranches) {\n\t\t\trunSqliteReadTransaction(this._db, () =>\n\t\t\t\tthis._loadValidatedThoughtState(sessionId, thoughts, branchId)\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._loadValidatedThoughtState(sessionId, thoughts, branchId);\n\t\t\tthis._db\n\t\t\t\t.prepare('INSERT OR REPLACE INTO branches (session_id, branch_id, data) VALUES (?, ?, ?)')\n\t\t\t\t.run(sessionId, branchId, JSON.stringify(thoughts));\n\t\t});\n\t}\n\n\tpublic async deleteBranch(branchId: BranchId): Promise<void> {\n\t\tawait this.deleteBranchForSession(GLOBAL_SESSION_ID, branchId);\n\t}\n\n\tpublic async deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void> {\n\t\tif (!this._persistBranches) return;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._db\n\t\t\t\t.prepare('DELETE FROM branches WHERE session_id = ? AND branch_id = ?')\n\t\t\t\t.run(validatedSessionId, validatedBranchId);\n\t\t});\n\t}\n\n\tpublic async loadBranch(branchId: BranchId): Promise<ThoughtData[] | undefined> {\n\t\treturn await this.loadBranchForSession(GLOBAL_SESSION_ID, branchId);\n\t}\n\n\tpublic async loadBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId\n\t): Promise<ThoughtData[] | undefined> {\n\t\tif (!this._persistBranches) return undefined;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\treturn runSqliteReadTransaction(this._db, () =>\n\t\t\tthis._loadValidatedThoughtState(validatedSessionId).branches.get(validatedBranchId)\n\t\t);\n\t}\n\n\tpublic async listBranches(): Promise<BranchId[]> {\n\t\treturn await this.listBranchesForSession(GLOBAL_SESSION_ID);\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\treturn this._db\n\t\t\t.prepare('SELECT branch_id FROM branches WHERE session_id = ? ORDER BY branch_id ASC')\n\t\t\t.all(asSessionId(sessionId))\n\t\t\t.map((row) =>\n\t\t\t\tparsePersistenceBranchId(stringField(row, 'branch_id', this._sourcePath), this._sourcePath)\n\t\t\t);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\treturn this._db\n\t\t\t.prepare(\n\t\t\t\t'SELECT session_id FROM thoughts UNION SELECT session_id FROM branches UNION SELECT session_id FROM edges UNION SELECT session_id FROM summaries'\n\t\t\t)\n\t\t\t.all()\n\t\t\t.map((row) => asSessionId(stringField(row, 'session_id', this._sourcePath)))\n\t\t\t.sort(compareCodePoint);\n\t}\n\n\tpublic async clear(): Promise<void> {\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tfor (const table of ['thoughts', 'branches', 'edges', 'summaries'])\n\t\t\t\tthis._db.exec(`DELETE FROM ${table}`);\n\t\t});\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tfor (const table of ['thoughts', 'branches', 'edges', 'summaries']) {\n\t\t\t\tthis._db.prepare(`DELETE FROM ${table} WHERE session_id = ?`).run(validatedSessionId);\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic async saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertEdgeScopes(validatedSessionId, edges);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._db.prepare('DELETE FROM edges WHERE session_id = ?').run(validatedSessionId);\n\t\t\tconst insert = this._db.prepare(\n\t\t\t\t'INSERT INTO edges (id, session_id, from_id, to_id, kind, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)'\n\t\t\t);\n\t\t\tfor (const edge of edges)\n\t\t\t\tinsert.run(\n\t\t\t\t\tedge.id,\n\t\t\t\t\tedge.sessionId,\n\t\t\t\t\tedge.from,\n\t\t\t\t\tedge.to,\n\t\t\t\t\tedge.kind,\n\t\t\t\t\tedge.createdAt,\n\t\t\t\t\tedge.metadata === undefined ? null : JSON.stringify(edge.metadata)\n\t\t\t\t);\n\t\t});\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn this._db\n\t\t\t.prepare(\n\t\t\t\t'SELECT id, session_id, from_id, to_id, kind, created_at, metadata FROM edges WHERE session_id = ? ORDER BY created_at ASC, id ASC'\n\t\t\t)\n\t\t\t.all(validatedSessionId)\n\t\t\t.map((row, index) => decodeEdgeRow(row, `${this._sourcePath}:edges:${index}`));\n\t}\n\n\tpublic async listEdgeSessions(): Promise<SessionId[]> {\n\t\treturn this._db\n\t\t\t.prepare('SELECT DISTINCT session_id FROM edges ORDER BY session_id ASC')\n\t\t\t.all()\n\t\t\t.map((row) => asSessionId(stringField(row, 'session_id', this._sourcePath)));\n\t}\n\n\tpublic async saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertSummaryScopes(validatedSessionId, summaries);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._db.prepare('DELETE FROM summaries WHERE session_id = ?').run(validatedSessionId);\n\t\t\tconst insert = this._db.prepare(\n\t\t\t\t'INSERT INTO summaries (id, session_id, branch_id, root_thought_id, covered_ids, covered_range_start, covered_range_end, topics, aggregate_confidence, created_at, meta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'\n\t\t\t);\n\t\t\tfor (const summary of summaries)\n\t\t\t\tinsert.run(\n\t\t\t\t\tsummary.id,\n\t\t\t\t\tsummary.sessionId,\n\t\t\t\t\tsummary.branchId ?? null,\n\t\t\t\t\tsummary.rootThoughtId,\n\t\t\t\t\tJSON.stringify(summary.coveredIds),\n\t\t\t\t\tsummary.coveredRange[0],\n\t\t\t\t\tsummary.coveredRange[1],\n\t\t\t\t\tJSON.stringify(summary.topics),\n\t\t\t\t\tsummary.aggregateConfidence,\n\t\t\t\t\tsummary.createdAt,\n\t\t\t\t\tsummary.meta === undefined ? null : JSON.stringify(summary.meta)\n\t\t\t\t);\n\t\t});\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn this._db\n\t\t\t.prepare(\n\t\t\t\t'SELECT id, session_id, branch_id, root_thought_id, covered_ids, covered_range_start, covered_range_end, topics, aggregate_confidence, created_at, meta FROM summaries WHERE session_id = ? ORDER BY created_at ASC, id ASC'\n\t\t\t)\n\t\t\t.all(validatedSessionId)\n\t\t\t.map((row, index) => decodeSummaryRow(row, `${this._sourcePath}:summaries:${index}`));\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tthis._db.prepare('SELECT 1').get();\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) return false;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tthis._db.close();\n\t}\n\n\tpublic getStats(): {\n\t\treadonly thoughtCount: number;\n\t\treadonly branchCount: number;\n\t\treadonly dbSize: number;\n\t} {\n\t\tconst thoughtCount = numberField(\n\t\t\tthis._db.prepare('SELECT COUNT(*) AS count FROM thoughts').get(),\n\t\t\t'count',\n\t\t\tthis._sourcePath\n\t\t);\n\t\tconst branchCount = numberField(\n\t\t\tthis._db.prepare('SELECT COUNT(*) AS count FROM branches').get(),\n\t\t\t'count',\n\t\t\tthis._sourcePath\n\t\t);\n\t\treturn { thoughtCount, branchCount: this._persistBranches ? branchCount : 0, dbSize: 0 };\n\t}\n\n\tprivate _loadValidatedThoughtState(\n\t\tsessionId: SessionId,\n\t\tcandidates: readonly ThoughtData[] = [],\n\t\treplacingBranch?: BranchId\n\t): ValidatedThoughtState {\n\t\tconst history = this.loadHistoryRows(sessionId);\n\t\tfor (const thought of history) {\n\t\t\tassertThoughtScope('saveThoughtForSession', sessionId, thought);\n\t\t}\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{\n\t\t\t\tsessionId,\n\t\t\t\tthoughts: replacingBranch === undefined ? [...history, ...candidates] : history,\n\t\t\t},\n\t\t];\n\t\tconst branches = new Map<BranchId, ThoughtData[]>();\n\t\tfor (const row of this._db\n\t\t\t.prepare('SELECT branch_id, data FROM branches WHERE session_id = ?')\n\t\t\t.all(sessionId)) {\n\t\t\tconst branchId = parsePersistenceBranchId(\n\t\t\t\tstringField(row, 'branch_id', this._sourcePath),\n\t\t\t\tthis._sourcePath\n\t\t\t);\n\t\t\tconst data = stringField(row, 'data', this._sourcePath);\n\t\t\tlet values: unknown;\n\t\t\ttry {\n\t\t\t\tvalues = JSON.parse(data);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new PersistenceCorruptionError(this._sourcePath, error);\n\t\t\t}\n\t\t\tif (!Array.isArray(values))\n\t\t\t\tthrow new PersistenceCorruptionError(\n\t\t\t\t\tthis._sourcePath,\n\t\t\t\t\tnew TypeError('branch data is not an array')\n\t\t\t\t);\n\t\t\tconst thoughts = values.map((value, index) =>\n\t\t\t\tdecodeThoughtRow(\n\t\t\t\t\t{ data: JSON.stringify(value) },\n\t\t\t\t\t`${this._sourcePath}:branch:${sessionId}:${branchId}:${index}`\n\t\t\t\t)\n\t\t\t);\n\t\t\tassertBranchScope('saveBranchForSession', sessionId, branchId, thoughts);\n\t\t\tbranches.set(branchId, thoughts);\n\t\t\tif (branchId !== replacingBranch) collections.push({ sessionId, thoughts });\n\t\t}\n\t\tif (replacingBranch !== undefined) {\n\t\t\tcollections.push({ sessionId, thoughts: candidates });\n\t\t}\n\t\tassertPersistableThoughtCollections(collections, this._sourcePath);\n\t\treturn { history, branches };\n\t}\n\n\tprivate loadHistoryRows(sessionId: SessionId): ThoughtData[] {\n\t\treturn this._db\n\t\t\t.prepare('SELECT data FROM thoughts WHERE session_id = ? ORDER BY id ASC')\n\t\t\t.all(sessionId)\n\t\t\t.map((row) => decodeThoughtRow(row, this._sourcePath));\n\t}\n}\n"],"names":["SqlitePersistence","_db","_sourcePath","_maxHistorySize","_persistBranches","database","options","sourcePath","initializeOrValidateSqliteV2","defaultDataDir","existsSync","join","homedir","dbPath","Database","module","error","PersistenceCompatibilityError","persistence","thought","assertThoughtScope","GLOBAL_SESSION_ID","sessionId","validatedSessionId","asSessionId","runSqliteTransaction","JSON","countRow","excess","numberField","runSqliteReadTransaction","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","assertPersistableThoughts","row","stringField","compareCodePoint","table","edges","assertEdgeScopes","insert","edge","undefined","index","decodeEdgeRow","summaries","assertSummaryScopes","summary","decodeSummaryRow","Error","thoughtCount","branchCount","candidates","replacingBranch","history","collections","branches","Map","data","values","PersistenceCorruptionError","Array","TypeError","value","decodeThoughtRow","assertPersistableThoughtCollections"],"mappings":";;;;;;;;;AAyCO,MAAMA;;;;;IACZ,YACkBC,GAAmB,EACnBC,WAAmB,EACnBC,eAAuB,EACvBC,gBAAyB,CACzC;aAJgBH,GAAG,GAAHA;aACAC,WAAW,GAAXA;aACAC,eAAe,GAAfA;aACAC,gBAAgB,GAAhBA;IACf;IAEH,OAAc,mBACbC,QAAwB,EACxBC,UAAyB,CAAC,CAAC,EAC3BC,aAAa,qBAAqB,EACd;QACpBC,6BAA6BH,UAAUE;QACvC,OAAO,IAAIP,kBACVK,UACAE,YACAD,SAAS,kBAAkB,OAC3BA,SAAS,mBAAmB;IAE9B;IAEA,aAAoB,OAAOA,OAAuB,EAA8B;QAC/E,MAAMG,iBAAiBC,WAAW,kBAC/B,iBACAC,KAAKC,WAAW;QACnB,MAAMC,SAASP,SAAS,UAAUK,KAAKF,gBAAgB;QACvD,IAAIK;QACJ,IAAI;YACH,MAAMC,SAAS,MAAM,MAAM,CAAC;YAC5BD,WAAWC,OAAO,OAAO;QAC1B,EAAE,OAAOC,OAAO;YACf,MAAM,IAAIC,8BACTJ,QACA,qEACAG;QAEF;QACA,MAAMX,WAAW,IAAIS,SAASD;QAC9B,IAAI;YACH,MAAMK,cAAclB,kBAAkB,kBAAkB,CAACK,UAAUC,SAASO;YAC5E,IAAIP,SAAS,cAAc,OAAOD,SAAS,MAAM,CAAC;YAClDA,SAAS,MAAM,CAAC;YAChBA,SAAS,MAAM,CAAC;YAChBA,SAAS,MAAM,CAAC;YAChBA,SAAS,MAAM,CAAC;YAChBA,SAAS,MAAM,CAAC;YAChB,OAAOa;QACR,EAAE,OAAOF,OAAO;YACfX,SAAS,KAAK;YACd,MAAMW;QACP;IACD;IAEA,MAAa,YAAYG,OAAoB,EAAiB;QAC7DC,mBAAmB,eAAeC,mBAAmBF;QACrD,IAAI,CAAC,YAAY,CAACE,mBAAmBF;IACtC;IAEA,MAAa,sBAAsBG,SAAoB,EAAEH,OAAoB,EAAiB;QAC7F,MAAMI,qBAAqBC,YAAYF;QACvCF,mBAAmB,yBAAyBG,oBAAoBJ;QAChE,IAAI,CAAC,YAAY,CAACI,oBAAoBJ;IACvC;IAEQ,aAAaG,SAAoB,EAAEH,OAAoB,EAAQ;QACtEM,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,0BAA0B,CAACH,WAAW;gBAACH;aAAQ;YACpD,IAAI,CAAC,GAAG,CACN,OAAO,CAAC,yDACR,GAAG,CAACG,WAAWI,KAAK,SAAS,CAACP;YAChC,IAAI,IAAI,CAAC,eAAe,GAAG,GAAG;gBAC7B,MAAMQ,WAAW,IAAI,CAAC,GAAG,CACvB,OAAO,CAAC,+DACR,GAAG,CAACL;gBACN,MAAMM,SACLC,YAAYF,UAAU,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,IAClE,IAAI,CAAC,eAAe;gBACrB,IAAIC,SAAS,GACZ,IAAI,CAAC,GAAG,CACN,OAAO,CACP,2GAEA,GAAG,CAACN,WAAWM;YAEnB;QACD;IACD;IAEA,MAAa,cAAsC;QAClD,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAACP;IACzC;IAEA,MAAa,sBAAsBC,SAAoB,EAA0B;QAChF,MAAMC,qBAAqBC,YAAYF;QACvC,OAAOQ,yBACN,IAAI,CAAC,GAAG,EACR,IAAM,IAAI,CAAC,0BAA0B,CAACP,oBAAoB,OAAO;IAEnE;IAEA,MAAa,WAAWQ,QAAkB,EAAEC,QAAuB,EAAiB;QACnF,MAAMC,oBAAoBC,yBAAyBH,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;QAC3FI,kBAAkB,cAAcd,mBAAmBY,mBAAmBD;QACtE,IAAI,CAAC,WAAW,CAACX,mBAAmBY,mBAAmBD;IACxD;IAEA,MAAa,qBACZV,SAAoB,EACpBS,QAAkB,EAClBC,QAAgC,EAChB;QAChB,MAAMT,qBAAqBC,YAAYF;QACvC,MAAMW,oBAAoBC,yBAAyBH,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;QAC3FI,kBAAkB,wBAAwBZ,oBAAoBU,mBAAmBD;QACjF,IAAI,CAAC,WAAW,CAACT,oBAAoBU,mBAAmBD;IACzD;IAEQ,YACPV,SAAoB,EACpBS,QAAkB,EAClBC,QAAgC,EACzB;QACPI,0BAA0BJ,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAED,UAAU;QAC5E,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,YAC3BD,yBAAyB,IAAI,CAAC,GAAG,EAAE,IAClC,IAAI,CAAC,0BAA0B,CAACR,WAAWU,UAAUD;QAIvDN,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,0BAA0B,CAACH,WAAWU,UAAUD;YACrD,IAAI,CAAC,GAAG,CACN,OAAO,CAAC,kFACR,GAAG,CAACT,WAAWS,UAAUL,KAAK,SAAS,CAACM;QAC3C;IACD;IAEA,MAAa,aAAaD,QAAkB,EAAiB;QAC5D,MAAM,IAAI,CAAC,sBAAsB,CAACV,mBAAmBU;IACtD;IAEA,MAAa,uBAAuBT,SAAoB,EAAES,QAAkB,EAAiB;QAC5F,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAC5B,MAAMR,qBAAqBC,YAAYF;QACvC,MAAMW,oBAAoBC,yBAAyBH,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;QAC3FN,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,GAAG,CACN,OAAO,CAAC,+DACR,GAAG,CAACF,oBAAoBU;QAC3B;IACD;IAEA,MAAa,WAAWF,QAAkB,EAAsC;QAC/E,OAAO,MAAM,IAAI,CAAC,oBAAoB,CAACV,mBAAmBU;IAC3D;IAEA,MAAa,qBACZT,SAAoB,EACpBS,QAAkB,EACmB;QACrC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAC5B,MAAMR,qBAAqBC,YAAYF;QACvC,MAAMW,oBAAoBC,yBAAyBH,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;QAC3F,OAAOD,yBAAyB,IAAI,CAAC,GAAG,EAAE,IACzC,IAAI,CAAC,0BAA0B,CAACP,oBAAoB,QAAQ,CAAC,GAAG,CAACU;IAEnE;IAEA,MAAa,eAAoC;QAChD,OAAO,MAAM,IAAI,CAAC,sBAAsB,CAACZ;IAC1C;IAEA,MAAa,uBAAuBC,SAAoB,EAAuB;QAC9E,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,EAAE;QACrC,OAAO,IAAI,CAAC,GAAG,CACb,OAAO,CAAC,8EACR,GAAG,CAACE,YAAYF,YAChB,GAAG,CAAC,CAACe,MACLH,yBAAyBI,YAAYD,KAAK,aAAa,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW;IAE7F;IAEA,MAAa,eAAqC;QACjD,OAAO,IAAI,CAAC,GAAG,CACb,OAAO,CACP,mJAEA,GAAG,GACH,GAAG,CAAC,CAACA,MAAQb,YAAYc,YAAYD,KAAK,cAAc,IAAI,CAAC,WAAW,IACxE,IAAI,CAACE;IACR;IAEA,MAAa,QAAuB;QACnCd,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,KAAK,MAAMe,SAAS;gBAAC;gBAAY;gBAAY;gBAAS;aAAY,CACjE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,YAAY,EAAEA,OAAO;QACtC;IACD;IAEA,MAAa,aAAalB,SAAoB,EAAiB;QAC9D,MAAMC,qBAAqBC,YAAYF;QACvCG,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,KAAK,MAAMe,SAAS;gBAAC;gBAAY;gBAAY;gBAAS;aAAY,CACjE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,YAAY,EAAEA,MAAM,qBAAqB,CAAC,EAAE,GAAG,CAACjB;QAEpE;IACD;IAEA,MAAa,UAAUD,SAAoB,EAAEmB,KAAsB,EAAiB;QACnF,MAAMlB,qBAAqBC,YAAYF;QACvCoB,iBAAiBnB,oBAAoBkB;QACrChB,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,0CAA0C,GAAG,CAACF;YAC/D,MAAMoB,SAAS,IAAI,CAAC,GAAG,CAAC,OAAO,CAC9B;YAED,KAAK,MAAMC,QAAQH,MAClBE,OAAO,GAAG,CACTC,KAAK,EAAE,EACPA,KAAK,SAAS,EACdA,KAAK,IAAI,EACTA,KAAK,EAAE,EACPA,KAAK,IAAI,EACTA,KAAK,SAAS,EACdA,AAAkBC,WAAlBD,KAAK,QAAQ,GAAiB,OAAOlB,KAAK,SAAS,CAACkB,KAAK,QAAQ;QAEpE;IACD;IAEA,MAAa,UAAUtB,SAAoB,EAAmB;QAC7D,MAAMC,qBAAqBC,YAAYF;QACvC,OAAO,IAAI,CAAC,GAAG,CACb,OAAO,CACP,qIAEA,GAAG,CAACC,oBACJ,GAAG,CAAC,CAACc,KAAKS,QAAUC,cAAcV,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAES,OAAO;IAC9E;IAEA,MAAa,mBAAyC;QACrD,OAAO,IAAI,CAAC,GAAG,CACb,OAAO,CAAC,iEACR,GAAG,GACH,GAAG,CAAC,CAACT,MAAQb,YAAYc,YAAYD,KAAK,cAAc,IAAI,CAAC,WAAW;IAC3E;IAEA,MAAa,cAAcf,SAAoB,EAAE0B,SAA6B,EAAiB;QAC9F,MAAMzB,qBAAqBC,YAAYF;QACvC2B,oBAAoB1B,oBAAoByB;QACxCvB,qBAAqB,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,8CAA8C,GAAG,CAACF;YACnE,MAAMoB,SAAS,IAAI,CAAC,GAAG,CAAC,OAAO,CAC9B;YAED,KAAK,MAAMO,WAAWF,UACrBL,OAAO,GAAG,CACTO,QAAQ,EAAE,EACVA,QAAQ,SAAS,EACjBA,QAAQ,QAAQ,IAAI,MACpBA,QAAQ,aAAa,EACrBxB,KAAK,SAAS,CAACwB,QAAQ,UAAU,GACjCA,QAAQ,YAAY,CAAC,EAAE,EACvBA,QAAQ,YAAY,CAAC,EAAE,EACvBxB,KAAK,SAAS,CAACwB,QAAQ,MAAM,GAC7BA,QAAQ,mBAAmB,EAC3BA,QAAQ,SAAS,EACjBA,AAAiBL,WAAjBK,QAAQ,IAAI,GAAiB,OAAOxB,KAAK,SAAS,CAACwB,QAAQ,IAAI;QAElE;IACD;IAEA,MAAa,cAAc5B,SAAoB,EAAsB;QACpE,MAAMC,qBAAqBC,YAAYF;QACvC,OAAO,IAAI,CAAC,GAAG,CACb,OAAO,CACP,8NAEA,GAAG,CAACC,oBACJ,GAAG,CAAC,CAACc,KAAKS,QAAUK,iBAAiBd,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAES,OAAO;IACrF;IAEA,MAAa,UAA4B;QACxC,IAAI;YACH,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,GAAG;YAChC,OAAO;QACR,EAAE,OAAO9B,OAAO;YACf,IAAIA,iBAAiBoC,OAAO,OAAO;YACnC,MAAMpC;QACP;IACD;IAEA,MAAa,QAAuB;QACnC,IAAI,CAAC,GAAG,CAAC,KAAK;IACf;IAEO,WAIL;QACD,MAAMqC,eAAexB,YACpB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,0CAA0C,GAAG,IAC9D,SACA,IAAI,CAAC,WAAW;QAEjB,MAAMyB,cAAczB,YACnB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,0CAA0C,GAAG,IAC9D,SACA,IAAI,CAAC,WAAW;QAEjB,OAAO;YAAEwB;YAAc,aAAa,IAAI,CAAC,gBAAgB,GAAGC,cAAc;YAAG,QAAQ;QAAE;IACxF;IAEQ,2BACPhC,SAAoB,EACpBiC,aAAqC,EAAE,EACvCC,eAA0B,EACF;QACxB,MAAMC,UAAU,IAAI,CAAC,eAAe,CAACnC;QACrC,KAAK,MAAMH,WAAWsC,QACrBrC,mBAAmB,yBAAyBE,WAAWH;QAExD,MAAMuC,cAA4C;YACjD;gBACCpC;gBACA,UAAUkC,AAAoBX,WAApBW,kBAAgC;uBAAIC;uBAAYF;iBAAW,GAAGE;YACzE;SACA;QACD,MAAME,WAAW,IAAIC;QACrB,KAAK,MAAMvB,OAAO,IAAI,CAAC,GAAG,CACxB,OAAO,CAAC,6DACR,GAAG,CAACf,WAAY;YACjB,MAAMS,WAAWG,yBAChBI,YAAYD,KAAK,aAAa,IAAI,CAAC,WAAW,GAC9C,IAAI,CAAC,WAAW;YAEjB,MAAMwB,OAAOvB,YAAYD,KAAK,QAAQ,IAAI,CAAC,WAAW;YACtD,IAAIyB;YACJ,IAAI;gBACHA,SAASpC,KAAK,KAAK,CAACmC;YACrB,EAAE,OAAO7C,OAAO;gBACf,MAAM,IAAI+C,2BAA2B,IAAI,CAAC,WAAW,EAAE/C;YACxD;YACA,IAAI,CAACgD,MAAM,OAAO,CAACF,SAClB,MAAM,IAAIC,2BACT,IAAI,CAAC,WAAW,EAChB,IAAIE,UAAU;YAEhB,MAAMjC,WAAW8B,OAAO,GAAG,CAAC,CAACI,OAAOpB,QACnCqB,iBACC;oBAAE,MAAMzC,KAAK,SAAS,CAACwC;gBAAO,GAC9B,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE5C,UAAU,CAAC,EAAES,SAAS,CAAC,EAAEe,OAAO;YAGhEX,kBAAkB,wBAAwBb,WAAWS,UAAUC;YAC/D2B,SAAS,GAAG,CAAC5B,UAAUC;YACvB,IAAID,aAAayB,iBAAiBE,YAAY,IAAI,CAAC;gBAAEpC;gBAAWU;YAAS;QAC1E;QACA,IAAIwB,AAAoBX,WAApBW,iBACHE,YAAY,IAAI,CAAC;YAAEpC;YAAW,UAAUiC;QAAW;QAEpDa,oCAAoCV,aAAa,IAAI,CAAC,WAAW;QACjE,OAAO;YAAED;YAASE;QAAS;IAC5B;IAEQ,gBAAgBrC,SAAoB,EAAiB;QAC5D,OAAO,IAAI,CAAC,GAAG,CACb,OAAO,CAAC,kEACR,GAAG,CAACA,WACJ,GAAG,CAAC,CAACe,MAAQ8B,iBAAiB9B,KAAK,IAAI,CAAC,WAAW;IACtD;AACD"}
1
+ {"version":3,"file":"persistence/SqlitePersistence.js","sources":["../../src/persistence/SqlitePersistence.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type {\n\tPersistenceConfig,\n\tPersistenceBackend,\n} from '../contracts/PersistenceBackend.js';\nimport { asSessionId, type BranchId, type SessionId } from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError, PersistenceCorruptionError } from '../errors.js';\nimport type { SqliteDatabase, SqliteDatabaseConstructor } from './SqliteDriver.js';\nimport { runSqliteReadTransaction, runSqliteTransaction } from './SqliteDriver.js';\nimport {\n\tdecodeEdgeRow,\n\tdecodeSummaryRow,\n\tdecodeThoughtRow,\n\tnumberField,\n\tstringField,\n} from './SqlitePayload.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertPersistableThoughts,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tcompareCodePoint,\n\tparsePersistenceBranchId,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\nimport { initializeOrValidateSqliteV2 } from './SqliteSchemaV2.js';\n\ntype SqliteOptions = PersistenceConfig['options'];\n\ntype ValidatedThoughtState = {\n\treadonly history: ThoughtData[];\n\treadonly branches: ReadonlyMap<BranchId, ThoughtData[]>;\n};\n\nexport class SqlitePersistence implements PersistenceBackend {\n\tprivate constructor(\n\t\tprivate readonly _db: SqliteDatabase,\n\t\tprivate readonly _sourcePath: string,\n\t\tprivate readonly _maxHistorySize: number,\n\t\tprivate readonly _persistBranches: boolean\n\t) {}\n\n\tpublic static createWithDatabase(\n\t\tdatabase: SqliteDatabase,\n\t\toptions: SqliteOptions = {},\n\t\tsourcePath = '<structural-sqlite>'\n\t): SqlitePersistence {\n\t\tinitializeOrValidateSqliteV2(database, sourcePath);\n\t\treturn new SqlitePersistence(\n\t\t\tdatabase,\n\t\t\tsourcePath,\n\t\t\toptions?.maxHistorySize ?? 10000,\n\t\t\toptions?.persistBranches ?? true\n\t\t);\n\t}\n\n\tpublic static async create(options?: SqliteOptions): Promise<SqlitePersistence> {\n\t\tconst defaultDataDir = existsSync('.claude/data')\n\t\t\t? '.claude/data'\n\t\t\t: join(homedir(), '.claude/data');\n\t\tconst dbPath = options?.dbPath ?? join(defaultDataDir, 'history.db');\n\t\tlet Database: SqliteDatabaseConstructor;\n\t\ttry {\n\t\t\tconst module = await import('better-sqlite3');\n\t\t\tDatabase = module.default;\n\t\t} catch (error) {\n\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\tdbPath,\n\t\t\t\t\"SQLite persistence requires the optional 'better-sqlite3' package\",\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t\tconst database = new Database(dbPath);\n\t\ttry {\n\t\t\tconst persistence = SqlitePersistence.createWithDatabase(database, options, dbPath);\n\t\t\tif (options?.enableWAL !== false) database.pragma('journal_mode = WAL');\n\t\t\tdatabase.pragma('synchronous = NORMAL');\n\t\t\tdatabase.pragma('foreign_keys = ON');\n\t\t\tdatabase.pragma('busy_timeout = 5000');\n\t\t\tdatabase.pragma('cache_size = -64000');\n\t\t\tdatabase.pragma('temp_store = MEMORY');\n\t\t\treturn persistence;\n\t\t} catch (error) {\n\t\t\tdatabase.close();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope('saveThoughtForSession', validatedSessionId, thought);\n\t\tthis._saveThought(validatedSessionId, thought);\n\t}\n\n\tprivate _saveThought(sessionId: SessionId, thought: ThoughtData): void {\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._loadValidatedThoughtState(sessionId, [thought]);\n\t\t\tthis._db\n\t\t\t\t.prepare('INSERT INTO thoughts (session_id, data) VALUES (?, ?)')\n\t\t\t\t.run(sessionId, JSON.stringify(thought));\n\t\t\tif (this._maxHistorySize > 0) {\n\t\t\t\tconst countRow = this._db\n\t\t\t\t\t.prepare('SELECT COUNT(*) AS count FROM thoughts WHERE session_id = ?')\n\t\t\t\t\t.get(sessionId);\n\t\t\t\tconst excess =\n\t\t\t\t\tnumberField(countRow, 'count', `${this._sourcePath}:thought-count`) -\n\t\t\t\t\tthis._maxHistorySize;\n\t\t\t\tif (excess > 0) {\n\t\t\t\t\tthis._db\n\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t'DELETE FROM thoughts WHERE id IN (SELECT id FROM thoughts WHERE session_id = ? ORDER BY id ASC LIMIT ?)'\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.run(sessionId, excess);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn runSqliteReadTransaction(\n\t\t\tthis._db,\n\t\t\t() => this._loadValidatedThoughtState(validatedSessionId).history\n\t\t);\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tthis._saveBranch(validatedSessionId, validatedBranchId, thoughts);\n\t}\n\n\tprivate _saveBranch(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): void {\n\t\tassertPersistableThoughts(thoughts, `${this._sourcePath}:branch:${branchId}`);\n\t\tif (!this._persistBranches) {\n\t\t\trunSqliteReadTransaction(this._db, () =>\n\t\t\t\tthis._loadValidatedThoughtState(sessionId, thoughts, branchId)\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._loadValidatedThoughtState(sessionId, thoughts, branchId);\n\t\t\tthis._db\n\t\t\t\t.prepare('INSERT OR REPLACE INTO branches (session_id, branch_id, data) VALUES (?, ?, ?)')\n\t\t\t\t.run(sessionId, branchId, JSON.stringify(thoughts));\n\t\t});\n\t}\n\n\tpublic async deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void> {\n\t\tif (!this._persistBranches) return;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._db\n\t\t\t\t.prepare('DELETE FROM branches WHERE session_id = ? AND branch_id = ?')\n\t\t\t\t.run(validatedSessionId, validatedBranchId);\n\t\t});\n\t}\n\n\tpublic async loadBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId\n\t): Promise<ThoughtData[] | undefined> {\n\t\tif (!this._persistBranches) return undefined;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${this._sourcePath}:branches`);\n\t\treturn runSqliteReadTransaction(this._db, () =>\n\t\t\tthis._loadValidatedThoughtState(validatedSessionId).branches.get(validatedBranchId)\n\t\t);\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\treturn this._db\n\t\t\t.prepare('SELECT branch_id FROM branches WHERE session_id = ? ORDER BY branch_id ASC')\n\t\t\t.all(asSessionId(sessionId))\n\t\t\t.map((row) =>\n\t\t\t\tparsePersistenceBranchId(stringField(row, 'branch_id', this._sourcePath), this._sourcePath)\n\t\t\t);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\treturn this._db\n\t\t\t.prepare(\n\t\t\t\t'SELECT session_id FROM thoughts UNION SELECT session_id FROM branches UNION SELECT session_id FROM edges UNION SELECT session_id FROM summaries'\n\t\t\t)\n\t\t\t.all()\n\t\t\t.map((row) => asSessionId(stringField(row, 'session_id', this._sourcePath)))\n\t\t\t.sort(compareCodePoint);\n\t}\n\n\tpublic async clearAll(): Promise<void> {\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tfor (const table of ['thoughts', 'branches', 'edges', 'summaries'])\n\t\t\t\tthis._db.exec(`DELETE FROM ${table}`);\n\t\t});\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tfor (const table of ['thoughts', 'branches', 'edges', 'summaries']) {\n\t\t\t\tthis._db.prepare(`DELETE FROM ${table} WHERE session_id = ?`).run(validatedSessionId);\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic async saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertEdgeScopes(validatedSessionId, edges);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._db.prepare('DELETE FROM edges WHERE session_id = ?').run(validatedSessionId);\n\t\t\tconst insert = this._db.prepare(\n\t\t\t\t'INSERT INTO edges (id, session_id, from_id, to_id, kind, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)'\n\t\t\t);\n\t\t\tfor (const edge of edges)\n\t\t\t\tinsert.run(\n\t\t\t\t\tedge.id,\n\t\t\t\t\tedge.sessionId,\n\t\t\t\t\tedge.from,\n\t\t\t\t\tedge.to,\n\t\t\t\t\tedge.kind,\n\t\t\t\t\tedge.createdAt,\n\t\t\t\t\tedge.metadata === undefined ? null : JSON.stringify(edge.metadata)\n\t\t\t\t);\n\t\t});\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn this._db\n\t\t\t.prepare(\n\t\t\t\t'SELECT id, session_id, from_id, to_id, kind, created_at, metadata FROM edges WHERE session_id = ? ORDER BY created_at ASC, id ASC'\n\t\t\t)\n\t\t\t.all(validatedSessionId)\n\t\t\t.map((row, index) => decodeEdgeRow(row, `${this._sourcePath}:edges:${index}`));\n\t}\n\n\tpublic async saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertSummaryScopes(validatedSessionId, summaries);\n\t\trunSqliteTransaction(this._db, () => {\n\t\t\tthis._db.prepare('DELETE FROM summaries WHERE session_id = ?').run(validatedSessionId);\n\t\t\tconst insert = this._db.prepare(\n\t\t\t\t'INSERT INTO summaries (id, session_id, branch_id, root_thought_id, covered_ids, covered_range_start, covered_range_end, topics, aggregate_confidence, created_at, meta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'\n\t\t\t);\n\t\t\tfor (const summary of summaries)\n\t\t\t\tinsert.run(\n\t\t\t\t\tsummary.id,\n\t\t\t\t\tsummary.sessionId,\n\t\t\t\t\tsummary.branchId ?? null,\n\t\t\t\t\tsummary.rootThoughtId,\n\t\t\t\t\tJSON.stringify(summary.coveredIds),\n\t\t\t\t\tsummary.coveredRange[0],\n\t\t\t\t\tsummary.coveredRange[1],\n\t\t\t\t\tJSON.stringify(summary.topics),\n\t\t\t\t\tsummary.aggregateConfidence,\n\t\t\t\t\tsummary.createdAt,\n\t\t\t\t\tsummary.meta === undefined ? null : JSON.stringify(summary.meta)\n\t\t\t\t);\n\t\t});\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn this._db\n\t\t\t.prepare(\n\t\t\t\t'SELECT id, session_id, branch_id, root_thought_id, covered_ids, covered_range_start, covered_range_end, topics, aggregate_confidence, created_at, meta FROM summaries WHERE session_id = ? ORDER BY created_at ASC, id ASC'\n\t\t\t)\n\t\t\t.all(validatedSessionId)\n\t\t\t.map((row, index) => decodeSummaryRow(row, `${this._sourcePath}:summaries:${index}`));\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tthis._db.prepare('SELECT 1').get();\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) return false;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tthis._db.close();\n\t}\n\n\tpublic getStats(): {\n\t\treadonly thoughtCount: number;\n\t\treadonly branchCount: number;\n\t\treadonly dbSize: number;\n\t} {\n\t\tconst thoughtCount = numberField(\n\t\t\tthis._db.prepare('SELECT COUNT(*) AS count FROM thoughts').get(),\n\t\t\t'count',\n\t\t\tthis._sourcePath\n\t\t);\n\t\tconst branchCount = numberField(\n\t\t\tthis._db.prepare('SELECT COUNT(*) AS count FROM branches').get(),\n\t\t\t'count',\n\t\t\tthis._sourcePath\n\t\t);\n\t\treturn { thoughtCount, branchCount: this._persistBranches ? branchCount : 0, dbSize: 0 };\n\t}\n\n\tprivate _loadValidatedThoughtState(\n\t\tsessionId: SessionId,\n\t\tcandidates: readonly ThoughtData[] = [],\n\t\treplacingBranch?: BranchId\n\t): ValidatedThoughtState {\n\t\tconst history = this.loadHistoryRows(sessionId);\n\t\tfor (const thought of history) {\n\t\t\tassertThoughtScope('saveThoughtForSession', sessionId, thought);\n\t\t}\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{\n\t\t\t\tsessionId,\n\t\t\t\tthoughts: replacingBranch === undefined ? [...history, ...candidates] : history,\n\t\t\t},\n\t\t];\n\t\tconst branches = new Map<BranchId, ThoughtData[]>();\n\t\tfor (const row of this._db\n\t\t\t.prepare('SELECT branch_id, data FROM branches WHERE session_id = ?')\n\t\t\t.all(sessionId)) {\n\t\t\tconst branchId = parsePersistenceBranchId(\n\t\t\t\tstringField(row, 'branch_id', this._sourcePath),\n\t\t\t\tthis._sourcePath\n\t\t\t);\n\t\t\tconst data = stringField(row, 'data', this._sourcePath);\n\t\t\tlet values: unknown;\n\t\t\ttry {\n\t\t\t\tvalues = JSON.parse(data);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new PersistenceCorruptionError(this._sourcePath, error);\n\t\t\t}\n\t\t\tif (!Array.isArray(values))\n\t\t\t\tthrow new PersistenceCorruptionError(\n\t\t\t\t\tthis._sourcePath,\n\t\t\t\t\tnew TypeError('branch data is not an array')\n\t\t\t\t);\n\t\t\tconst thoughts = values.map((value, index) =>\n\t\t\t\tdecodeThoughtRow(\n\t\t\t\t\t{ data: JSON.stringify(value) },\n\t\t\t\t\t`${this._sourcePath}:branch:${sessionId}:${branchId}:${index}`\n\t\t\t\t)\n\t\t\t);\n\t\t\tassertBranchScope('saveBranchForSession', sessionId, branchId, thoughts);\n\t\t\tbranches.set(branchId, thoughts);\n\t\t\tif (branchId !== replacingBranch) collections.push({ sessionId, thoughts });\n\t\t}\n\t\tif (replacingBranch !== undefined) {\n\t\t\tcollections.push({ sessionId, thoughts: candidates });\n\t\t}\n\t\tassertPersistableThoughtCollections(collections, this._sourcePath);\n\t\treturn { history, branches };\n\t}\n\n\tprivate loadHistoryRows(sessionId: SessionId): ThoughtData[] {\n\t\treturn this._db\n\t\t\t.prepare('SELECT data FROM thoughts WHERE session_id = ? ORDER BY id ASC')\n\t\t\t.all(sessionId)\n\t\t\t.map((row) => decodeThoughtRow(row, this._sourcePath));\n\t}\n}\n"],"names":["SqlitePersistence","_db","_sourcePath","_maxHistorySize","_persistBranches","database","options","sourcePath","initializeOrValidateSqliteV2","defaultDataDir","existsSync","join","homedir","dbPath","Database","module","error","PersistenceCompatibilityError","persistence","sessionId","thought","validatedSessionId","asSessionId","assertThoughtScope","runSqliteTransaction","JSON","countRow","excess","numberField","runSqliteReadTransaction","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","assertPersistableThoughts","row","stringField","compareCodePoint","table","edges","assertEdgeScopes","insert","edge","undefined","index","decodeEdgeRow","summaries","assertSummaryScopes","summary","decodeSummaryRow","Error","thoughtCount","branchCount","candidates","replacingBranch","history","collections","branches","Map","data","values","PersistenceCorruptionError","Array","TypeError","value","decodeThoughtRow","assertPersistableThoughtCollections"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteSchemaV2.d.ts","sourceRoot":"","sources":["../../src/persistence/SqliteSchemaV2.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,eAAO,MAAM,oBAAoB,4tEAiEhC,CAAC;AAEF,eAAO,MAAM,wBAAwB,mEAC4B,CAAC;AAElE,KAAK,YAAY,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB,CAAC;AAuCF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,EAAE,CAOhG;AAYD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CA8BzF;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAS/F"}
1
+ {"version":3,"file":"SqliteSchemaV2.d.ts","sourceRoot":"","sources":["../../src/persistence/SqliteSchemaV2.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,eAAO,MAAM,oBAAoB,4tEAiEhC,CAAC;AAEF,eAAO,MAAM,wBAAwB,mEAC4B,CAAC;AAElE,KAAK,YAAY,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB,CAAC;AAuCF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,EAAE,CAOhG;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CA2BzF;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAS/F"}
@@ -1,4 +1,4 @@
1
- import { PersistenceCompatibilityError, PersistenceImportRequiredError } from "../errors.js";
1
+ import { PersistenceCompatibilityError } from "../errors.js";
2
2
  import { runSqliteTransaction } from "./SqliteDriver.js";
3
3
  const SQLITE_V2_SCHEMA_DDL = `
4
4
  CREATE TABLE schema_version (
@@ -96,21 +96,12 @@ function readSchemaObject(row, sourcePath) {
96
96
  function sqliteSchemaObjects(database, sourcePath) {
97
97
  return database.prepare("SELECT type, name, tbl_name, sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY type, name").all().map((row)=>readSchemaObject(row, sourcePath));
98
98
  }
99
- function hasLegacyShape(objects) {
100
- const names = new Set(objects.map(({ type, name })=>`${type}:${name}`));
101
- return names.has('table:thoughts') && names.has('table:edges') && names.has('table:summaries') && !names.has('table:schema_version');
102
- }
103
99
  function validateSqliteV2Schema(database, sourcePath) {
104
100
  const objects = sqliteSchemaObjects(database, sourcePath);
105
- if (objects.length !== V2_OBJECTS.size) {
106
- if (hasLegacyShape(objects)) throw new PersistenceImportRequiredError(sourcePath, [
107
- 'unversioned SQLite v1 schema'
108
- ]);
109
- throw new PersistenceCompatibilityError(sourcePath, 'SQLite v2 object set does not match');
110
- }
101
+ if (objects.length !== V2_OBJECTS.size) throw new PersistenceCompatibilityError(sourcePath, 'database does not match SQLite v2 schema');
111
102
  for (const object of objects){
112
103
  const expected = V2_OBJECTS.get(`${object.type}:${object.name}`);
113
- if (void 0 === expected || normalizeSql(object.sql) !== expected) throw new PersistenceCompatibilityError(sourcePath, `SQLite v2 drift at '${object.name}'`);
104
+ if (void 0 === expected || normalizeSql(object.sql) !== expected) throw new PersistenceCompatibilityError(sourcePath, 'database does not match SQLite v2 schema');
114
105
  }
115
106
  const versionRows = database.prepare('SELECT singleton, version FROM schema_version').all();
116
107
  const versionRow = versionRows[0];
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/SqliteSchemaV2.js","sources":["../../src/persistence/SqliteSchemaV2.ts"],"sourcesContent":["import { PersistenceCompatibilityError, PersistenceImportRequiredError } from '../errors.js';\nimport type { SqliteDatabase } from './SqliteDriver.js';\nimport { runSqliteTransaction } from './SqliteDriver.js';\n\nexport const SQLITE_V2_SCHEMA_DDL = `\nCREATE TABLE schema_version (\n singleton INTEGER PRIMARY KEY CHECK (singleton = 1),\n version INTEGER NOT NULL CHECK (version = 2)\n);\nCREATE TABLE thoughts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n data TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch()),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*')\n);\nCREATE INDEX idx_thoughts_session_id ON thoughts(session_id, id);\nCREATE TABLE branches (\n session_id TEXT NOT NULL,\n branch_id TEXT NOT NULL,\n data TEXT NOT NULL,\n updated_at INTEGER NOT NULL DEFAULT (unixepoch()),\n PRIMARY KEY (session_id, branch_id),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*'),\n CHECK (length(branch_id) BETWEEN 1 AND 50),\n CHECK (branch_id NOT GLOB '*[^A-Za-z0-9_-]*')\n);\nCREATE TABLE edges (\n id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n from_id TEXT NOT NULL,\n to_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n metadata TEXT,\n PRIMARY KEY (session_id, id),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*')\n);\nCREATE INDEX idx_edges_session_created ON edges(session_id, created_at, id);\nCREATE INDEX idx_edges_from ON edges(session_id, from_id);\nCREATE INDEX idx_edges_to ON edges(session_id, to_id);\nCREATE TABLE summaries (\n id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n branch_id TEXT,\n root_thought_id TEXT NOT NULL,\n covered_ids TEXT NOT NULL,\n covered_range_start INTEGER NOT NULL,\n covered_range_end INTEGER NOT NULL,\n topics TEXT NOT NULL,\n aggregate_confidence REAL NOT NULL,\n created_at INTEGER NOT NULL,\n meta TEXT,\n PRIMARY KEY (session_id, id),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*'),\n CHECK (branch_id IS NULL OR (\n length(branch_id) BETWEEN 1 AND 50\n AND branch_id NOT GLOB '*[^A-Za-z0-9_-]*'\n )),\n CHECK (aggregate_confidence >= 0.0 AND aggregate_confidence <= 1.0)\n);\nCREATE INDEX idx_summaries_session_created\n ON summaries(session_id, created_at, id);\nCREATE INDEX idx_summaries_session_branch\n ON summaries(session_id, branch_id);\n`;\n\nexport const SQLITE_V2_VERSION_INSERT =\n\t'INSERT INTO schema_version (singleton, version) VALUES (1, 2);';\n\ntype SchemaObject = {\n\treadonly type: string;\n\treadonly name: string;\n\treadonly tableName: string;\n\treadonly sql: string;\n};\n\nfunction normalizeSql(sql: string): string {\n\treturn sql.replace(/\\s+/g, ' ').replace(/;$/, '').trim().toLowerCase();\n}\n\nfunction expectedV2Objects(): Map<string, string> {\n\tconst objects = new Map<string, string>();\n\tfor (const statement of SQLITE_V2_SCHEMA_DDL.split(';')\n\t\t.map((sql) => sql.trim())\n\t\t.filter(Boolean)) {\n\t\tconst match = /^CREATE\\s+(TABLE|INDEX)\\s+([^\\s(]+)/i.exec(statement);\n\t\tif (match?.[1] === undefined || match[2] === undefined) continue;\n\t\tobjects.set(`${match[1].toLowerCase()}:${match[2]}`, normalizeSql(statement));\n\t}\n\treturn objects;\n}\n\nconst V2_OBJECTS = expectedV2Objects();\n\nfunction readSchemaObject(row: unknown, sourcePath: string): SchemaObject {\n\tif (typeof row !== 'object' || row === null) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'invalid sqlite_master row');\n\t}\n\tconst type = 'type' in row ? row.type : undefined;\n\tconst name = 'name' in row ? row.name : undefined;\n\tconst tableName = 'tbl_name' in row ? row.tbl_name : undefined;\n\tconst sql = 'sql' in row ? row.sql : undefined;\n\tif (\n\t\ttypeof type !== 'string' ||\n\t\ttypeof name !== 'string' ||\n\t\ttypeof tableName !== 'string' ||\n\t\ttypeof sql !== 'string'\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'invalid sqlite_master fields');\n\t}\n\treturn { type, name, tableName, sql };\n}\n\nexport function sqliteSchemaObjects(database: SqliteDatabase, sourcePath: string): SchemaObject[] {\n\treturn database\n\t\t.prepare(\n\t\t\t\"SELECT type, name, tbl_name, sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY type, name\"\n\t\t)\n\t\t.all()\n\t\t.map((row) => readSchemaObject(row, sourcePath));\n}\n\nfunction hasLegacyShape(objects: readonly SchemaObject[]): boolean {\n\tconst names = new Set(objects.map(({ type, name }) => `${type}:${name}`));\n\treturn (\n\t\tnames.has('table:thoughts') &&\n\t\tnames.has('table:edges') &&\n\t\tnames.has('table:summaries') &&\n\t\t!names.has('table:schema_version')\n\t);\n}\n\nexport function validateSqliteV2Schema(database: SqliteDatabase, sourcePath: string): void {\n\tconst objects = sqliteSchemaObjects(database, sourcePath);\n\tif (objects.length !== V2_OBJECTS.size) {\n\t\tif (hasLegacyShape(objects)) {\n\t\t\tthrow new PersistenceImportRequiredError(sourcePath, ['unversioned SQLite v1 schema']);\n\t\t}\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'SQLite v2 object set does not match');\n\t}\n\tfor (const object of objects) {\n\t\tconst expected = V2_OBJECTS.get(`${object.type}:${object.name}`);\n\t\tif (expected === undefined || normalizeSql(object.sql) !== expected) {\n\t\t\tthrow new PersistenceCompatibilityError(sourcePath, `SQLite v2 drift at '${object.name}'`);\n\t\t}\n\t}\n\tconst versionRows = database.prepare('SELECT singleton, version FROM schema_version').all();\n\tconst versionRow = versionRows[0];\n\tif (\n\t\tversionRows.length !== 1 ||\n\t\ttypeof versionRow !== 'object' ||\n\t\tversionRow === null ||\n\t\t!('singleton' in versionRow) ||\n\t\tversionRow.singleton !== 1 ||\n\t\t!('version' in versionRow) ||\n\t\tversionRow.version !== 2\n\t) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\tsourcePath,\n\t\t\t'schema_version must contain exactly (1, 2)'\n\t\t);\n\t}\n}\n\nexport function initializeOrValidateSqliteV2(database: SqliteDatabase, sourcePath: string): void {\n\tconst objects = sqliteSchemaObjects(database, sourcePath);\n\tif (objects.length === 0) {\n\t\trunSqliteTransaction(database, () => {\n\t\t\tdatabase.exec(SQLITE_V2_SCHEMA_DDL);\n\t\t\tdatabase.exec(SQLITE_V2_VERSION_INSERT);\n\t\t});\n\t}\n\tvalidateSqliteV2Schema(database, sourcePath);\n}\n"],"names":["SQLITE_V2_SCHEMA_DDL","SQLITE_V2_VERSION_INSERT","normalizeSql","sql","expectedV2Objects","objects","Map","statement","Boolean","match","undefined","V2_OBJECTS","readSchemaObject","row","sourcePath","PersistenceCompatibilityError","type","name","tableName","sqliteSchemaObjects","database","hasLegacyShape","names","Set","validateSqliteV2Schema","PersistenceImportRequiredError","object","expected","versionRows","versionRow","initializeOrValidateSqliteV2","runSqliteTransaction"],"mappings":"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"}
1
+ {"version":3,"file":"persistence/SqliteSchemaV2.js","sources":["../../src/persistence/SqliteSchemaV2.ts"],"sourcesContent":["import { PersistenceCompatibilityError } from '../errors.js';\nimport type { SqliteDatabase } from './SqliteDriver.js';\nimport { runSqliteTransaction } from './SqliteDriver.js';\n\nexport const SQLITE_V2_SCHEMA_DDL = `\nCREATE TABLE schema_version (\n singleton INTEGER PRIMARY KEY CHECK (singleton = 1),\n version INTEGER NOT NULL CHECK (version = 2)\n);\nCREATE TABLE thoughts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n data TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch()),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*')\n);\nCREATE INDEX idx_thoughts_session_id ON thoughts(session_id, id);\nCREATE TABLE branches (\n session_id TEXT NOT NULL,\n branch_id TEXT NOT NULL,\n data TEXT NOT NULL,\n updated_at INTEGER NOT NULL DEFAULT (unixepoch()),\n PRIMARY KEY (session_id, branch_id),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*'),\n CHECK (length(branch_id) BETWEEN 1 AND 50),\n CHECK (branch_id NOT GLOB '*[^A-Za-z0-9_-]*')\n);\nCREATE TABLE edges (\n id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n from_id TEXT NOT NULL,\n to_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n metadata TEXT,\n PRIMARY KEY (session_id, id),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*')\n);\nCREATE INDEX idx_edges_session_created ON edges(session_id, created_at, id);\nCREATE INDEX idx_edges_from ON edges(session_id, from_id);\nCREATE INDEX idx_edges_to ON edges(session_id, to_id);\nCREATE TABLE summaries (\n id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n branch_id TEXT,\n root_thought_id TEXT NOT NULL,\n covered_ids TEXT NOT NULL,\n covered_range_start INTEGER NOT NULL,\n covered_range_end INTEGER NOT NULL,\n topics TEXT NOT NULL,\n aggregate_confidence REAL NOT NULL,\n created_at INTEGER NOT NULL,\n meta TEXT,\n PRIMARY KEY (session_id, id),\n CHECK (length(session_id) BETWEEN 1 AND 100),\n CHECK (session_id NOT GLOB '*[^A-Za-z0-9_-]*'),\n CHECK (branch_id IS NULL OR (\n length(branch_id) BETWEEN 1 AND 50\n AND branch_id NOT GLOB '*[^A-Za-z0-9_-]*'\n )),\n CHECK (aggregate_confidence >= 0.0 AND aggregate_confidence <= 1.0)\n);\nCREATE INDEX idx_summaries_session_created\n ON summaries(session_id, created_at, id);\nCREATE INDEX idx_summaries_session_branch\n ON summaries(session_id, branch_id);\n`;\n\nexport const SQLITE_V2_VERSION_INSERT =\n\t'INSERT INTO schema_version (singleton, version) VALUES (1, 2);';\n\ntype SchemaObject = {\n\treadonly type: string;\n\treadonly name: string;\n\treadonly tableName: string;\n\treadonly sql: string;\n};\n\nfunction normalizeSql(sql: string): string {\n\treturn sql.replace(/\\s+/g, ' ').replace(/;$/, '').trim().toLowerCase();\n}\n\nfunction expectedV2Objects(): Map<string, string> {\n\tconst objects = new Map<string, string>();\n\tfor (const statement of SQLITE_V2_SCHEMA_DDL.split(';')\n\t\t.map((sql) => sql.trim())\n\t\t.filter(Boolean)) {\n\t\tconst match = /^CREATE\\s+(TABLE|INDEX)\\s+([^\\s(]+)/i.exec(statement);\n\t\tif (match?.[1] === undefined || match[2] === undefined) continue;\n\t\tobjects.set(`${match[1].toLowerCase()}:${match[2]}`, normalizeSql(statement));\n\t}\n\treturn objects;\n}\n\nconst V2_OBJECTS = expectedV2Objects();\n\nfunction readSchemaObject(row: unknown, sourcePath: string): SchemaObject {\n\tif (typeof row !== 'object' || row === null) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'invalid sqlite_master row');\n\t}\n\tconst type = 'type' in row ? row.type : undefined;\n\tconst name = 'name' in row ? row.name : undefined;\n\tconst tableName = 'tbl_name' in row ? row.tbl_name : undefined;\n\tconst sql = 'sql' in row ? row.sql : undefined;\n\tif (\n\t\ttypeof type !== 'string' ||\n\t\ttypeof name !== 'string' ||\n\t\ttypeof tableName !== 'string' ||\n\t\ttypeof sql !== 'string'\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'invalid sqlite_master fields');\n\t}\n\treturn { type, name, tableName, sql };\n}\n\nexport function sqliteSchemaObjects(database: SqliteDatabase, sourcePath: string): SchemaObject[] {\n\treturn database\n\t\t.prepare(\n\t\t\t\"SELECT type, name, tbl_name, sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY type, name\"\n\t\t)\n\t\t.all()\n\t\t.map((row) => readSchemaObject(row, sourcePath));\n}\n\nexport function validateSqliteV2Schema(database: SqliteDatabase, sourcePath: string): void {\n\tconst objects = sqliteSchemaObjects(database, sourcePath);\n\tif (objects.length !== V2_OBJECTS.size) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'database does not match SQLite v2 schema');\n\t}\n\tfor (const object of objects) {\n\t\tconst expected = V2_OBJECTS.get(`${object.type}:${object.name}`);\n\t\tif (expected === undefined || normalizeSql(object.sql) !== expected) {\n\t\t\tthrow new PersistenceCompatibilityError(sourcePath, 'database does not match SQLite v2 schema');\n\t\t}\n\t}\n\tconst versionRows = database.prepare('SELECT singleton, version FROM schema_version').all();\n\tconst versionRow = versionRows[0];\n\tif (\n\t\tversionRows.length !== 1 ||\n\t\ttypeof versionRow !== 'object' ||\n\t\tversionRow === null ||\n\t\t!('singleton' in versionRow) ||\n\t\tversionRow.singleton !== 1 ||\n\t\t!('version' in versionRow) ||\n\t\tversionRow.version !== 2\n\t) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\tsourcePath,\n\t\t\t'schema_version must contain exactly (1, 2)'\n\t\t);\n\t}\n}\n\nexport function initializeOrValidateSqliteV2(database: SqliteDatabase, sourcePath: string): void {\n\tconst objects = sqliteSchemaObjects(database, sourcePath);\n\tif (objects.length === 0) {\n\t\trunSqliteTransaction(database, () => {\n\t\t\tdatabase.exec(SQLITE_V2_SCHEMA_DDL);\n\t\t\tdatabase.exec(SQLITE_V2_VERSION_INSERT);\n\t\t});\n\t}\n\tvalidateSqliteV2Schema(database, sourcePath);\n}\n"],"names":["SQLITE_V2_SCHEMA_DDL","SQLITE_V2_VERSION_INSERT","normalizeSql","sql","expectedV2Objects","objects","Map","statement","Boolean","match","undefined","V2_OBJECTS","readSchemaObject","row","sourcePath","PersistenceCompatibilityError","type","name","tableName","sqliteSchemaObjects","database","validateSqliteV2Schema","object","expected","versionRows","versionRow","initializeOrValidateSqliteV2","runSqliteTransaction"],"mappings":"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"}
@@ -131,12 +131,12 @@ export declare class ConnectionPool implements IConnectionPool {
131
131
  /**
132
132
  * Process a thought in the specified session.
133
133
  *
134
- * @param sessionId - The session ID
134
+ * @param poolSessionId - The pool slot ID, distinct from `input.session_id`
135
135
  * @param input - The thought data to process
136
136
  * @returns Promise with the processing result
137
137
  * @throws Error if session not found
138
138
  */
139
- process(sessionId: SessionId, input: SessionThoughtInput): Promise<ProcessResult>;
139
+ process(poolSessionId: SessionId, input: SessionThoughtInput): Promise<ProcessResult>;
140
140
  runWithSession<T>(sessionId: SessionId, operation: (session: SessionServer) => Promise<T>): Promise<SessionRunResult<T>>;
141
141
  private _runWithSession;
142
142
  /**
@@ -173,17 +173,8 @@ export declare class ConnectionPool implements IConnectionPool {
173
173
  * Remove timed-out sessions.
174
174
  */
175
175
  private _cleanupTimedOutSessions;
176
- /**
177
- * Close all sessions and stop the cleanup timer.
178
- */
179
- terminate(): Promise<void>;
180
- private _completeTerminationGeneration;
181
- /**
182
- * Dispose of the connection pool, releasing all resources.
183
- * Implements the IDisposable interface.
184
- * Delegates to terminate() for backward compatibility.
185
- */
186
176
  dispose(): Promise<void>;
177
+ private _completeTerminationGeneration;
187
178
  /**
188
179
  * Check if the connection pool is active.
189
180
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionPool.d.ts","sourceRoot":"","sources":["../../src/pool/ConnectionPool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConnectionPool.d.ts","sourceRoot":"","sources":["../../src/pool/ConnectionPool.ts"],"names":[],"mappings":"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"}
@@ -177,15 +177,15 @@ class ConnectionPool {
177
177
  this._createSessionLock = null;
178
178
  }
179
179
  }
180
- async process(sessionId, input) {
181
- const result = await this._runWithSession(sessionId, (session)=>session.processAdmitted(input));
180
+ async process(poolSessionId, input) {
181
+ const result = await this._runWithSession(poolSessionId, (session)=>session.processAdmitted(input));
182
182
  switch(result.status){
183
183
  case 'completed':
184
184
  return result.value;
185
185
  case 'inactive':
186
- throw new SessionNotActiveError(sessionId);
186
+ throw new SessionNotActiveError(poolSessionId);
187
187
  case 'missing':
188
- throw new SessionNotFoundError(sessionId);
188
+ throw new SessionNotFoundError(poolSessionId);
189
189
  default:
190
190
  return assertNever(result);
191
191
  }
@@ -283,7 +283,7 @@ class ConnectionPool {
283
283
  }
284
284
  if (cleaned > 0) this._logger.info(`Cleaned ${cleaned} timed-out sessions (${this._sessions.size}/${this._maxSessions} active sessions)`);
285
285
  }
286
- terminate() {
286
+ dispose() {
287
287
  if (this._terminationGeneration) return this._terminationGeneration.completion.promise;
288
288
  const completion = Promise.withResolvers();
289
289
  const generation = {
@@ -313,9 +313,6 @@ class ConnectionPool {
313
313
  this._logger.info('ConnectionPool terminated');
314
314
  generation.completion.resolve();
315
315
  }
316
- dispose() {
317
- return this.terminate();
318
- }
319
316
  isRunning() {
320
317
  return !this._terminated;
321
318
  }