@iworkforces/tracelattice 2.0.8 → 2.1.2

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 (178) hide show
  1. package/README.md +89 -64
  2. package/dist/ServerConfig.d.ts +1 -1
  3. package/dist/ServerConfig.js.map +1 -1
  4. package/dist/cli.js +18 -73
  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/core/HistoryManager.d.ts +12 -16
  24. package/dist/core/HistoryManager.d.ts.map +1 -1
  25. package/dist/core/HistoryManager.js +19 -40
  26. package/dist/core/HistoryManager.js.map +1 -1
  27. package/dist/core/IHistoryManager.d.ts +22 -30
  28. package/dist/core/IHistoryManager.d.ts.map +1 -1
  29. package/dist/core/InputNormalizer.d.ts +7 -24
  30. package/dist/core/InputNormalizer.d.ts.map +1 -1
  31. package/dist/core/InputNormalizer.js +3 -9
  32. package/dist/core/InputNormalizer.js.map +1 -1
  33. package/dist/core/PersistenceBuffer.d.ts +3 -20
  34. package/dist/core/PersistenceBuffer.d.ts.map +1 -1
  35. package/dist/core/PersistenceBuffer.js +1 -4
  36. package/dist/core/PersistenceBuffer.js.map +1 -1
  37. package/dist/core/PersistenceRestore.d.ts.map +1 -1
  38. package/dist/core/PersistenceRestore.js +4 -10
  39. package/dist/core/PersistenceRestore.js.map +1 -1
  40. package/dist/core/PersistenceWriter.d.ts.map +1 -1
  41. package/dist/core/PersistenceWriter.js +3 -12
  42. package/dist/core/PersistenceWriter.js.map +1 -1
  43. package/dist/core/SessionErrors.d.ts +0 -11
  44. package/dist/core/SessionErrors.d.ts.map +1 -1
  45. package/dist/core/SessionErrors.js +1 -14
  46. package/dist/core/SessionErrors.js.map +1 -1
  47. package/dist/core/SessionLock.d.ts +4 -5
  48. package/dist/core/SessionLock.d.ts.map +1 -1
  49. package/dist/core/SessionLock.js +5 -10
  50. package/dist/core/SessionLock.js.map +1 -1
  51. package/dist/core/SessionManager.d.ts +0 -2
  52. package/dist/core/SessionManager.d.ts.map +1 -1
  53. package/dist/core/SessionManager.js +3 -5
  54. package/dist/core/SessionManager.js.map +1 -1
  55. package/dist/core/SessionResetCoordinator.d.ts +10 -7
  56. package/dist/core/SessionResetCoordinator.d.ts.map +1 -1
  57. package/dist/core/SessionResetCoordinator.js +10 -28
  58. package/dist/core/SessionResetCoordinator.js.map +1 -1
  59. package/dist/core/ThoughtEvaluator.d.ts +5 -5
  60. package/dist/core/ThoughtEvaluator.d.ts.map +1 -1
  61. package/dist/core/ThoughtEvaluator.js +4 -40
  62. package/dist/core/ThoughtEvaluator.js.map +1 -1
  63. package/dist/core/ThoughtProcessor.d.ts +10 -3
  64. package/dist/core/ThoughtProcessor.d.ts.map +1 -1
  65. package/dist/core/ThoughtProcessor.js +34 -38
  66. package/dist/core/ThoughtProcessor.js.map +1 -1
  67. package/dist/core/VerificationOutcomeAdmission.d.ts.map +1 -1
  68. package/dist/core/VerificationOutcomeAdmission.js +5 -7
  69. package/dist/core/VerificationOutcomeAdmission.js.map +1 -1
  70. package/dist/core/evaluator/Calibrator.d.ts +1 -1
  71. package/dist/core/evaluator/Calibrator.d.ts.map +1 -1
  72. package/dist/core/evaluator/Calibrator.js +2 -5
  73. package/dist/core/evaluator/Calibrator.js.map +1 -1
  74. package/dist/core/evaluator/internals.d.ts +0 -4
  75. package/dist/core/evaluator/internals.d.ts.map +1 -1
  76. package/dist/core/evaluator/internals.js +1 -3
  77. package/dist/core/evaluator/internals.js.map +1 -1
  78. package/dist/core/graph/Edge.d.ts +1 -1
  79. package/dist/core/graph/EdgeEmitter.d.ts +2 -4
  80. package/dist/core/graph/EdgeEmitter.d.ts.map +1 -1
  81. package/dist/core/graph/EdgeEmitter.js +2 -4
  82. package/dist/core/graph/EdgeEmitter.js.map +1 -1
  83. package/dist/core/reasoning/OutcomeRecorder.d.ts +0 -1
  84. package/dist/core/reasoning/OutcomeRecorder.d.ts.map +1 -1
  85. package/dist/core/reasoning/OutcomeRecorder.js.map +1 -1
  86. package/dist/core/reasoning/strategies/SequentialStrategy.d.ts +3 -3
  87. package/dist/core/reasoning/strategies/SequentialStrategy.js.map +1 -1
  88. package/dist/core/thought.d.ts +2 -1
  89. package/dist/core/thought.d.ts.map +1 -1
  90. package/dist/errors.d.ts +4 -20
  91. package/dist/errors.d.ts.map +1 -1
  92. package/dist/errors.js +2 -28
  93. package/dist/errors.js.map +1 -1
  94. package/dist/lib.d.ts +13 -20
  95. package/dist/lib.d.ts.map +1 -1
  96. package/dist/lib.js +4 -7
  97. package/dist/lib.js.map +1 -1
  98. package/dist/logger/NullLogger.d.ts +9 -11
  99. package/dist/logger/NullLogger.d.ts.map +1 -1
  100. package/dist/logger/NullLogger.js.map +1 -1
  101. package/dist/persistence/FilePersistence.d.ts +3 -12
  102. package/dist/persistence/FilePersistence.d.ts.map +1 -1
  103. package/dist/persistence/FilePersistence.js +9 -61
  104. package/dist/persistence/FilePersistence.js.map +1 -1
  105. package/dist/persistence/FileSnapshotV2.d.ts +2 -2
  106. package/dist/persistence/FileSnapshotV2.js +2 -2
  107. package/dist/persistence/FileSnapshotV2.js.map +1 -1
  108. package/dist/persistence/FileWriter.d.ts +1 -0
  109. package/dist/persistence/FileWriter.d.ts.map +1 -1
  110. package/dist/persistence/FileWriter.js +3 -3
  111. package/dist/persistence/FileWriter.js.map +1 -1
  112. package/dist/persistence/MemoryPersistence.d.ts +5 -15
  113. package/dist/persistence/MemoryPersistence.d.ts.map +1 -1
  114. package/dist/persistence/MemoryPersistence.js +6 -40
  115. package/dist/persistence/MemoryPersistence.js.map +1 -1
  116. package/dist/persistence/PersistenceCodec.js +1 -3
  117. package/dist/persistence/PersistenceCodec.js.map +1 -1
  118. package/dist/persistence/PersistenceErrors.d.ts +0 -6
  119. package/dist/persistence/PersistenceErrors.d.ts.map +1 -1
  120. package/dist/persistence/PersistenceErrors.js +1 -9
  121. package/dist/persistence/PersistenceErrors.js.map +1 -1
  122. package/dist/persistence/PersistenceScope.d.ts.map +1 -1
  123. package/dist/persistence/PersistenceScope.js +2 -2
  124. package/dist/persistence/PersistenceScope.js.map +1 -1
  125. package/dist/persistence/SqlitePersistence.d.ts +3 -10
  126. package/dist/persistence/SqlitePersistence.d.ts.map +1 -1
  127. package/dist/persistence/SqlitePersistence.js +2 -26
  128. package/dist/persistence/SqlitePersistence.js.map +1 -1
  129. package/dist/persistence/SqliteSchemaV2.d.ts.map +1 -1
  130. package/dist/persistence/SqliteSchemaV2.js +3 -12
  131. package/dist/persistence/SqliteSchemaV2.js.map +1 -1
  132. package/dist/pool/ConnectionPool.d.ts +3 -12
  133. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  134. package/dist/pool/ConnectionPool.js +5 -8
  135. package/dist/pool/ConnectionPool.js.map +1 -1
  136. package/dist/pool/IConnectionPool.d.ts +3 -9
  137. package/dist/pool/IConnectionPool.d.ts.map +1 -1
  138. package/dist/registry/BaseRegistry.d.ts +10 -2
  139. package/dist/registry/BaseRegistry.d.ts.map +1 -1
  140. package/dist/registry/BaseRegistry.js +128 -81
  141. package/dist/registry/BaseRegistry.js.map +1 -1
  142. package/dist/registry/SkillRegistry.d.ts +1 -7
  143. package/dist/registry/SkillRegistry.d.ts.map +1 -1
  144. package/dist/registry/SkillRegistry.js +0 -15
  145. package/dist/registry/SkillRegistry.js.map +1 -1
  146. package/dist/registry/ToolRegistry.d.ts +1 -9
  147. package/dist/registry/ToolRegistry.d.ts.map +1 -1
  148. package/dist/registry/ToolRegistry.js +0 -21
  149. package/dist/registry/ToolRegistry.js.map +1 -1
  150. package/dist/schema.d.ts +2 -1
  151. package/dist/schema.d.ts.map +1 -1
  152. package/dist/schema.js +3 -3
  153. package/dist/schema.js.map +1 -1
  154. package/dist/transport/BaseTransport.d.ts +0 -9
  155. package/dist/transport/BaseTransport.d.ts.map +1 -1
  156. package/dist/transport/BaseTransport.js +0 -11
  157. package/dist/transport/BaseTransport.js.map +1 -1
  158. package/dist/watchers/SkillWatcher.d.ts.map +1 -1
  159. package/dist/watchers/SkillWatcher.js +1 -1
  160. package/dist/watchers/SkillWatcher.js.map +1 -1
  161. package/package.json +1 -1
  162. package/dist/contracts/PersistenceBackend.js.map +0 -1
  163. package/dist/persistence/FileLegacyImport.d.ts +0 -2
  164. package/dist/persistence/FileLegacyImport.d.ts.map +0 -1
  165. package/dist/persistence/FileLegacyImport.js +0 -183
  166. package/dist/persistence/FileLegacyImport.js.map +0 -1
  167. package/dist/persistence/SessionScopedPersistence.d.ts +0 -4
  168. package/dist/persistence/SessionScopedPersistence.d.ts.map +0 -1
  169. package/dist/persistence/SessionScopedPersistence.js +0 -9
  170. package/dist/persistence/SessionScopedPersistence.js.map +0 -1
  171. package/dist/persistence/SqliteLegacyImport.d.ts +0 -14
  172. package/dist/persistence/SqliteLegacyImport.d.ts.map +0 -1
  173. package/dist/persistence/SqliteLegacyImport.js +0 -136
  174. package/dist/persistence/SqliteLegacyImport.js.map +0 -1
  175. package/dist/persistence/SqliteLegacySchema.d.ts +0 -15
  176. package/dist/persistence/SqliteLegacySchema.d.ts.map +0 -1
  177. package/dist/persistence/SqliteLegacySchema.js +0 -72
  178. package/dist/persistence/SqliteLegacySchema.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/FileWriter.js","sources":["../../src/persistence/FileWriter.ts"],"sourcesContent":["import { mkdir, realpath, rename, rmdir, unlink, writeFile } from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport { basename, dirname, join } from 'node:path';\nimport {\n\tPersistenceClosedError,\n\tPersistenceOwnershipError,\n\tPersistencePublicationError,\n} from '../errors.js';\n\nconst WRITER_LOCK_NAME = '.tracelattice-writer.lock';\n\nexport interface FileWriterOperations {\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly mkdirExclusive: (path: string) => Promise<void>;\n\treadonly realpath: (path: string) => Promise<string>;\n\treadonly rename: (source: string, destination: string) => Promise<void>;\n\treadonly rmdir: (path: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n\treadonly writeExclusiveUtf8: (path: string, content: string) => Promise<void>;\n}\n\nexport const nodeFileWriterOperations: FileWriterOperations = {\n\tmkdir: async (path) => {\n\t\tawait mkdir(path, { recursive: true });\n\t},\n\tmkdirExclusive: async (path) => await mkdir(path),\n\trealpath: async (path) => await realpath(path),\n\trename: async (source, destination) => await rename(source, destination),\n\trmdir: async (path) => await rmdir(path),\n\tunlink: async (path) => await unlink(path),\n\twriteExclusiveUtf8: async (path, content) => {\n\t\tawait writeFile(path, content, { encoding: 'utf-8', flag: 'wx' });\n\t},\n};\n\nexport function isFileNotFound(error: unknown): boolean {\n\treturn error instanceof Error && 'code' in error && error.code === 'ENOENT';\n}\n\nfunction isFileAlreadyPresent(error: unknown): boolean {\n\treturn error instanceof Error && 'code' in error && error.code === 'EEXIST';\n}\n\nfunction isDirectoryNotEmpty(error: unknown): boolean {\n\treturn error instanceof Error && 'code' in error && error.code === 'ENOTEMPTY';\n}\n\ntype DirectoryOwnership = {\n\treadonly canonicalDataDir: string;\n\treadonly lockPath: string;\n\treadonly markerPath: string;\n};\n\ntype WriterState = 'open' | 'closing' | 'closed';\n\nexport class FileWriter {\n\tprivate readonly _configuredDataDir: string;\n\tprivate readonly _operations: FileWriterOperations;\n\tprivate _ownershipPromise: Promise<DirectoryOwnership> | undefined;\n\tprivate _ownership: DirectoryOwnership | undefined;\n\tprivate _tail: Promise<void> = Promise.resolve();\n\tprivate _closePromise: Promise<void> | undefined;\n\tprivate _state: WriterState = 'open';\n\n\tconstructor(dataDir: string, operations: FileWriterOperations = nodeFileWriterOperations) {\n\t\tthis._configuredDataDir = dataDir;\n\t\tthis._operations = operations;\n\t}\n\n\tpublic async ready(): Promise<void> {\n\t\tif (this._state !== 'open') {\n\t\t\tthrow new PersistenceClosedError(this._configuredDataDir);\n\t\t}\n\t\tawait this._getOwnership();\n\t}\n\n\tpublic run<T>(operation: (canonicalDataDir: string) => Promise<T>): Promise<T> {\n\t\tif (this._state !== 'open') {\n\t\t\treturn Promise.reject(new PersistenceClosedError(this._configuredDataDir));\n\t\t}\n\n\t\tconst queued = this._tail.then(async () => {\n\t\t\tconst ownership = await this._getOwnership();\n\t\t\treturn await operation(ownership.canonicalDataDir);\n\t\t});\n\t\tthis._tail = queued.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined\n\t\t);\n\t\treturn queued;\n\t}\n\n\tpublic async publish(targetPath: string, content: string): Promise<void> {\n\t\tconst temporaryPath = join(\n\t\t\tdirname(targetPath),\n\t\t\t`.${basename(targetPath)}.${process.pid}.${randomUUID()}.tmp`\n\t\t);\n\t\tlet stage: 'temporary-write' | 'atomic-replacement' = 'temporary-write';\n\n\t\ttry {\n\t\t\tawait this._operations.writeExclusiveUtf8(temporaryPath, content);\n\t\t\tstage = 'atomic-replacement';\n\t\t\tawait this._operations.rename(temporaryPath, targetPath);\n\t\t} catch (error) {\n\t\t\tconst publicationError = new PersistencePublicationError(targetPath, stage, error);\n\t\t\ttry {\n\t\t\t\tawait this._operations.unlink(temporaryPath);\n\t\t\t} catch (cleanupError) {\n\t\t\t\tif (!isFileNotFound(cleanupError)) {\n\t\t\t\t\tthrow new PersistencePublicationError(\n\t\t\t\t\t\ttargetPath,\n\t\t\t\t\t\t'cleanup',\n\t\t\t\t\t\tnew AggregateError([publicationError, cleanupError])\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow publicationError;\n\t\t}\n\t}\n\n\tpublic close(): Promise<void> {\n\t\tif (this._closePromise) {\n\t\t\treturn this._closePromise;\n\t\t}\n\n\t\tthis._state = 'closing';\n\t\tthis._closePromise = (async () => {\n\t\t\ttry {\n\t\t\t\tawait this._tail;\n\t\t\t\tawait this._releaseOwnership();\n\t\t\t} finally {\n\t\t\t\tthis._state = 'closed';\n\t\t\t}\n\t\t})();\n\t\treturn this._closePromise;\n\t}\n\n\tprivate _getOwnership(): Promise<DirectoryOwnership> {\n\t\tthis._ownershipPromise ??= this._acquireOwnership();\n\t\treturn this._ownershipPromise;\n\t}\n\n\tprivate async _acquireOwnership(): Promise<DirectoryOwnership> {\n\t\tawait this._operations.mkdir(this._configuredDataDir);\n\t\tconst canonicalDataDir = await this._operations.realpath(this._configuredDataDir);\n\t\tconst lockPath = join(canonicalDataDir, WRITER_LOCK_NAME);\n\t\tconst markerName = `${process.pid}-${randomUUID()}.owner`;\n\t\tconst markerPath = join(lockPath, markerName);\n\n\t\ttry {\n\t\t\tawait this._operations.mkdirExclusive(lockPath);\n\t\t} catch (error) {\n\t\t\tif (isFileAlreadyPresent(error)) {\n\t\t\t\tthrow new PersistenceOwnershipError(canonicalDataDir, lockPath, error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this._operations.writeExclusiveUtf8(markerPath, `${process.pid}\\n`);\n\t\t} catch (error) {\n\t\t\tawait this._cleanupFailedAcquisition(lockPath, markerPath, error);\n\t\t}\n\n\t\tconst ownership = { canonicalDataDir, lockPath, markerPath } satisfies DirectoryOwnership;\n\t\tthis._ownership = ownership;\n\t\treturn ownership;\n\t}\n\n\tprivate async _cleanupFailedAcquisition(\n\t\tlockPath: string,\n\t\tmarkerPath: string,\n\t\tacquisitionError: unknown\n\t): Promise<never> {\n\t\tconst failures: unknown[] = [acquisitionError];\n\t\ttry {\n\t\t\tawait this._operations.unlink(markerPath);\n\t\t} catch (unlinkError) {\n\t\t\tif (!isFileNotFound(unlinkError)) {\n\t\t\t\tfailures.push(unlinkError);\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tawait this._operations.rmdir(lockPath);\n\t\t} catch (removeDirectoryError) {\n\t\t\tif (!isFileNotFound(removeDirectoryError) && !isDirectoryNotEmpty(removeDirectoryError)) {\n\t\t\t\tfailures.push(removeDirectoryError);\n\t\t\t}\n\t\t}\n\t\tthrow new PersistencePublicationError(lockPath, 'cleanup', new AggregateError(failures));\n\t}\n\n\tprivate async _releaseOwnership(): Promise<void> {\n\t\tconst ownership = this._ownership;\n\t\tthis._ownership = undefined;\n\t\tif (!ownership) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this._operations.unlink(ownership.markerPath);\n\t\t} catch (error) {\n\t\t\tif (isFileNotFound(error)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new PersistencePublicationError(ownership.markerPath, 'cleanup', error);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this._operations.rmdir(ownership.lockPath);\n\t\t} catch (error) {\n\t\t\tif (!isFileNotFound(error) && !isDirectoryNotEmpty(error)) {\n\t\t\t\tthrow new PersistencePublicationError(ownership.lockPath, 'cleanup', error);\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["WRITER_LOCK_NAME","nodeFileWriterOperations","path","mkdir","realpath","source","destination","rename","rmdir","unlink","content","writeFile","isFileNotFound","error","Error","isFileAlreadyPresent","isDirectoryNotEmpty","FileWriter","Promise","dataDir","operations","PersistenceClosedError","operation","queued","ownership","undefined","targetPath","temporaryPath","join","dirname","basename","process","randomUUID","stage","publicationError","PersistencePublicationError","cleanupError","AggregateError","canonicalDataDir","lockPath","markerName","markerPath","PersistenceOwnershipError","acquisitionError","failures","unlinkError","removeDirectoryError"],"mappings":"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"}
1
+ {"version":3,"file":"persistence/FileWriter.js","sources":["../../src/persistence/FileWriter.ts"],"sourcesContent":["import { mkdir, realpath, rename, rmdir, unlink, writeFile } from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport { basename, dirname, join } from 'node:path';\nimport {\n\tPersistenceClosedError,\n\tPersistenceOwnershipError,\n\tPersistencePublicationError,\n} from '../errors.js';\n\nexport const FILE_WRITER_LOCK_NAME = '.tracelattice-writer.lock';\n\nexport interface FileWriterOperations {\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly mkdirExclusive: (path: string) => Promise<void>;\n\treadonly realpath: (path: string) => Promise<string>;\n\treadonly rename: (source: string, destination: string) => Promise<void>;\n\treadonly rmdir: (path: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n\treadonly writeExclusiveUtf8: (path: string, content: string) => Promise<void>;\n}\n\nexport const nodeFileWriterOperations: FileWriterOperations = {\n\tmkdir: async (path) => {\n\t\tawait mkdir(path, { recursive: true });\n\t},\n\tmkdirExclusive: async (path) => await mkdir(path),\n\trealpath: async (path) => await realpath(path),\n\trename: async (source, destination) => await rename(source, destination),\n\trmdir: async (path) => await rmdir(path),\n\tunlink: async (path) => await unlink(path),\n\twriteExclusiveUtf8: async (path, content) => {\n\t\tawait writeFile(path, content, { encoding: 'utf-8', flag: 'wx' });\n\t},\n};\n\nexport function isFileNotFound(error: unknown): boolean {\n\treturn error instanceof Error && 'code' in error && error.code === 'ENOENT';\n}\n\nfunction isFileAlreadyPresent(error: unknown): boolean {\n\treturn error instanceof Error && 'code' in error && error.code === 'EEXIST';\n}\n\nfunction isDirectoryNotEmpty(error: unknown): boolean {\n\treturn error instanceof Error && 'code' in error && error.code === 'ENOTEMPTY';\n}\n\ntype DirectoryOwnership = {\n\treadonly canonicalDataDir: string;\n\treadonly lockPath: string;\n\treadonly markerPath: string;\n};\n\ntype WriterState = 'open' | 'closing' | 'closed';\n\nexport class FileWriter {\n\tprivate readonly _configuredDataDir: string;\n\tprivate readonly _operations: FileWriterOperations;\n\tprivate _ownershipPromise: Promise<DirectoryOwnership> | undefined;\n\tprivate _ownership: DirectoryOwnership | undefined;\n\tprivate _tail: Promise<void> = Promise.resolve();\n\tprivate _closePromise: Promise<void> | undefined;\n\tprivate _state: WriterState = 'open';\n\n\tconstructor(dataDir: string, operations: FileWriterOperations = nodeFileWriterOperations) {\n\t\tthis._configuredDataDir = dataDir;\n\t\tthis._operations = operations;\n\t}\n\n\tpublic async ready(): Promise<void> {\n\t\tif (this._state !== 'open') {\n\t\t\tthrow new PersistenceClosedError(this._configuredDataDir);\n\t\t}\n\t\tawait this._getOwnership();\n\t}\n\n\tpublic run<T>(operation: (canonicalDataDir: string) => Promise<T>): Promise<T> {\n\t\tif (this._state !== 'open') {\n\t\t\treturn Promise.reject(new PersistenceClosedError(this._configuredDataDir));\n\t\t}\n\n\t\tconst queued = this._tail.then(async () => {\n\t\t\tconst ownership = await this._getOwnership();\n\t\t\treturn await operation(ownership.canonicalDataDir);\n\t\t});\n\t\tthis._tail = queued.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined\n\t\t);\n\t\treturn queued;\n\t}\n\n\tpublic async publish(targetPath: string, content: string): Promise<void> {\n\t\tconst temporaryPath = join(\n\t\t\tdirname(targetPath),\n\t\t\t`.${basename(targetPath)}.${process.pid}.${randomUUID()}.tmp`\n\t\t);\n\t\tlet stage: 'temporary-write' | 'atomic-replacement' = 'temporary-write';\n\n\t\ttry {\n\t\t\tawait this._operations.writeExclusiveUtf8(temporaryPath, content);\n\t\t\tstage = 'atomic-replacement';\n\t\t\tawait this._operations.rename(temporaryPath, targetPath);\n\t\t} catch (error) {\n\t\t\tconst publicationError = new PersistencePublicationError(targetPath, stage, error);\n\t\t\ttry {\n\t\t\t\tawait this._operations.unlink(temporaryPath);\n\t\t\t} catch (cleanupError) {\n\t\t\t\tif (!isFileNotFound(cleanupError)) {\n\t\t\t\t\tthrow new PersistencePublicationError(\n\t\t\t\t\t\ttargetPath,\n\t\t\t\t\t\t'cleanup',\n\t\t\t\t\t\tnew AggregateError([publicationError, cleanupError])\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow publicationError;\n\t\t}\n\t}\n\n\tpublic close(): Promise<void> {\n\t\tif (this._closePromise) {\n\t\t\treturn this._closePromise;\n\t\t}\n\n\t\tthis._state = 'closing';\n\t\tthis._closePromise = (async () => {\n\t\t\ttry {\n\t\t\t\tawait this._tail;\n\t\t\t\tawait this._releaseOwnership();\n\t\t\t} finally {\n\t\t\t\tthis._state = 'closed';\n\t\t\t}\n\t\t})();\n\t\treturn this._closePromise;\n\t}\n\n\tprivate _getOwnership(): Promise<DirectoryOwnership> {\n\t\tthis._ownershipPromise ??= this._acquireOwnership();\n\t\treturn this._ownershipPromise;\n\t}\n\n\tprivate async _acquireOwnership(): Promise<DirectoryOwnership> {\n\t\tawait this._operations.mkdir(this._configuredDataDir);\n\t\tconst canonicalDataDir = await this._operations.realpath(this._configuredDataDir);\n\t\tconst lockPath = join(canonicalDataDir, FILE_WRITER_LOCK_NAME);\n\t\tconst markerName = `${process.pid}-${randomUUID()}.owner`;\n\t\tconst markerPath = join(lockPath, markerName);\n\n\t\ttry {\n\t\t\tawait this._operations.mkdirExclusive(lockPath);\n\t\t} catch (error) {\n\t\t\tif (isFileAlreadyPresent(error)) {\n\t\t\t\tthrow new PersistenceOwnershipError(canonicalDataDir, lockPath, error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this._operations.writeExclusiveUtf8(markerPath, `${process.pid}\\n`);\n\t\t} catch (error) {\n\t\t\tawait this._cleanupFailedAcquisition(lockPath, markerPath, error);\n\t\t}\n\n\t\tconst ownership = { canonicalDataDir, lockPath, markerPath } satisfies DirectoryOwnership;\n\t\tthis._ownership = ownership;\n\t\treturn ownership;\n\t}\n\n\tprivate async _cleanupFailedAcquisition(\n\t\tlockPath: string,\n\t\tmarkerPath: string,\n\t\tacquisitionError: unknown\n\t): Promise<never> {\n\t\tconst failures: unknown[] = [acquisitionError];\n\t\ttry {\n\t\t\tawait this._operations.unlink(markerPath);\n\t\t} catch (unlinkError) {\n\t\t\tif (!isFileNotFound(unlinkError)) {\n\t\t\t\tfailures.push(unlinkError);\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tawait this._operations.rmdir(lockPath);\n\t\t} catch (removeDirectoryError) {\n\t\t\tif (!isFileNotFound(removeDirectoryError) && !isDirectoryNotEmpty(removeDirectoryError)) {\n\t\t\t\tfailures.push(removeDirectoryError);\n\t\t\t}\n\t\t}\n\t\tthrow new PersistencePublicationError(lockPath, 'cleanup', new AggregateError(failures));\n\t}\n\n\tprivate async _releaseOwnership(): Promise<void> {\n\t\tconst ownership = this._ownership;\n\t\tthis._ownership = undefined;\n\t\tif (!ownership) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this._operations.unlink(ownership.markerPath);\n\t\t} catch (error) {\n\t\t\tif (isFileNotFound(error)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new PersistencePublicationError(ownership.markerPath, 'cleanup', error);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this._operations.rmdir(ownership.lockPath);\n\t\t} catch (error) {\n\t\t\tif (!isFileNotFound(error) && !isDirectoryNotEmpty(error)) {\n\t\t\t\tthrow new PersistencePublicationError(ownership.lockPath, 'cleanup', error);\n\t\t\t}\n\t\t}\n\t}\n}\n"],"names":["FILE_WRITER_LOCK_NAME","nodeFileWriterOperations","path","mkdir","realpath","source","destination","rename","rmdir","unlink","content","writeFile","isFileNotFound","error","Error","isFileAlreadyPresent","isDirectoryNotEmpty","FileWriter","Promise","dataDir","operations","PersistenceClosedError","operation","queued","ownership","undefined","targetPath","temporaryPath","join","dirname","basename","process","randomUUID","stage","publicationError","PersistencePublicationError","cleanupError","AggregateError","canonicalDataDir","lockPath","markerName","markerPath","PersistenceOwnershipError","acquisitionError","failures","unlinkError","removeDirectoryError"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import type { ThoughtData } from '../core/thought.js';
2
2
  import type { Edge } from '../core/graph/Edge.js';
3
3
  import type { Summary } from '../core/compression/Summary.js';
4
- import type { SessionScopedPersistenceBackend } from '../contracts/PersistenceBackend.js';
4
+ import type { PersistenceBackend } from '../contracts/PersistenceBackend.js';
5
5
  import { type BranchId, type SessionId } from '../contracts/ids.js';
6
6
  export interface MemoryPersistenceOptions {
7
7
  maxSize?: number;
8
8
  maxHistorySize?: number;
9
9
  persistBranches?: boolean;
10
10
  }
11
- export declare class MemoryPersistence implements SessionScopedPersistenceBackend {
11
+ export declare class MemoryPersistence implements PersistenceBackend {
12
12
  private readonly _histories;
13
13
  private readonly _branches;
14
14
  private readonly _edges;
@@ -16,30 +16,20 @@ export declare class MemoryPersistence implements SessionScopedPersistenceBacken
16
16
  private readonly _maxSize;
17
17
  private readonly _persistBranches;
18
18
  constructor(options?: MemoryPersistenceOptions);
19
- saveThought(thought: ThoughtData): Promise<void>;
20
- saveThoughtForSession(sessionId: SessionId, thought: ThoughtData, operation?: 'saveThought' | 'saveThoughtForSession'): Promise<void>;
21
- loadHistory(): Promise<ThoughtData[]>;
19
+ saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void>;
22
20
  loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]>;
23
- saveBranch(branchId: BranchId, thoughts: ThoughtData[]): Promise<void>;
24
- saveBranchForSession(sessionId: SessionId, branchId: BranchId, thoughts: readonly ThoughtData[], operation?: 'saveBranch' | 'saveBranchForSession'): Promise<void>;
25
- deleteBranch(branchId: BranchId): Promise<void>;
21
+ saveBranchForSession(sessionId: SessionId, branchId: BranchId, thoughts: readonly ThoughtData[]): Promise<void>;
26
22
  deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void>;
27
- loadBranch(branchId: BranchId): Promise<ThoughtData[] | undefined>;
28
23
  loadBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<ThoughtData[] | undefined>;
29
- listBranches(): Promise<BranchId[]>;
30
24
  listBranchesForSession(sessionId: SessionId): Promise<BranchId[]>;
31
25
  listSessions(): Promise<SessionId[]>;
32
26
  healthy(): Promise<boolean>;
33
- clear(): Promise<void>;
27
+ clearAll(): Promise<void>;
34
28
  clearSession(sessionId: SessionId): Promise<void>;
35
29
  close(): Promise<void>;
36
30
  saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void>;
37
31
  loadEdges(sessionId: SessionId): Promise<Edge[]>;
38
- listEdgeSessions(): Promise<SessionId[]>;
39
32
  saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void>;
40
33
  loadSummaries(sessionId: SessionId): Promise<Summary[]>;
41
- getHistorySize(): number;
42
- getBranchCount(): number;
43
- getBranchIds(): BranchId[];
44
34
  }
45
35
  //# sourceMappingURL=MemoryPersistence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/MemoryPersistence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MemoryPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/MemoryPersistence.ts"],"names":[],"mappings":"AAAA,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,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAe,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAcjF,MAAM,WAAW,wBAAwB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,iBAAkB,YAAW,kBAAkB;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuC;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsD;IAChF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAE/B,OAAO,GAAE,wBAA6B;IAMrC,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhF,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAInE,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;IAuBH,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/E,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAQxB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKjE,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAQpC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAI3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAEtB,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAIhD,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAIpE"}
@@ -1,4 +1,4 @@
1
- import { GLOBAL_SESSION_ID, asSessionId } from "../contracts/ids.js";
1
+ import { asSessionId } from "../contracts/ids.js";
2
2
  import { assertBranchScope, assertEdgeScopes, assertPersistableThoughtCollections, assertSummaryScopes, assertThoughtScope, assertUniqueRecordIds, compareCodePoint, compareCreatedThenId, parsePersistenceBranchId } from "./PersistenceScope.js";
3
3
  class MemoryPersistence {
4
4
  _histories = new Map();
@@ -12,12 +12,9 @@ class MemoryPersistence {
12
12
  this._maxSize = void 0 !== configuredSize && configuredSize > 0 ? configuredSize : void 0;
13
13
  this._persistBranches = options.persistBranches ?? true;
14
14
  }
15
- async saveThought(thought) {
16
- await this.saveThoughtForSession(GLOBAL_SESSION_ID, thought, 'saveThought');
17
- }
18
- async saveThoughtForSession(sessionId, thought, operation = 'saveThoughtForSession') {
15
+ async saveThoughtForSession(sessionId, thought) {
19
16
  const validatedSessionId = asSessionId(sessionId);
20
- assertThoughtScope(operation, validatedSessionId, thought);
17
+ assertThoughtScope('saveThoughtForSession', validatedSessionId, thought);
21
18
  const history = [
22
19
  ...this._histories.get(validatedSessionId) ?? [],
23
20
  thought
@@ -35,21 +32,15 @@ class MemoryPersistence {
35
32
  assertPersistableThoughtCollections(collections, `${validatedSessionId}/thoughts`);
36
33
  this._histories.set(validatedSessionId, void 0 === this._maxSize ? history : history.slice(-this._maxSize));
37
34
  }
38
- async loadHistory() {
39
- return await this.loadHistoryForSession(GLOBAL_SESSION_ID);
40
- }
41
35
  async loadHistoryForSession(sessionId) {
42
36
  return [
43
37
  ...this._histories.get(asSessionId(sessionId)) ?? []
44
38
  ];
45
39
  }
46
- async saveBranch(branchId, thoughts) {
47
- await this.saveBranchForSession(GLOBAL_SESSION_ID, branchId, thoughts, 'saveBranch');
48
- }
49
- async saveBranchForSession(sessionId, branchId, thoughts, operation = 'saveBranchForSession') {
40
+ async saveBranchForSession(sessionId, branchId, thoughts) {
50
41
  const validatedSessionId = asSessionId(sessionId);
51
42
  const validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);
52
- assertBranchScope(operation, validatedSessionId, validatedBranchId, thoughts);
43
+ assertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);
53
44
  const branches = new Map(this._branches.get(validatedSessionId) ?? []);
54
45
  branches.set(validatedBranchId, [
55
46
  ...thoughts
@@ -68,9 +59,6 @@ class MemoryPersistence {
68
59
  if (!this._persistBranches) return;
69
60
  this._branches.set(validatedSessionId, branches);
70
61
  }
71
- async deleteBranch(branchId) {
72
- await this.deleteBranchForSession(GLOBAL_SESSION_ID, branchId);
73
- }
74
62
  async deleteBranchForSession(sessionId, branchId) {
75
63
  if (!this._persistBranches) return;
76
64
  const validatedSessionId = asSessionId(sessionId);
@@ -80,9 +68,6 @@ class MemoryPersistence {
80
68
  branches.delete(validatedBranchId);
81
69
  if (0 === branches.size) this._branches.delete(validatedSessionId);
82
70
  }
83
- async loadBranch(branchId) {
84
- return await this.loadBranchForSession(GLOBAL_SESSION_ID, branchId);
85
- }
86
71
  async loadBranchForSession(sessionId, branchId) {
87
72
  if (!this._persistBranches) return;
88
73
  const validatedSessionId = asSessionId(sessionId);
@@ -92,9 +77,6 @@ class MemoryPersistence {
92
77
  ...branch
93
78
  ];
94
79
  }
95
- async listBranches() {
96
- return await this.listBranchesForSession(GLOBAL_SESSION_ID);
97
- }
98
80
  async listBranchesForSession(sessionId) {
99
81
  if (!this._persistBranches) return [];
100
82
  return [
@@ -116,7 +98,7 @@ class MemoryPersistence {
116
98
  async healthy() {
117
99
  return true;
118
100
  }
119
- async clear() {
101
+ async clearAll() {
120
102
  this._histories.clear();
121
103
  this._branches.clear();
122
104
  this._edges.clear();
@@ -144,11 +126,6 @@ class MemoryPersistence {
144
126
  ...this._edges.get(asSessionId(sessionId)) ?? []
145
127
  ].sort(compareCreatedThenId);
146
128
  }
147
- async listEdgeSessions() {
148
- return [
149
- ...this._edges.keys()
150
- ].sort(compareCodePoint);
151
- }
152
129
  async saveSummaries(sessionId, summaries) {
153
130
  const validatedSessionId = asSessionId(sessionId);
154
131
  assertSummaryScopes(validatedSessionId, summaries);
@@ -163,17 +140,6 @@ class MemoryPersistence {
163
140
  ...this._summaries.get(asSessionId(sessionId)) ?? []
164
141
  ].sort(compareCreatedThenId);
165
142
  }
166
- getHistorySize() {
167
- return this._histories.get(GLOBAL_SESSION_ID)?.length ?? 0;
168
- }
169
- getBranchCount() {
170
- return this._branches.get(GLOBAL_SESSION_ID)?.size ?? 0;
171
- }
172
- getBranchIds() {
173
- return [
174
- ...this._branches.get(GLOBAL_SESSION_ID)?.keys() ?? []
175
- ].sort(compareCodePoint);
176
- }
177
143
  }
178
144
  export { MemoryPersistence };
179
145
 
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/MemoryPersistence.js","sources":["../../src/persistence/MemoryPersistence.ts"],"sourcesContent":["import type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { SessionScopedPersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport { asSessionId, GLOBAL_SESSION_ID, type BranchId, type SessionId } from '../contracts/ids.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tassertUniqueRecordIds,\n\tcompareCodePoint,\n\tcompareCreatedThenId,\n\tparsePersistenceBranchId,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\n\nexport interface MemoryPersistenceOptions {\n\tmaxSize?: number;\n\tmaxHistorySize?: number;\n\tpersistBranches?: boolean;\n}\n\nexport class MemoryPersistence implements SessionScopedPersistenceBackend {\n\tprivate readonly _histories = new Map<SessionId, ThoughtData[]>();\n\tprivate readonly _branches = new Map<SessionId, Map<BranchId, ThoughtData[]>>();\n\tprivate readonly _edges = new Map<SessionId, Edge[]>();\n\tprivate readonly _summaries = new Map<SessionId, Summary[]>();\n\tprivate readonly _maxSize: number | undefined;\n\tprivate readonly _persistBranches: boolean;\n\n\tconstructor(options: MemoryPersistenceOptions = {}) {\n\t\tconst configuredSize = options.maxHistorySize ?? options.maxSize;\n\t\tthis._maxSize = configuredSize !== undefined && configuredSize > 0 ? configuredSize : undefined;\n\t\tthis._persistBranches = options.persistBranches ?? true;\n\t}\n\n\tpublic async saveThought(thought: ThoughtData): Promise<void> {\n\t\tawait this.saveThoughtForSession(GLOBAL_SESSION_ID, thought, 'saveThought');\n\t}\n\n\tpublic async saveThoughtForSession(\n\t\tsessionId: SessionId,\n\t\tthought: ThoughtData,\n\t\toperation: 'saveThought' | 'saveThoughtForSession' = 'saveThoughtForSession'\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope(operation, validatedSessionId, thought);\n\t\tconst history = [...(this._histories.get(validatedSessionId) ?? []), thought];\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{ sessionId: validatedSessionId, thoughts: history },\n\t\t];\n\t\tfor (const branch of this._branches.get(validatedSessionId)?.values() ?? []) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(collections, `${validatedSessionId}/thoughts`);\n\t\tthis._histories.set(\n\t\t\tvalidatedSessionId,\n\t\t\tthis._maxSize === undefined ? history : history.slice(-this._maxSize)\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\treturn [...(this._histories.get(asSessionId(sessionId)) ?? [])];\n\t}\n\n\tpublic async saveBranch(branchId: BranchId, thoughts: ThoughtData[]): Promise<void> {\n\t\tawait this.saveBranchForSession(GLOBAL_SESSION_ID, branchId, thoughts, 'saveBranch');\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[],\n\t\toperation: 'saveBranch' | 'saveBranchForSession' = 'saveBranchForSession'\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tassertBranchScope(operation, validatedSessionId, validatedBranchId, thoughts);\n\t\tconst branches = new Map(this._branches.get(validatedSessionId) ?? []);\n\t\tbranches.set(validatedBranchId, [...thoughts]);\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{\n\t\t\t\tsessionId: validatedSessionId,\n\t\t\t\tthoughts: this._histories.get(validatedSessionId) ?? [],\n\t\t\t},\n\t\t];\n\t\tfor (const branch of branches.values()) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(\n\t\t\tcollections,\n\t\t\t`${validatedSessionId}/branches/${validatedBranchId}`\n\t\t);\n\t\tif (!this._persistBranches) return;\n\t\tthis._branches.set(validatedSessionId, branches);\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, `${validatedSessionId}/branches`);\n\t\tconst branches = this._branches.get(validatedSessionId);\n\t\tif (branches === undefined) return;\n\t\tbranches.delete(validatedBranchId);\n\t\tif (branches.size === 0) this._branches.delete(validatedSessionId);\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, `${validatedSessionId}/branches`);\n\t\tconst branch = this._branches.get(validatedSessionId)?.get(validatedBranchId);\n\t\treturn branch === undefined ? undefined : [...branch];\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._branches.get(asSessionId(sessionId))?.keys() ?? [])].sort(compareCodePoint);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\tconst sessions = new Set<SessionId>();\n\t\tfor (const namespace of [this._histories, this._branches, this._edges, this._summaries]) {\n\t\t\tfor (const sessionId of namespace.keys()) sessions.add(sessionId);\n\t\t}\n\t\treturn [...sessions].sort(compareCodePoint);\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\treturn true;\n\t}\n\n\tpublic async clear(): Promise<void> {\n\t\tthis._histories.clear();\n\t\tthis._branches.clear();\n\t\tthis._edges.clear();\n\t\tthis._summaries.clear();\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tthis._histories.delete(validatedSessionId);\n\t\tthis._branches.delete(validatedSessionId);\n\t\tthis._edges.delete(validatedSessionId);\n\t\tthis._summaries.delete(validatedSessionId);\n\t}\n\n\tpublic async close(): Promise<void> {}\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\tassertUniqueRecordIds(edges, `${validatedSessionId}/edges`, 'edge');\n\t\tif (edges.length === 0) this._edges.delete(validatedSessionId);\n\t\telse this._edges.set(validatedSessionId, [...edges].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\treturn [...(this._edges.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n\n\tpublic async listEdgeSessions(): Promise<SessionId[]> {\n\t\treturn [...this._edges.keys()].sort(compareCodePoint);\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\tassertUniqueRecordIds(summaries, `${validatedSessionId}/summaries`, 'summary');\n\t\tif (summaries.length === 0) this._summaries.delete(validatedSessionId);\n\t\telse this._summaries.set(validatedSessionId, [...summaries].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\treturn [...(this._summaries.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n\n\tpublic getHistorySize(): number {\n\t\treturn this._histories.get(GLOBAL_SESSION_ID)?.length ?? 0;\n\t}\n\n\tpublic getBranchCount(): number {\n\t\treturn this._branches.get(GLOBAL_SESSION_ID)?.size ?? 0;\n\t}\n\n\tpublic getBranchIds(): BranchId[] {\n\t\treturn [...(this._branches.get(GLOBAL_SESSION_ID)?.keys() ?? [])].sort(compareCodePoint);\n\t}\n}\n"],"names":["MemoryPersistence","Map","options","configuredSize","undefined","thought","GLOBAL_SESSION_ID","sessionId","operation","validatedSessionId","asSessionId","assertThoughtScope","history","collections","branch","assertPersistableThoughtCollections","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","branches","compareCodePoint","sessions","Set","namespace","edges","assertEdgeScopes","assertUniqueRecordIds","compareCreatedThenId","summaries","assertSummaryScopes"],"mappings":"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"}
1
+ {"version":3,"file":"persistence/MemoryPersistence.js","sources":["../../src/persistence/MemoryPersistence.ts"],"sourcesContent":["import type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport { asSessionId, type BranchId, type SessionId } from '../contracts/ids.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tassertUniqueRecordIds,\n\tcompareCodePoint,\n\tcompareCreatedThenId,\n\tparsePersistenceBranchId,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\n\nexport interface MemoryPersistenceOptions {\n\tmaxSize?: number;\n\tmaxHistorySize?: number;\n\tpersistBranches?: boolean;\n}\n\nexport class MemoryPersistence implements PersistenceBackend {\n\tprivate readonly _histories = new Map<SessionId, ThoughtData[]>();\n\tprivate readonly _branches = new Map<SessionId, Map<BranchId, ThoughtData[]>>();\n\tprivate readonly _edges = new Map<SessionId, Edge[]>();\n\tprivate readonly _summaries = new Map<SessionId, Summary[]>();\n\tprivate readonly _maxSize: number | undefined;\n\tprivate readonly _persistBranches: boolean;\n\n\tconstructor(options: MemoryPersistenceOptions = {}) {\n\t\tconst configuredSize = options.maxHistorySize ?? options.maxSize;\n\t\tthis._maxSize = configuredSize !== undefined && configuredSize > 0 ? configuredSize : undefined;\n\t\tthis._persistBranches = options.persistBranches ?? true;\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\tconst history = [...(this._histories.get(validatedSessionId) ?? []), thought];\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{ sessionId: validatedSessionId, thoughts: history },\n\t\t];\n\t\tfor (const branch of this._branches.get(validatedSessionId)?.values() ?? []) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(collections, `${validatedSessionId}/thoughts`);\n\t\tthis._histories.set(\n\t\t\tvalidatedSessionId,\n\t\t\tthis._maxSize === undefined ? history : history.slice(-this._maxSize)\n\t\t);\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\treturn [...(this._histories.get(asSessionId(sessionId)) ?? [])];\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, `${validatedSessionId}/branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tconst branches = new Map(this._branches.get(validatedSessionId) ?? []);\n\t\tbranches.set(validatedBranchId, [...thoughts]);\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{\n\t\t\t\tsessionId: validatedSessionId,\n\t\t\t\tthoughts: this._histories.get(validatedSessionId) ?? [],\n\t\t\t},\n\t\t];\n\t\tfor (const branch of branches.values()) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(\n\t\t\tcollections,\n\t\t\t`${validatedSessionId}/branches/${validatedBranchId}`\n\t\t);\n\t\tif (!this._persistBranches) return;\n\t\tthis._branches.set(validatedSessionId, branches);\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, `${validatedSessionId}/branches`);\n\t\tconst branches = this._branches.get(validatedSessionId);\n\t\tif (branches === undefined) return;\n\t\tbranches.delete(validatedBranchId);\n\t\tif (branches.size === 0) this._branches.delete(validatedSessionId);\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, `${validatedSessionId}/branches`);\n\t\tconst branch = this._branches.get(validatedSessionId)?.get(validatedBranchId);\n\t\treturn branch === undefined ? undefined : [...branch];\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\treturn [...(this._branches.get(asSessionId(sessionId))?.keys() ?? [])].sort(compareCodePoint);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\tconst sessions = new Set<SessionId>();\n\t\tfor (const namespace of [this._histories, this._branches, this._edges, this._summaries]) {\n\t\t\tfor (const sessionId of namespace.keys()) sessions.add(sessionId);\n\t\t}\n\t\treturn [...sessions].sort(compareCodePoint);\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\treturn true;\n\t}\n\n\tpublic async clearAll(): Promise<void> {\n\t\tthis._histories.clear();\n\t\tthis._branches.clear();\n\t\tthis._edges.clear();\n\t\tthis._summaries.clear();\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tthis._histories.delete(validatedSessionId);\n\t\tthis._branches.delete(validatedSessionId);\n\t\tthis._edges.delete(validatedSessionId);\n\t\tthis._summaries.delete(validatedSessionId);\n\t}\n\n\tpublic async close(): Promise<void> {}\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\tassertUniqueRecordIds(edges, `${validatedSessionId}/edges`, 'edge');\n\t\tif (edges.length === 0) this._edges.delete(validatedSessionId);\n\t\telse this._edges.set(validatedSessionId, [...edges].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\treturn [...(this._edges.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\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\tassertUniqueRecordIds(summaries, `${validatedSessionId}/summaries`, 'summary');\n\t\tif (summaries.length === 0) this._summaries.delete(validatedSessionId);\n\t\telse this._summaries.set(validatedSessionId, [...summaries].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\treturn [...(this._summaries.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n\n}\n"],"names":["MemoryPersistence","Map","options","configuredSize","undefined","sessionId","thought","validatedSessionId","asSessionId","assertThoughtScope","history","collections","branch","assertPersistableThoughtCollections","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","branches","compareCodePoint","sessions","Set","namespace","edges","assertEdgeScopes","assertUniqueRecordIds","compareCreatedThenId","summaries","assertSummaryScopes"],"mappings":"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"}
@@ -43,9 +43,7 @@ function parseThoughtData(raw, sourcePath) {
43
43
  ...void 0 === id ? {} : {
44
44
  id: asThoughtId(id)
45
45
  },
46
- ...void 0 === session_id ? {} : {
47
- session_id: asSessionId(session_id)
48
- },
46
+ session_id: asSessionId(session_id),
49
47
  ...void 0 === branch_id ? {} : {
50
48
  branch_id: parsePersistenceBranchId(branch_id, sourcePath)
51
49
  },
@@ -1 +1 @@
1
- {"version":3,"file":"persistence/PersistenceCodec.js","sources":["../../src/persistence/PersistenceCodec.ts"],"sourcesContent":["import * as v from 'valibot';\nimport {\n\tasBranchId,\n\tasEdgeId,\n\tasSessionId,\n\tasSuspensionToken,\n\tasThoughtId,\n} from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport { SummarySchema } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { StepRecommendation } from '../core/step.js';\nimport { EdgeSchema, SequentialThinkingSchema } from '../schema.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport { parsePersistenceBranchId } from './PersistenceScope.js';\n\ntype PersistedToolRecommendation = {\n\treadonly tool_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly suggested_inputs?: Record<string, string | number | boolean | null>;\n\treadonly alternatives?: string[];\n};\n\ntype PersistedSkillRecommendation = {\n\treadonly skill_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly alternatives?: string[];\n\treadonly allowed_tools?: string[];\n\treadonly user_invocable?: boolean;\n};\n\ntype PersistedStepRecommendation = {\n\treadonly step_description?: string;\n\treadonly recommended_tools: readonly PersistedToolRecommendation[];\n\treadonly recommended_skills?: readonly PersistedSkillRecommendation[];\n\treadonly expected_outcome?: string;\n\treadonly next_step_conditions?: string[];\n};\n\nfunction parseToolRecommendation(recommendation: PersistedToolRecommendation, sourcePath: string) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'tool recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseSkillRecommendation(\n\trecommendation: PersistedSkillRecommendation,\n\tsourcePath: string\n) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'skill recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseStepRecommendation(\n\tstep: PersistedStepRecommendation,\n\tsourcePath: string\n): StepRecommendation {\n\tif (step.step_description === undefined || step.expected_outcome === undefined) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'step recommendation defaults are absent');\n\t}\n\tconst { recommended_tools, recommended_skills, ...fields } = step;\n\treturn {\n\t\t...fields,\n\t\tstep_description: step.step_description,\n\t\texpected_outcome: step.expected_outcome,\n\t\trecommended_tools: recommended_tools.map((tool) => parseToolRecommendation(tool, sourcePath)),\n\t\t...(recommended_skills === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\trecommended_skills: recommended_skills.map((skill) =>\n\t\t\t\t\t\tparseSkillRecommendation(skill, sourcePath)\n\t\t\t\t\t),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseThoughtData(raw: unknown, sourcePath: string): ThoughtData {\n\tconst parsed = v.parse(SequentialThinkingSchema, raw);\n\tconst {\n\t\tid,\n\t\tsession_id,\n\t\tbranch_id,\n\t\tmerge_branch_ids,\n\t\tcontinuation_token,\n\t\tcurrent_step,\n\t\tprevious_steps,\n\t\t...thought\n\t} = parsed;\n\treturn {\n\t\t...thought,\n\t\t...(id === undefined ? {} : { id: asThoughtId(id) }),\n\t\t...(session_id === undefined ? {} : { session_id: asSessionId(session_id) }),\n\t\t...(branch_id === undefined\n\t\t\t? {}\n\t\t\t: { branch_id: parsePersistenceBranchId(branch_id, sourcePath) }),\n\t\t...(merge_branch_ids === undefined\n\t\t\t? {}\n\t\t\t: { merge_branch_ids: merge_branch_ids.map(asBranchId) }),\n\t\t...(continuation_token === undefined\n\t\t\t? {}\n\t\t\t: { continuation_token: asSuspensionToken(continuation_token) }),\n\t\t...(current_step === undefined\n\t\t\t? {}\n\t\t\t: { current_step: parseStepRecommendation(current_step, sourcePath) }),\n\t\t...(previous_steps === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\tprevious_steps: previous_steps.map((step) => parseStepRecommendation(step, sourcePath)),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseEdge(raw: unknown): Edge {\n\tconst parsed = v.parse(EdgeSchema, raw);\n\treturn {\n\t\t...parsed,\n\t\tid: asEdgeId(parsed.id),\n\t\tfrom: asThoughtId(parsed.from),\n\t\tto: asThoughtId(parsed.to),\n\t\tsessionId: asSessionId(parsed.sessionId),\n\t};\n}\n\nexport function parseSummary(raw: unknown, sourcePath: string): Summary {\n\tconst parsed = v.parse(SummarySchema, raw);\n\tconst { branchId, sessionId, rootThoughtId, coveredIds, coveredRange, ...summary } = parsed;\n\tconst [rangeStart, rangeEnd] = coveredRange;\n\tif (rangeStart === undefined || rangeEnd === undefined) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\tsourcePath,\n\t\t\t'summary coveredRange must contain two values'\n\t\t);\n\t}\n\treturn {\n\t\t...summary,\n\t\tsessionId: asSessionId(sessionId),\n\t\t...(branchId === undefined ? {} : { branchId: parsePersistenceBranchId(branchId, sourcePath) }),\n\t\trootThoughtId: asThoughtId(rootThoughtId),\n\t\tcoveredIds: coveredIds.map(asThoughtId),\n\t\tcoveredRange: [rangeStart, rangeEnd],\n\t};\n}\n"],"names":["parseToolRecommendation","recommendation","sourcePath","undefined","PersistenceCompatibilityError","parseSkillRecommendation","parseStepRecommendation","step","recommended_tools","recommended_skills","fields","tool","skill","parseThoughtData","raw","parsed","v","SequentialThinkingSchema","id","session_id","branch_id","merge_branch_ids","continuation_token","current_step","previous_steps","thought","asThoughtId","asSessionId","parsePersistenceBranchId","asBranchId","asSuspensionToken","parseEdge","EdgeSchema","asEdgeId","parseSummary","SummarySchema","branchId","sessionId","rootThoughtId","coveredIds","coveredRange","summary","rangeStart","rangeEnd"],"mappings":"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"}
1
+ {"version":3,"file":"persistence/PersistenceCodec.js","sources":["../../src/persistence/PersistenceCodec.ts"],"sourcesContent":["import * as v from 'valibot';\nimport {\n\tasBranchId,\n\tasEdgeId,\n\tasSessionId,\n\tasSuspensionToken,\n\tasThoughtId,\n} from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport { SummarySchema } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { StepRecommendation } from '../core/step.js';\nimport { EdgeSchema, SequentialThinkingSchema } from '../schema.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport { parsePersistenceBranchId } from './PersistenceScope.js';\n\ntype PersistedToolRecommendation = {\n\treadonly tool_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly suggested_inputs?: Record<string, string | number | boolean | null>;\n\treadonly alternatives?: string[];\n};\n\ntype PersistedSkillRecommendation = {\n\treadonly skill_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly alternatives?: string[];\n\treadonly allowed_tools?: string[];\n\treadonly user_invocable?: boolean;\n};\n\ntype PersistedStepRecommendation = {\n\treadonly step_description?: string;\n\treadonly recommended_tools: readonly PersistedToolRecommendation[];\n\treadonly recommended_skills?: readonly PersistedSkillRecommendation[];\n\treadonly expected_outcome?: string;\n\treadonly next_step_conditions?: string[];\n};\n\nfunction parseToolRecommendation(recommendation: PersistedToolRecommendation, sourcePath: string) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'tool recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseSkillRecommendation(\n\trecommendation: PersistedSkillRecommendation,\n\tsourcePath: string\n) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'skill recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseStepRecommendation(\n\tstep: PersistedStepRecommendation,\n\tsourcePath: string\n): StepRecommendation {\n\tif (step.step_description === undefined || step.expected_outcome === undefined) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'step recommendation defaults are absent');\n\t}\n\tconst { recommended_tools, recommended_skills, ...fields } = step;\n\treturn {\n\t\t...fields,\n\t\tstep_description: step.step_description,\n\t\texpected_outcome: step.expected_outcome,\n\t\trecommended_tools: recommended_tools.map((tool) => parseToolRecommendation(tool, sourcePath)),\n\t\t...(recommended_skills === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\trecommended_skills: recommended_skills.map((skill) =>\n\t\t\t\t\t\tparseSkillRecommendation(skill, sourcePath)\n\t\t\t\t\t),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseThoughtData(raw: unknown, sourcePath: string): ThoughtData {\n\tconst parsed = v.parse(SequentialThinkingSchema, raw);\n\tconst {\n\t\tid,\n\t\tsession_id,\n\t\tbranch_id,\n\t\tmerge_branch_ids,\n\t\tcontinuation_token,\n\t\tcurrent_step,\n\t\tprevious_steps,\n\t\t...thought\n\t} = parsed;\n\treturn {\n\t\t...thought,\n\t\t...(id === undefined ? {} : { id: asThoughtId(id) }),\n\t\tsession_id: asSessionId(session_id),\n\t\t...(branch_id === undefined\n\t\t\t? {}\n\t\t\t: { branch_id: parsePersistenceBranchId(branch_id, sourcePath) }),\n\t\t...(merge_branch_ids === undefined\n\t\t\t? {}\n\t\t\t: { merge_branch_ids: merge_branch_ids.map(asBranchId) }),\n\t\t...(continuation_token === undefined\n\t\t\t? {}\n\t\t\t: { continuation_token: asSuspensionToken(continuation_token) }),\n\t\t...(current_step === undefined\n\t\t\t? {}\n\t\t\t: { current_step: parseStepRecommendation(current_step, sourcePath) }),\n\t\t...(previous_steps === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\tprevious_steps: previous_steps.map((step) => parseStepRecommendation(step, sourcePath)),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseEdge(raw: unknown): Edge {\n\tconst parsed = v.parse(EdgeSchema, raw);\n\treturn {\n\t\t...parsed,\n\t\tid: asEdgeId(parsed.id),\n\t\tfrom: asThoughtId(parsed.from),\n\t\tto: asThoughtId(parsed.to),\n\t\tsessionId: asSessionId(parsed.sessionId),\n\t};\n}\n\nexport function parseSummary(raw: unknown, sourcePath: string): Summary {\n\tconst parsed = v.parse(SummarySchema, raw);\n\tconst { branchId, sessionId, rootThoughtId, coveredIds, coveredRange, ...summary } = parsed;\n\tconst [rangeStart, rangeEnd] = coveredRange;\n\tif (rangeStart === undefined || rangeEnd === undefined) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\tsourcePath,\n\t\t\t'summary coveredRange must contain two values'\n\t\t);\n\t}\n\treturn {\n\t\t...summary,\n\t\tsessionId: asSessionId(sessionId),\n\t\t...(branchId === undefined ? {} : { branchId: parsePersistenceBranchId(branchId, sourcePath) }),\n\t\trootThoughtId: asThoughtId(rootThoughtId),\n\t\tcoveredIds: coveredIds.map(asThoughtId),\n\t\tcoveredRange: [rangeStart, rangeEnd],\n\t};\n}\n"],"names":["parseToolRecommendation","recommendation","sourcePath","undefined","PersistenceCompatibilityError","parseSkillRecommendation","parseStepRecommendation","step","recommended_tools","recommended_skills","fields","tool","skill","parseThoughtData","raw","parsed","v","SequentialThinkingSchema","id","session_id","branch_id","merge_branch_ids","continuation_token","current_step","previous_steps","thought","asThoughtId","asSessionId","parsePersistenceBranchId","asBranchId","asSuspensionToken","parseEdge","EdgeSchema","asEdgeId","parseSummary","SummarySchema","branchId","sessionId","rootThoughtId","coveredIds","coveredRange","summary","rangeStart","rangeEnd"],"mappings":"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"}
@@ -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"}