@earendil-works/pi-agent-core 0.84.3 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +4 -0
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +32 -25
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/harness/agent-harness.d.ts +639 -384
  6. package/dist/harness/agent-harness.d.ts.map +1 -1
  7. package/dist/harness/agent-harness.js +5 -251
  8. package/dist/harness/agent-harness.js.map +1 -1
  9. package/dist/harness/compaction/branch-summarization.d.ts +12 -6
  10. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  11. package/dist/harness/compaction/branch-summarization.js +33 -26
  12. package/dist/harness/compaction/branch-summarization.js.map +1 -1
  13. package/dist/harness/compaction/compaction.d.ts +30 -8
  14. package/dist/harness/compaction/compaction.d.ts.map +1 -1
  15. package/dist/harness/compaction/compaction.js +53 -63
  16. package/dist/harness/compaction/compaction.js.map +1 -1
  17. package/dist/harness/config.d.ts +9 -0
  18. package/dist/harness/config.d.ts.map +1 -0
  19. package/dist/harness/config.js +27 -0
  20. package/dist/harness/config.js.map +1 -0
  21. package/dist/harness/context.d.ts +9 -0
  22. package/dist/harness/context.d.ts.map +1 -0
  23. package/dist/harness/context.js +13 -0
  24. package/dist/harness/context.js.map +1 -0
  25. package/dist/harness/env/nodejs.d.ts +24 -28
  26. package/dist/harness/env/nodejs.d.ts.map +1 -1
  27. package/dist/harness/env/nodejs.js +242 -87
  28. package/dist/harness/env/nodejs.js.map +1 -1
  29. package/dist/harness/events.d.ts +20 -38
  30. package/dist/harness/events.d.ts.map +1 -1
  31. package/dist/harness/events.js +240 -55
  32. package/dist/harness/events.js.map +1 -1
  33. package/dist/harness/execution/assistant.d.ts +42 -0
  34. package/dist/harness/execution/assistant.d.ts.map +1 -0
  35. package/dist/harness/execution/assistant.js +82 -0
  36. package/dist/harness/execution/assistant.js.map +1 -0
  37. package/dist/harness/execution/effect-gate.d.ts +22 -0
  38. package/dist/harness/execution/effect-gate.d.ts.map +1 -0
  39. package/dist/harness/execution/effect-gate.js +49 -0
  40. package/dist/harness/execution/effect-gate.js.map +1 -0
  41. package/dist/harness/execution/tools.d.ts +67 -0
  42. package/dist/harness/execution/tools.d.ts.map +1 -0
  43. package/dist/harness/execution/tools.js +121 -0
  44. package/dist/harness/execution/tools.js.map +1 -0
  45. package/dist/harness/hooks.d.ts +38 -0
  46. package/dist/harness/hooks.d.ts.map +1 -0
  47. package/dist/harness/hooks.js +406 -0
  48. package/dist/harness/hooks.js.map +1 -0
  49. package/dist/harness/messages.d.ts +2 -2
  50. package/dist/harness/messages.d.ts.map +1 -1
  51. package/dist/harness/messages.js.map +1 -1
  52. package/dist/harness/prompt-templates.d.ts +3 -2
  53. package/dist/harness/prompt-templates.d.ts.map +1 -1
  54. package/dist/harness/prompt-templates.js +17 -17
  55. package/dist/harness/prompt-templates.js.map +1 -1
  56. package/dist/harness/result.d.ts +93 -0
  57. package/dist/harness/result.d.ts.map +1 -1
  58. package/dist/harness/result.js +40 -0
  59. package/dist/harness/result.js.map +1 -1
  60. package/dist/harness/runtime/drive/boundary.d.ts +28 -0
  61. package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
  62. package/dist/harness/runtime/drive/boundary.js +170 -0
  63. package/dist/harness/runtime/drive/boundary.js.map +1 -0
  64. package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
  65. package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
  66. package/dist/harness/runtime/drive/checkpoint.js +133 -0
  67. package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
  68. package/dist/harness/runtime/drive/deferred.d.ts +15 -0
  69. package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
  70. package/dist/harness/runtime/drive/deferred.js +179 -0
  71. package/dist/harness/runtime/drive/deferred.js.map +1 -0
  72. package/dist/harness/runtime/drive/generation.d.ts +8 -0
  73. package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
  74. package/dist/harness/runtime/drive/generation.js +205 -0
  75. package/dist/harness/runtime/drive/generation.js.map +1 -0
  76. package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
  77. package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
  78. package/dist/harness/runtime/drive/reconcile.js +140 -0
  79. package/dist/harness/runtime/drive/reconcile.js.map +1 -0
  80. package/dist/harness/runtime/drive/recovery.d.ts +8 -0
  81. package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
  82. package/dist/harness/runtime/drive/recovery.js +85 -0
  83. package/dist/harness/runtime/drive/recovery.js.map +1 -0
  84. package/dist/harness/runtime/drive/response.d.ts +23 -0
  85. package/dist/harness/runtime/drive/response.d.ts.map +1 -0
  86. package/dist/harness/runtime/drive/response.js +394 -0
  87. package/dist/harness/runtime/drive/response.js.map +1 -0
  88. package/dist/harness/runtime/drive/retry.d.ts +4 -0
  89. package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
  90. package/dist/harness/runtime/drive/retry.js +37 -0
  91. package/dist/harness/runtime/drive/retry.js.map +1 -0
  92. package/dist/harness/runtime/drive/structural.d.ts +32 -0
  93. package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
  94. package/dist/harness/runtime/drive/structural.js +929 -0
  95. package/dist/harness/runtime/drive/structural.js.map +1 -0
  96. package/dist/harness/runtime/drive/terminal.d.ts +7 -0
  97. package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
  98. package/dist/harness/runtime/drive/terminal.js +49 -0
  99. package/dist/harness/runtime/drive/terminal.js.map +1 -0
  100. package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
  101. package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
  102. package/dist/harness/runtime/drive/tool-placement.js +244 -0
  103. package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
  104. package/dist/harness/runtime/drive/tools.d.ts +6 -0
  105. package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
  106. package/dist/harness/runtime/drive/tools.js +449 -0
  107. package/dist/harness/runtime/drive/tools.js.map +1 -0
  108. package/dist/harness/runtime/drive.d.ts +6 -0
  109. package/dist/harness/runtime/drive.d.ts.map +1 -0
  110. package/dist/harness/runtime/drive.js +93 -0
  111. package/dist/harness/runtime/drive.js.map +1 -0
  112. package/dist/harness/runtime/harness.d.ts +59 -0
  113. package/dist/harness/runtime/harness.d.ts.map +1 -0
  114. package/dist/harness/runtime/harness.js +311 -0
  115. package/dist/harness/runtime/harness.js.map +1 -0
  116. package/dist/harness/runtime/index.d.ts +2 -0
  117. package/dist/harness/runtime/index.d.ts.map +1 -0
  118. package/dist/harness/runtime/index.js +2 -0
  119. package/dist/harness/runtime/index.js.map +1 -0
  120. package/dist/harness/runtime/lane.d.ts +101 -0
  121. package/dist/harness/runtime/lane.d.ts.map +1 -0
  122. package/dist/harness/runtime/lane.js +1575 -0
  123. package/dist/harness/runtime/lane.js.map +1 -0
  124. package/dist/harness/runtime/progress.d.ts +15 -0
  125. package/dist/harness/runtime/progress.d.ts.map +1 -0
  126. package/dist/harness/runtime/progress.js +66 -0
  127. package/dist/harness/runtime/progress.js.map +1 -0
  128. package/dist/harness/runtime/reducer.d.ts +5 -0
  129. package/dist/harness/runtime/reducer.d.ts.map +1 -0
  130. package/dist/harness/runtime/reducer.js +240 -0
  131. package/dist/harness/runtime/reducer.js.map +1 -0
  132. package/dist/harness/runtime/restore.d.ts +24 -0
  133. package/dist/harness/runtime/restore.d.ts.map +1 -0
  134. package/dist/harness/runtime/restore.js +117 -0
  135. package/dist/harness/runtime/restore.js.map +1 -0
  136. package/dist/harness/runtime/transcript.d.ts +21 -0
  137. package/dist/harness/runtime/transcript.d.ts.map +1 -0
  138. package/dist/harness/runtime/transcript.js +72 -0
  139. package/dist/harness/runtime/transcript.js.map +1 -0
  140. package/dist/harness/runtime/types.d.ts +105 -0
  141. package/dist/harness/runtime/types.d.ts.map +1 -0
  142. package/dist/harness/runtime/types.js +61 -0
  143. package/dist/harness/runtime/types.js.map +1 -0
  144. package/dist/harness/session/commit.d.ts +53 -0
  145. package/dist/harness/session/commit.d.ts.map +1 -0
  146. package/dist/harness/session/commit.js +57 -0
  147. package/dist/harness/session/commit.js.map +1 -0
  148. package/dist/harness/session/context.d.ts +6 -18
  149. package/dist/harness/session/context.d.ts.map +1 -1
  150. package/dist/harness/session/context.js +31 -49
  151. package/dist/harness/session/context.js.map +1 -1
  152. package/dist/harness/session/fork-policy.d.ts +13 -0
  153. package/dist/harness/session/fork-policy.d.ts.map +1 -0
  154. package/dist/harness/session/fork-policy.js +22 -0
  155. package/dist/harness/session/fork-policy.js.map +1 -0
  156. package/dist/harness/session/fork.d.ts +18 -0
  157. package/dist/harness/session/fork.d.ts.map +1 -0
  158. package/dist/harness/session/fork.js +127 -0
  159. package/dist/harness/session/fork.js.map +1 -0
  160. package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
  161. package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
  162. package/dist/harness/session/in-memory-storage-state.js +216 -0
  163. package/dist/harness/session/in-memory-storage-state.js.map +1 -0
  164. package/dist/harness/session/index.d.ts +9 -5
  165. package/dist/harness/session/index.d.ts.map +1 -1
  166. package/dist/harness/session/index.js +7 -4
  167. package/dist/harness/session/index.js.map +1 -1
  168. package/dist/harness/session/jsonl/codec.d.ts +19 -8
  169. package/dist/harness/session/jsonl/codec.d.ts.map +1 -1
  170. package/dist/harness/session/jsonl/codec.js +34 -218
  171. package/dist/harness/session/jsonl/codec.js.map +1 -1
  172. package/dist/harness/session/jsonl/index.d.ts +4 -0
  173. package/dist/harness/session/jsonl/index.d.ts.map +1 -0
  174. package/dist/harness/session/jsonl/index.js +4 -0
  175. package/dist/harness/session/jsonl/index.js.map +1 -0
  176. package/dist/harness/session/jsonl/legacy-v3.d.ts +18 -0
  177. package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
  178. package/dist/harness/session/jsonl/legacy-v3.js +383 -0
  179. package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
  180. package/dist/harness/session/jsonl/repo.d.ts +26 -19
  181. package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
  182. package/dist/harness/session/jsonl/repo.js +266 -156
  183. package/dist/harness/session/jsonl/repo.js.map +1 -1
  184. package/dist/harness/session/jsonl/storage.d.ts +39 -41
  185. package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
  186. package/dist/harness/session/jsonl/storage.js +238 -181
  187. package/dist/harness/session/jsonl/storage.js.map +1 -1
  188. package/dist/harness/session/jsonl/types.d.ts +23 -22
  189. package/dist/harness/session/jsonl/types.d.ts.map +1 -1
  190. package/dist/harness/session/jsonl/types.js +2 -1
  191. package/dist/harness/session/jsonl/types.js.map +1 -1
  192. package/dist/harness/session/memory.d.ts +46 -40
  193. package/dist/harness/session/memory.d.ts.map +1 -1
  194. package/dist/harness/session/memory.js +346 -113
  195. package/dist/harness/session/memory.js.map +1 -1
  196. package/dist/harness/session/mutation-line.d.ts +8 -0
  197. package/dist/harness/session/mutation-line.d.ts.map +1 -0
  198. package/dist/harness/session/mutation-line.js +21 -0
  199. package/dist/harness/session/mutation-line.js.map +1 -0
  200. package/dist/harness/session/session.d.ts +78 -46
  201. package/dist/harness/session/session.d.ts.map +1 -1
  202. package/dist/harness/session/session.js +343 -209
  203. package/dist/harness/session/session.js.map +1 -1
  204. package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
  205. package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
  206. package/dist/harness/session/testing/benchmark/datasets.js +24 -0
  207. package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
  208. package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
  209. package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
  210. package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
  211. package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
  212. package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
  213. package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
  214. package/dist/harness/session/testing/benchmark/storage.js +114 -0
  215. package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
  216. package/dist/harness/session/testing/conformance/session-repo.d.ts +21 -0
  217. package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
  218. package/dist/harness/session/testing/conformance/session-repo.js +590 -0
  219. package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
  220. package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
  221. package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
  222. package/dist/harness/session/testing/conformance/storage.js +600 -0
  223. package/dist/harness/session/testing/conformance/storage.js.map +1 -0
  224. package/dist/harness/session/testing/gating-storage.d.ts +26 -0
  225. package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
  226. package/dist/harness/session/testing/gating-storage.js +100 -0
  227. package/dist/harness/session/testing/gating-storage.js.map +1 -0
  228. package/dist/harness/session/testing/index.d.ts +9 -2
  229. package/dist/harness/session/testing/index.d.ts.map +1 -1
  230. package/dist/harness/session/testing/index.js +8 -1
  231. package/dist/harness/session/testing/index.js.map +1 -1
  232. package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
  233. package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
  234. package/dist/harness/session/testing/instrumented-storage.js +16 -0
  235. package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
  236. package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
  237. package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
  238. package/dist/harness/session/testing/storage-decorator.js +41 -0
  239. package/dist/harness/session/testing/storage-decorator.js.map +1 -0
  240. package/dist/harness/session/testing/types.d.ts +5 -7
  241. package/dist/harness/session/testing/types.d.ts.map +1 -1
  242. package/dist/harness/session/testing/types.js.map +1 -1
  243. package/dist/harness/session/types.d.ts +424 -259
  244. package/dist/harness/session/types.d.ts.map +1 -1
  245. package/dist/harness/session/types.js +7 -8
  246. package/dist/harness/session/types.js.map +1 -1
  247. package/dist/harness/session/values.d.ts +95 -0
  248. package/dist/harness/session/values.d.ts.map +1 -0
  249. package/dist/harness/session/values.js +81 -0
  250. package/dist/harness/session/values.js.map +1 -0
  251. package/dist/harness/skills.d.ts +3 -2
  252. package/dist/harness/skills.d.ts.map +1 -1
  253. package/dist/harness/skills.js +29 -26
  254. package/dist/harness/skills.js.map +1 -1
  255. package/dist/harness/telemetry.d.ts +64 -43
  256. package/dist/harness/telemetry.d.ts.map +1 -1
  257. package/dist/harness/telemetry.js +45 -26
  258. package/dist/harness/telemetry.js.map +1 -1
  259. package/dist/harness/tools/bash.d.ts +4 -4
  260. package/dist/harness/tools/bash.d.ts.map +1 -1
  261. package/dist/harness/tools/bash.js +66 -93
  262. package/dist/harness/tools/bash.js.map +1 -1
  263. package/dist/harness/tools/edit.d.ts.map +1 -1
  264. package/dist/harness/tools/edit.js +10 -10
  265. package/dist/harness/tools/edit.js.map +1 -1
  266. package/dist/harness/tools/file-mutation-queue.d.ts +2 -1
  267. package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
  268. package/dist/harness/tools/file-mutation-queue.js +5 -5
  269. package/dist/harness/tools/file-mutation-queue.js.map +1 -1
  270. package/dist/harness/tools/path-utils.d.ts +3 -2
  271. package/dist/harness/tools/path-utils.d.ts.map +1 -1
  272. package/dist/harness/tools/path-utils.js +5 -5
  273. package/dist/harness/tools/path-utils.js.map +1 -1
  274. package/dist/harness/tools/read.d.ts +2 -1
  275. package/dist/harness/tools/read.d.ts.map +1 -1
  276. package/dist/harness/tools/read.js +4 -6
  277. package/dist/harness/tools/read.js.map +1 -1
  278. package/dist/harness/tools/write.d.ts.map +1 -1
  279. package/dist/harness/tools/write.js +7 -7
  280. package/dist/harness/tools/write.js.map +1 -1
  281. package/dist/harness/types.d.ts +108 -45
  282. package/dist/harness/types.d.ts.map +1 -1
  283. package/dist/harness/types.js.map +1 -1
  284. package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
  285. package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
  286. package/dist/harness/utils/adaptive-publisher.js +79 -0
  287. package/dist/harness/utils/adaptive-publisher.js.map +1 -0
  288. package/dist/harness/utils/output-capture.d.ts +31 -0
  289. package/dist/harness/utils/output-capture.d.ts.map +1 -0
  290. package/dist/harness/utils/output-capture.js +217 -0
  291. package/dist/harness/utils/output-capture.js.map +1 -0
  292. package/dist/harness/utils/shell-output.d.ts +12 -5
  293. package/dist/harness/utils/shell-output.d.ts.map +1 -1
  294. package/dist/harness/utils/shell-output.js +64 -174
  295. package/dist/harness/utils/shell-output.js.map +1 -1
  296. package/dist/harness/utils/truncate.d.ts +1 -0
  297. package/dist/harness/utils/truncate.d.ts.map +1 -1
  298. package/dist/harness/utils/truncate.js +1 -1
  299. package/dist/harness/utils/truncate.js.map +1 -1
  300. package/dist/harness/utils/usage.d.ts +4 -0
  301. package/dist/harness/utils/usage.d.ts.map +1 -0
  302. package/dist/harness/utils/usage.js +33 -0
  303. package/dist/harness/utils/usage.js.map +1 -0
  304. package/dist/index.d.ts +4 -1
  305. package/dist/index.d.ts.map +1 -1
  306. package/dist/index.js +3 -6
  307. package/dist/index.js.map +1 -1
  308. package/dist/proxy.d.ts +2 -0
  309. package/dist/proxy.d.ts.map +1 -1
  310. package/dist/proxy.js +40 -10
  311. package/dist/proxy.js.map +1 -1
  312. package/dist/search/index.d.ts +24 -16
  313. package/dist/search/index.d.ts.map +1 -1
  314. package/dist/search/index.js +1 -1
  315. package/dist/search/index.js.map +1 -1
  316. package/dist/types.d.ts +5 -2
  317. package/dist/types.d.ts.map +1 -1
  318. package/dist/types.js.map +1 -1
  319. package/package.json +25 -4
  320. package/dist/harness/reducer.d.ts +0 -100
  321. package/dist/harness/reducer.d.ts.map +0 -1
  322. package/dist/harness/reducer.js +0 -415
  323. package/dist/harness/reducer.js.map +0 -1
  324. package/dist/harness/session/jsonl/errors.d.ts +0 -9
  325. package/dist/harness/session/jsonl/errors.d.ts.map +0 -1
  326. package/dist/harness/session/jsonl/errors.js +0 -19
  327. package/dist/harness/session/jsonl/errors.js.map +0 -1
  328. package/dist/harness/session/jsonl.d.ts +0 -3
  329. package/dist/harness/session/jsonl.d.ts.map +0 -1
  330. package/dist/harness/session/jsonl.js +0 -2
  331. package/dist/harness/session/jsonl.js.map +0 -1
  332. package/dist/harness/session/state.d.ts +0 -65
  333. package/dist/harness/session/state.d.ts.map +0 -1
  334. package/dist/harness/session/state.js +0 -319
  335. package/dist/harness/session/state.js.map +0 -1
  336. package/dist/harness/session/testing/conformance.d.ts +0 -4
  337. package/dist/harness/session/testing/conformance.d.ts.map +0 -1
  338. package/dist/harness/session/testing/conformance.js +0 -762
  339. package/dist/harness/session/testing/conformance.js.map +0 -1
  340. package/dist/search/scanning.d.ts +0 -29
  341. package/dist/search/scanning.d.ts.map +0 -1
  342. package/dist/search/scanning.js +0 -103
  343. package/dist/search/scanning.js.map +0 -1
@@ -1,141 +1,374 @@
1
- import { uuidv7 } from "@earendil-works/pi-ai";
2
- import { Session } from "./session.js";
3
- import { SessionState } from "./state.js";
4
- import { SessionError, } from "./types.js";
5
- export class InMemorySessionStorage {
6
- metadata;
7
- state = new SessionState();
8
- constructor(metadata) {
9
- this.metadata = structuredClone(metadata);
10
- }
11
- fork(metadata, options) {
12
- const storage = new InMemorySessionStorage(metadata);
13
- for (const mutation of this.state.createForkMutations(options))
14
- storage.state.applyMutation(mutation);
1
+ import { uuidv7 } from "@earendil-works/pi-ai/utils/uuid";
2
+ import { createForkSnapshot, forkSnapshotWrites, } from "./fork.js";
3
+ import { InMemoryStorageState } from "./in-memory-storage-state.js";
4
+ import { StorageBackedSession } from "./session.js";
5
+ export class MemoryStorage {
6
+ now;
7
+ storageState = new InMemoryStorageState();
8
+ commitQueue = Promise.resolve();
9
+ state = "open";
10
+ closePromise;
11
+ constructor(options = {}) {
12
+ this.now = options.now ?? Date.now;
13
+ }
14
+ async commit(writes, _context) {
15
+ if (this.state !== "open")
16
+ throw new Error("MemoryStorage is closed");
17
+ const result = this.commitQueue.then(() => {
18
+ const prepared = this.storageState.prepareCommit(writes, this.now());
19
+ const stats = this.storageState.applyValidated(prepared.writes);
20
+ return { ...prepared.result, stats };
21
+ });
22
+ this.commitQueue = result.then(() => undefined, () => undefined);
23
+ return result;
24
+ }
25
+ getEntries(ids, _context) {
26
+ if (this.state !== "open")
27
+ return Promise.reject(new Error("MemoryStorage is closed"));
28
+ return Promise.resolve(this.storageState.getEntries(ids));
29
+ }
30
+ getValue(address, _context) {
31
+ if (this.state !== "open")
32
+ return Promise.reject(new Error("MemoryStorage is closed"));
33
+ return Promise.resolve(this.storageState.getValue(address));
34
+ }
35
+ scanValues(prefix, _context) {
36
+ if (this.state !== "open")
37
+ return Promise.reject(new Error("MemoryStorage is closed"));
38
+ return Promise.resolve(this.storageState.scanValues(prefix));
39
+ }
40
+ async readList(address, options, _context) {
41
+ if (this.state !== "open")
42
+ throw new Error("MemoryStorage is closed");
43
+ return this.storageState.readList(address, options);
44
+ }
45
+ async scanBranch(query, _context) {
46
+ if (this.state !== "open")
47
+ throw new Error("MemoryStorage is closed");
48
+ return this.storageState.scanBranch(query);
49
+ }
50
+ async scanBranchStructure(query, _context) {
51
+ if (this.state !== "open")
52
+ throw new Error("MemoryStorage is closed");
53
+ return this.storageState.scanBranchStructure(query);
54
+ }
55
+ scanEntries(query, _context) {
56
+ if (this.state !== "open")
57
+ return Promise.reject(new Error("MemoryStorage is closed"));
58
+ return Promise.resolve(this.storageState.scanEntries(query));
59
+ }
60
+ scanUsage(query, _context) {
61
+ if (this.state !== "open")
62
+ return Promise.reject(new Error("MemoryStorage is closed"));
63
+ return Promise.resolve(this.storageState.scanUsage(query));
64
+ }
65
+ getStats(_context) {
66
+ if (this.state !== "open")
67
+ return Promise.reject(new Error("MemoryStorage is closed"));
68
+ return Promise.resolve(this.storageState.getStats());
69
+ }
70
+ /** Capture the state needed to fork at one serialized boundary between commits. */
71
+ captureForkSource(_context) {
72
+ if (this.state !== "open")
73
+ return Promise.reject(new Error("MemoryStorage is closed"));
74
+ const result = this.commitQueue.then(() => this.storageState.snapshotEntriesAndValues());
75
+ this.commitQueue = result.then(() => undefined, () => undefined);
76
+ return result;
77
+ }
78
+ close(_context) {
79
+ if (this.closePromise !== undefined)
80
+ return this.closePromise;
81
+ this.state = "closing";
82
+ this.closePromise = this.commitQueue.then(() => {
83
+ this.state = "closed";
84
+ });
85
+ return this.closePromise;
86
+ }
87
+ static fromSnapshot(options, snapshot) {
88
+ const storage = new MemoryStorage(options);
89
+ const writes = forkSnapshotWrites(snapshot);
90
+ storage.storageState.validateCommitted(writes);
91
+ storage.storageState.applyValidated(writes);
15
92
  return storage;
16
93
  }
17
- async getMetadata() {
18
- return structuredClone(this.metadata);
19
- }
20
- async getLanes() {
21
- return this.state.getLanes();
22
- }
23
- async createLane(lane, at) {
24
- this.state.validateNewLane(lane);
25
- this.state.validateTarget(at);
26
- this.state.applyMutation({ kind: "lane", seq: this.state.nextSequence, lane, leafId: at });
27
- }
28
- async moveLane(lane, to) {
29
- this.state.requireLane(lane);
30
- this.state.validateTarget(to);
31
- this.state.applyMutation({ kind: "lane", seq: this.state.nextSequence, lane, leafId: to });
32
- }
33
- async appendEntry(newEntry, lane) {
34
- const parentId = this.state.requireLane(lane);
35
- this.state.validateUnusedId(newEntry.id);
36
- const entry = {
37
- ...structuredClone(newEntry),
38
- parentId,
39
- seq: this.state.nextSequence,
40
- timestamp: Date.now(),
41
- };
42
- this.state.applyMutation({ kind: "entry", lane, entry });
43
- return structuredClone(entry);
44
- }
45
- async appendRecord(newRecord) {
46
- this.state.requireLane(newRecord.lane);
47
- this.state.validateUnusedId(newRecord.id);
48
- const currentOpenOperationId = this.state.findOpenOperations(newRecord.lane, { limit: 1 })[0]?.id;
49
- if (newRecord.type === "operation_started" && currentOpenOperationId !== undefined) {
50
- throw new SessionError("storage", `Lane ${newRecord.lane} already has an open operation ${currentOpenOperationId}`);
94
+ }
95
+ const MEMORY_STORAGE_VERSION = 1;
96
+ class MemorySessionFacade {
97
+ metadata;
98
+ idGenerator;
99
+ session;
100
+ onClose;
101
+ admitted = new Set();
102
+ closedError = new Error("Session is closed");
103
+ state = "open";
104
+ closePromise;
105
+ constructor(session, onClose) {
106
+ this.session = session;
107
+ this.metadata = session.metadata;
108
+ this.idGenerator = session.idGenerator;
109
+ this.onClose = onClose;
110
+ }
111
+ async beginMutation(context) {
112
+ let resolveFinished;
113
+ const finished = new Promise((resolve) => {
114
+ resolveFinished = resolve;
115
+ });
116
+ this.admitted.add(finished);
117
+ let source;
118
+ try {
119
+ source = await this.admit(() => this.session.beginMutation(context));
120
+ }
121
+ catch (error) {
122
+ this.admitted.delete(finished);
123
+ resolveFinished();
124
+ throw error;
125
+ }
126
+ if (this.state !== "open") {
127
+ await source.end(context);
128
+ this.admitted.delete(finished);
129
+ resolveFinished();
130
+ throw this.closedError;
51
131
  }
52
- const record = {
53
- ...structuredClone(newRecord),
54
- seq: this.state.nextSequence,
55
- timestamp: Date.now(),
132
+ let ended = false;
133
+ return {
134
+ commit: (writes, commitContext) => source.commit(writes, commitContext),
135
+ end: async (endContext) => {
136
+ try {
137
+ await source.end(endContext);
138
+ }
139
+ finally {
140
+ if (!ended) {
141
+ ended = true;
142
+ this.admitted.delete(finished);
143
+ resolveFinished();
144
+ }
145
+ }
146
+ },
147
+ getEntries: (ids, readContext) => source.getEntries(ids, readContext),
148
+ getStats: (readContext) => source.getStats(readContext),
149
+ getValue: (address, readContext) => source.getValue(address, readContext),
150
+ scanValues: (prefix, readContext) => source.scanValues(prefix, readContext),
151
+ readList: (address, options, readContext) => source.readList(address, options, readContext),
152
+ scanBranch: (query, readContext) => source.scanBranch(query, readContext),
56
153
  };
57
- this.state.applyMutation({ kind: "record", record });
58
- return structuredClone(record);
59
154
  }
60
- async getEntry(id) {
61
- const entry = this.state.getEntry(id);
62
- return entry === undefined ? undefined : structuredClone(entry);
155
+ mutate(mutation, context) {
156
+ return this.admit(() => this.session.mutate((mutator, mutationContext) => {
157
+ if (this.state !== "open")
158
+ throw this.closedError;
159
+ return mutation(mutator, mutationContext);
160
+ }, context));
161
+ }
162
+ getEntries(ids, context) {
163
+ return this.admit(() => this.session.getEntries(ids, context));
164
+ }
165
+ getEntry(id, context) {
166
+ return this.admit(() => this.session.getEntry(id, context));
167
+ }
168
+ getValue(address, context) {
169
+ return this.admit(() => this.session.getValue(address, context));
63
170
  }
64
- async findEntries(query = {}) {
65
- return structuredClone(this.state.findEntries(query));
171
+ scanValues(prefix, context) {
172
+ return this.admit(() => this.session.scanValues(prefix, context));
66
173
  }
67
- async findEntriesOnBranch(query) {
68
- return structuredClone(this.state.findEntriesOnBranch(query));
174
+ readList(address, options, context) {
175
+ return this.admit(() => this.session.readList(address, options, context));
69
176
  }
70
- async findRecords(query = {}) {
71
- return structuredClone(this.state.findRecords(query));
177
+ scanBranch(query, context) {
178
+ return this.admit(() => this.session.scanBranch(query, context));
72
179
  }
73
- async findOpenOperations(lane, options) {
74
- return structuredClone(this.state.findOpenOperations(lane, options));
180
+ getStats(context) {
181
+ return this.admit(() => this.session.getStats(context));
75
182
  }
76
- async getLog(options = {}) {
77
- return structuredClone(this.state.getLog(options));
183
+ getName(context) {
184
+ return this.admit(() => this.session.getName(context));
78
185
  }
79
- async getName() {
80
- return this.state.getName();
186
+ getLabel(targetId, context) {
187
+ return this.admit(() => this.session.getLabel(targetId, context));
81
188
  }
82
- async setName(name) {
83
- this.state.applyMutation({ kind: "fact", seq: this.state.nextSequence, fact: "name", name });
189
+ findEntries(query, context) {
190
+ return this.admit(() => this.session.findEntries(query, context));
84
191
  }
85
- async getLabel(id) {
86
- return this.state.getLabel(id);
192
+ findEntry(query, context) {
193
+ return this.admit(() => this.session.findEntry(query, context));
87
194
  }
88
- async setLabel(id, label) {
89
- this.state.validateTarget(id);
90
- this.state.applyMutation({
91
- kind: "fact",
92
- seq: this.state.nextSequence,
93
- fact: "label",
94
- targetId: id,
95
- label,
195
+ async branch(name, context) {
196
+ const branch = await this.admit(() => this.session.branch(name, context));
197
+ return branch === undefined ? undefined : this.wrapBranch(branch);
198
+ }
199
+ async createBranch(name, at, context) {
200
+ return this.wrapBranch(await this.admit(() => this.session.createBranch(name, at, context)));
201
+ }
202
+ setValue(address, next, context) {
203
+ return this.admit(() => this.session.setValue(address, next, context));
204
+ }
205
+ deleteValue(address, context) {
206
+ return this.admit(() => this.session.deleteValue(address, context));
207
+ }
208
+ appendList(address, element, context) {
209
+ return this.admit(() => this.session.appendList(address, element, context));
210
+ }
211
+ deleteList(address, context) {
212
+ return this.admit(() => this.session.deleteList(address, context));
213
+ }
214
+ setName(name, context) {
215
+ return this.admit(() => this.session.setName(name, context));
216
+ }
217
+ setLabel(targetId, label, context) {
218
+ return this.admit(() => this.session.setLabel(targetId, label, context));
219
+ }
220
+ close(_context) {
221
+ if (this.closePromise !== undefined)
222
+ return this.closePromise;
223
+ this.state = "closing";
224
+ this.closePromise = Promise.allSettled([...this.admitted]).then(() => {
225
+ this.state = "closed";
226
+ this.onClose();
96
227
  });
228
+ return this.closePromise;
229
+ }
230
+ wrapBranch(branch) {
231
+ return {
232
+ name: branch.name,
233
+ getTipId: (context) => this.admit(() => branch.getTipId(context)),
234
+ findEntries: (query, context) => this.admit(() => branch.findEntries(query, context)),
235
+ findEntry: (query, context) => this.admit(() => branch.findEntry(query, context)),
236
+ appendMessage: (message, context) => this.admit(() => branch.appendMessage(message, context)),
237
+ appendCustomEntry: (customType, data, context) => this.admit(() => branch.appendCustomEntry(customType, data, context)),
238
+ };
97
239
  }
98
- async getStats() {
99
- return structuredClone(this.state.getStats());
240
+ admit(operation) {
241
+ if (this.state !== "open")
242
+ return Promise.reject(this.closedError);
243
+ let result;
244
+ try {
245
+ result = operation();
246
+ }
247
+ catch (error) {
248
+ result = Promise.reject(error);
249
+ }
250
+ this.admitted.add(result);
251
+ void result.then(() => this.admitted.delete(result), () => this.admitted.delete(result));
252
+ return result;
100
253
  }
101
254
  }
102
- export class InMemorySessionRepo {
255
+ export class MemorySessionRepo {
256
+ now;
103
257
  sessions = new Map();
104
- async create(options = {}) {
105
- const id = options.id ?? uuidv7();
106
- if (this.sessions.has(id))
107
- throw new SessionError("already_exists", `Session already exists: ${id}`);
108
- const storage = new InMemorySessionStorage({
258
+ pendingIds = new Set();
259
+ closed = false;
260
+ closePromise;
261
+ constructor(options = {}) {
262
+ this.now = options.now ?? Date.now;
263
+ }
264
+ async create(options, context) {
265
+ this.assertOpen();
266
+ const createdAt = this.now();
267
+ const id = options.id ?? uuidv7(createdAt);
268
+ this.reserveId(id);
269
+ const metadata = {
109
270
  id,
110
- createdAt: Date.now(),
111
- parentSessionId: options.parentSessionId,
112
- });
113
- this.sessions.set(id, storage);
114
- return new Session(storage);
271
+ createdAt,
272
+ storageVersion: MEMORY_STORAGE_VERSION,
273
+ ...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),
274
+ };
275
+ const storage = new MemoryStorage({ now: this.now });
276
+ const session = new StorageBackedSession(metadata, storage);
277
+ try {
278
+ const record = {
279
+ metadata,
280
+ storage,
281
+ session,
282
+ open: true,
283
+ };
284
+ this.sessions.set(id, record);
285
+ return this.openRecord(record);
286
+ }
287
+ catch (error) {
288
+ await session.close(context);
289
+ throw error;
290
+ }
291
+ finally {
292
+ this.pendingIds.delete(id);
293
+ }
115
294
  }
116
- async open(metadata) {
117
- return new Session(this.requireStorage(metadata.id));
295
+ open(metadata, _context) {
296
+ // Memory sessions are always created at the current storage version, so
297
+ // persistent-backend version gating does not apply here.
298
+ this.assertOpen();
299
+ const record = this.sessions.get(metadata.id);
300
+ if (record === undefined)
301
+ return Promise.reject(new Error(`Unknown session: ${metadata.id}`));
302
+ if (record.open)
303
+ return Promise.reject(new Error(`Session is already open: ${metadata.id}`));
304
+ record.open = true;
305
+ return Promise.resolve(this.openRecord(record));
118
306
  }
119
- async list() {
120
- return Promise.all([...this.sessions.values()].map((storage) => storage.getMetadata()));
307
+ list(_options, _context) {
308
+ this.assertOpen();
309
+ return Promise.resolve([...this.sessions.values()].map(({ metadata }) => metadata));
121
310
  }
122
- async delete(metadata) {
311
+ async delete(metadata, context) {
312
+ this.assertOpen();
313
+ const record = this.sessions.get(metadata.id);
314
+ if (record === undefined)
315
+ throw new Error(`Unknown session: ${metadata.id}`);
316
+ if (record.open)
317
+ throw new Error(`Session is open: ${metadata.id}`);
318
+ await record.session.close(context);
123
319
  this.sessions.delete(metadata.id);
124
320
  }
125
- async fork(source, options = {}) {
126
- const sourceStorage = this.requireStorage(source.id);
127
- const id = options.id ?? uuidv7();
128
- if (this.sessions.has(id))
129
- throw new SessionError("already_exists", `Session already exists: ${id}`);
130
- const storage = sourceStorage.fork({ id, createdAt: Date.now(), parentSessionId: options.parentSessionId ?? source.id }, options);
131
- this.sessions.set(id, storage);
132
- return new Session(storage);
133
- }
134
- requireStorage(id) {
135
- const storage = this.sessions.get(id);
136
- if (!storage)
137
- throw new SessionError("not_found", `Session not found: ${id}`);
138
- return storage;
321
+ async fork(source, options, context) {
322
+ this.assertOpen();
323
+ const sourceRecord = this.sessions.get(source.id);
324
+ if (sourceRecord === undefined)
325
+ throw new Error(`Unknown session: ${source.id}`);
326
+ const createdAt = this.now();
327
+ const id = options.id ?? uuidv7(createdAt);
328
+ this.reserveId(id);
329
+ try {
330
+ const snapshot = createForkSnapshot(await sourceRecord.storage.captureForkSource(context), options);
331
+ const storage = MemoryStorage.fromSnapshot({ now: this.now }, snapshot);
332
+ const metadata = {
333
+ id,
334
+ createdAt,
335
+ storageVersion: MEMORY_STORAGE_VERSION,
336
+ parentSessionId: sourceRecord.metadata.id,
337
+ };
338
+ const session = new StorageBackedSession(metadata, storage);
339
+ const record = {
340
+ metadata,
341
+ storage,
342
+ session,
343
+ open: true,
344
+ };
345
+ this.sessions.set(id, record);
346
+ return this.openRecord(record);
347
+ }
348
+ finally {
349
+ this.pendingIds.delete(id);
350
+ }
351
+ }
352
+ close(context) {
353
+ if (this.closePromise !== undefined)
354
+ return this.closePromise;
355
+ this.closed = true;
356
+ this.closePromise = Promise.all([...this.sessions.values()].map(({ session }) => session.close(context))).then(() => undefined);
357
+ return this.closePromise;
358
+ }
359
+ openRecord(record) {
360
+ return new MemorySessionFacade(record.session, () => {
361
+ record.open = false;
362
+ });
363
+ }
364
+ reserveId(id) {
365
+ if (this.sessions.has(id) || this.pendingIds.has(id))
366
+ throw new Error(`Session already exists: ${id}`);
367
+ this.pendingIds.add(id);
368
+ }
369
+ assertOpen() {
370
+ if (this.closed)
371
+ throw new Error("MemorySessionRepo is closed");
139
372
  }
140
373
  }
141
374
  //# sourceMappingURL=memory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/session/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai\";\nimport { Session } from \"./session.ts\";\nimport { SessionState } from \"./state.ts\";\nimport {\n\ttype BranchBounds,\n\ttype Entry,\n\ttype EntryQuery,\n\ttype ForkOptions,\n\ttype LanePointer,\n\ttype LaneRecord,\n\ttype LogItem,\n\ttype LogOptions,\n\ttype NewRecord,\n\ttype OperationStartedRecord,\n\ttype ProvisionedEntry,\n\ttype RecordQuery,\n\ttype SessionCreateOptions,\n\tSessionError,\n\ttype SessionMetadata,\n\ttype SessionRepo,\n\ttype SessionStats,\n\ttype SessionStorage,\n} from \"./types.ts\";\n\nexport class InMemorySessionStorage implements SessionStorage {\n\tprivate readonly metadata: SessionMetadata;\n\tprivate readonly state = new SessionState();\n\n\tconstructor(metadata: SessionMetadata) {\n\t\tthis.metadata = structuredClone(metadata);\n\t}\n\n\tfork(metadata: SessionMetadata, options: ForkOptions & SessionCreateOptions): InMemorySessionStorage {\n\t\tconst storage = new InMemorySessionStorage(metadata);\n\t\tfor (const mutation of this.state.createForkMutations(options)) storage.state.applyMutation(mutation);\n\t\treturn storage;\n\t}\n\n\tasync getMetadata(): Promise<SessionMetadata> {\n\t\treturn structuredClone(this.metadata);\n\t}\n\n\tasync getLanes(): Promise<LanePointer[]> {\n\t\treturn this.state.getLanes();\n\t}\n\n\tasync createLane(lane: string, at: string | null): Promise<void> {\n\t\tthis.state.validateNewLane(lane);\n\t\tthis.state.validateTarget(at);\n\t\tthis.state.applyMutation({ kind: \"lane\", seq: this.state.nextSequence, lane, leafId: at });\n\t}\n\n\tasync moveLane(lane: string, to: string | null): Promise<void> {\n\t\tthis.state.requireLane(lane);\n\t\tthis.state.validateTarget(to);\n\t\tthis.state.applyMutation({ kind: \"lane\", seq: this.state.nextSequence, lane, leafId: to });\n\t}\n\n\tasync appendEntry<TEntry extends Entry>(newEntry: ProvisionedEntry<TEntry>, lane: string): Promise<TEntry> {\n\t\tconst parentId = this.state.requireLane(lane);\n\t\tthis.state.validateUnusedId(newEntry.id);\n\t\tconst entry = {\n\t\t\t...structuredClone(newEntry),\n\t\t\tparentId,\n\t\t\tseq: this.state.nextSequence,\n\t\t\ttimestamp: Date.now(),\n\t\t} as unknown as TEntry;\n\t\tthis.state.applyMutation({ kind: \"entry\", lane, entry });\n\t\treturn structuredClone(entry);\n\t}\n\n\tasync appendRecord<TRecord extends LaneRecord>(newRecord: NewRecord<TRecord>): Promise<TRecord> {\n\t\tthis.state.requireLane(newRecord.lane);\n\t\tthis.state.validateUnusedId(newRecord.id);\n\t\tconst currentOpenOperationId = this.state.findOpenOperations(newRecord.lane, { limit: 1 })[0]?.id;\n\t\tif (newRecord.type === \"operation_started\" && currentOpenOperationId !== undefined) {\n\t\t\tthrow new SessionError(\n\t\t\t\t\"storage\",\n\t\t\t\t`Lane ${newRecord.lane} already has an open operation ${currentOpenOperationId}`,\n\t\t\t);\n\t\t}\n\t\tconst record = {\n\t\t\t...structuredClone(newRecord),\n\t\t\tseq: this.state.nextSequence,\n\t\t\ttimestamp: Date.now(),\n\t\t} as unknown as TRecord;\n\t\tthis.state.applyMutation({ kind: \"record\", record });\n\t\treturn structuredClone(record);\n\t}\n\n\tasync getEntry(id: string): Promise<Entry | undefined> {\n\t\tconst entry = this.state.getEntry(id);\n\t\treturn entry === undefined ? undefined : structuredClone(entry);\n\t}\n\n\tasync findEntries(query: EntryQuery = {}): Promise<Entry[]> {\n\t\treturn structuredClone(this.state.findEntries(query));\n\t}\n\n\tasync findEntriesOnBranch(query: EntryQuery & BranchBounds & { start: string }): Promise<Entry[]> {\n\t\treturn structuredClone(this.state.findEntriesOnBranch(query));\n\t}\n\n\tasync findRecords<K extends LaneRecord[\"type\"]>(\n\t\tquery: RecordQuery & { type: K },\n\t): Promise<Extract<LaneRecord, { type: K }>[]>;\n\tasync findRecords(query?: RecordQuery): Promise<LaneRecord[]>;\n\tasync findRecords(query: RecordQuery = {}): Promise<LaneRecord[]> {\n\t\treturn structuredClone(this.state.findRecords(query));\n\t}\n\n\tasync findOpenOperations(lane: string, options?: { limit?: number }): Promise<OperationStartedRecord[]> {\n\t\treturn structuredClone(this.state.findOpenOperations(lane, options));\n\t}\n\n\tasync getLog(options: LogOptions = {}): Promise<LogItem[]> {\n\t\treturn structuredClone(this.state.getLog(options));\n\t}\n\n\tasync getName(): Promise<string | undefined> {\n\t\treturn this.state.getName();\n\t}\n\n\tasync setName(name: string | undefined): Promise<void> {\n\t\tthis.state.applyMutation({ kind: \"fact\", seq: this.state.nextSequence, fact: \"name\", name });\n\t}\n\n\tasync getLabel(id: string): Promise<string | undefined> {\n\t\treturn this.state.getLabel(id);\n\t}\n\n\tasync setLabel(id: string, label: string | undefined): Promise<void> {\n\t\tthis.state.validateTarget(id);\n\t\tthis.state.applyMutation({\n\t\t\tkind: \"fact\",\n\t\t\tseq: this.state.nextSequence,\n\t\t\tfact: \"label\",\n\t\t\ttargetId: id,\n\t\t\tlabel,\n\t\t});\n\t}\n\n\tasync getStats(): Promise<SessionStats> {\n\t\treturn structuredClone(this.state.getStats());\n\t}\n}\n\nexport class InMemorySessionRepo implements SessionRepo {\n\tprivate readonly sessions = new Map<string, InMemorySessionStorage>();\n\n\tasync create(options: SessionCreateOptions = {}): Promise<Session> {\n\t\tconst id = options.id ?? uuidv7();\n\t\tif (this.sessions.has(id)) throw new SessionError(\"already_exists\", `Session already exists: ${id}`);\n\t\tconst storage = new InMemorySessionStorage({\n\t\t\tid,\n\t\t\tcreatedAt: Date.now(),\n\t\t\tparentSessionId: options.parentSessionId,\n\t\t});\n\t\tthis.sessions.set(id, storage);\n\t\treturn new Session(storage);\n\t}\n\n\tasync open(metadata: SessionMetadata): Promise<Session> {\n\t\treturn new Session(this.requireStorage(metadata.id));\n\t}\n\n\tasync list(): Promise<SessionMetadata[]> {\n\t\treturn Promise.all([...this.sessions.values()].map((storage) => storage.getMetadata()));\n\t}\n\n\tasync delete(metadata: SessionMetadata): Promise<void> {\n\t\tthis.sessions.delete(metadata.id);\n\t}\n\n\tasync fork(source: SessionMetadata, options: ForkOptions & SessionCreateOptions = {}): Promise<Session> {\n\t\tconst sourceStorage = this.requireStorage(source.id);\n\t\tconst id = options.id ?? uuidv7();\n\t\tif (this.sessions.has(id)) throw new SessionError(\"already_exists\", `Session already exists: ${id}`);\n\t\tconst storage = sourceStorage.fork(\n\t\t\t{ id, createdAt: Date.now(), parentSessionId: options.parentSessionId ?? source.id },\n\t\t\toptions,\n\t\t);\n\t\tthis.sessions.set(id, storage);\n\t\treturn new Session(storage);\n\t}\n\n\tprivate requireStorage(id: string): InMemorySessionStorage {\n\t\tconst storage = this.sessions.get(id);\n\t\tif (!storage) throw new SessionError(\"not_found\", `Session not found: ${id}`);\n\t\treturn storage;\n\t}\n}\n"]}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/session/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { Context } from \"../context.ts\";\nimport {\n\tcreateForkSnapshot,\n\ttype ForkDestinationSnapshot,\n\ttype ForkSourceSnapshot,\n\tforkSnapshotWrites,\n} from \"./fork.ts\";\nimport { InMemoryStorageState } from \"./in-memory-storage-state.ts\";\nimport { StorageBackedSession } from \"./session.ts\";\nimport type {\n\tBranch,\n\tCommitResult,\n\tEntry,\n\tEntryQuery,\n\tEntryScan,\n\tEntryStructure,\n\tForkOptions,\n\tIdGenerator,\n\tSession,\n\tSessionCreateOptions,\n\tSessionMetadata,\n\tSessionMutation,\n\tSessionMutationCallback,\n\tSessionRepo,\n\tSessionStats,\n\tStorage,\n\tStorageBranchScan,\n\tUsageRow,\n\tUsageScan,\n\tWrite,\n} from \"./types.ts\";\nimport type { ListElement, ListReadOptions, StoredValue, Value, ValueList } from \"./values.ts\";\n\nexport interface MemoryStorageOptions {\n\tnow?: () => number;\n}\n\nexport interface MemorySessionRepoOptions {\n\tnow?: () => number;\n}\n\nexport class MemoryStorage implements Storage {\n\tprivate readonly now: () => number;\n\tprivate storageState = new InMemoryStorageState();\n\tprivate commitQueue: Promise<void> = Promise.resolve();\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: MemoryStorageOptions = {}) {\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync commit(writes: Write[], _context: Context): Promise<CommitResult> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\tconst result = this.commitQueue.then(() => {\n\t\t\tconst prepared = this.storageState.prepareCommit(writes, this.now());\n\t\t\tconst stats = this.storageState.applyValidated(prepared.writes);\n\t\t\treturn { ...prepared.result, stats };\n\t\t});\n\t\tthis.commitQueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tgetEntries(ids: string[], _context: Context): Promise<Map<string, Entry>> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getEntries(ids));\n\t}\n\n\tgetValue<T>(address: Value<T>, _context: Context): Promise<StoredValue<T> | undefined> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getValue(address));\n\t}\n\n\tscanValues<T>(prefix: Value<T>, _context: Context): Promise<StoredValue<T>[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanValues(prefix));\n\t}\n\n\tasync readList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\t_context: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.readList(address, options);\n\t}\n\n\tasync scanBranch(query: StorageBranchScan, _context: Context): Promise<Entry[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.scanBranch(query);\n\t}\n\n\tasync scanBranchStructure(query: StorageBranchScan, _context: Context): Promise<EntryStructure[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.scanBranchStructure(query);\n\t}\n\n\tscanEntries(query: EntryScan, _context: Context): Promise<Entry[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanEntries(query));\n\t}\n\n\tscanUsage(query: UsageScan, _context: Context): Promise<UsageRow[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanUsage(query));\n\t}\n\n\tgetStats(_context: Context): Promise<SessionStats> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getStats());\n\t}\n\n\t/** Capture the state needed to fork at one serialized boundary between commits. */\n\tcaptureForkSource(_context: Context): Promise<ForkSourceSnapshot> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\tconst result = this.commitQueue.then(() => this.storageState.snapshotEntriesAndValues());\n\t\tthis.commitQueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = this.commitQueue.then(() => {\n\t\t\tthis.state = \"closed\";\n\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tstatic fromSnapshot(options: MemoryStorageOptions, snapshot: ForkDestinationSnapshot): MemoryStorage {\n\t\tconst storage = new MemoryStorage(options);\n\t\tconst writes = forkSnapshotWrites(snapshot);\n\t\tstorage.storageState.validateCommitted(writes);\n\t\tstorage.storageState.applyValidated(writes);\n\t\treturn storage;\n\t}\n}\n\nconst MEMORY_STORAGE_VERSION = 1;\n\ninterface MemorySessionRecord {\n\tmetadata: SessionMetadata;\n\tstorage: MemoryStorage;\n\tsession: StorageBackedSession;\n\topen: boolean;\n}\n\nclass MemorySessionFacade implements Session {\n\treadonly metadata: SessionMetadata;\n\treadonly idGenerator: IdGenerator;\n\tprivate readonly session: StorageBackedSession;\n\tprivate readonly onClose: () => void;\n\tprivate readonly admitted = new Set<Promise<unknown>>();\n\tprivate readonly closedError = new Error(\"Session is closed\");\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(session: StorageBackedSession, onClose: () => void) {\n\t\tthis.session = session;\n\t\tthis.metadata = session.metadata;\n\t\tthis.idGenerator = session.idGenerator;\n\t\tthis.onClose = onClose;\n\t}\n\n\tasync beginMutation(context: Context): Promise<SessionMutation> {\n\t\tlet resolveFinished!: () => void;\n\t\tconst finished = new Promise<void>((resolve) => {\n\t\t\tresolveFinished = resolve;\n\t\t});\n\t\tthis.admitted.add(finished);\n\t\tlet source: SessionMutation;\n\t\ttry {\n\t\t\tsource = await this.admit(() => this.session.beginMutation(context));\n\t\t} catch (error) {\n\t\t\tthis.admitted.delete(finished);\n\t\t\tresolveFinished();\n\t\t\tthrow error;\n\t\t}\n\t\tif (this.state !== \"open\") {\n\t\t\tawait source.end(context);\n\t\t\tthis.admitted.delete(finished);\n\t\t\tresolveFinished();\n\t\t\tthrow this.closedError;\n\t\t}\n\t\tlet ended = false;\n\t\treturn {\n\t\t\tcommit: (writes, commitContext) => source.commit(writes, commitContext),\n\t\t\tend: async (endContext) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.end(endContext);\n\t\t\t\t} finally {\n\t\t\t\t\tif (!ended) {\n\t\t\t\t\t\tended = true;\n\t\t\t\t\t\tthis.admitted.delete(finished);\n\t\t\t\t\t\tresolveFinished();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tgetEntries: (ids, readContext) => source.getEntries(ids, readContext),\n\t\t\tgetStats: (readContext) => source.getStats(readContext),\n\t\t\tgetValue: (address, readContext) => source.getValue(address, readContext),\n\t\t\tscanValues: (prefix, readContext) => source.scanValues(prefix, readContext),\n\t\t\treadList: (address, options, readContext) => source.readList(address, options, readContext),\n\t\t\tscanBranch: (query, readContext) => source.scanBranch(query, readContext),\n\t\t};\n\t}\n\n\tmutate<T>(mutation: SessionMutationCallback<T>, context: Context): Promise<T> {\n\t\treturn this.admit(() =>\n\t\t\tthis.session.mutate((mutator, mutationContext) => {\n\t\t\t\tif (this.state !== \"open\") throw this.closedError;\n\t\t\t\treturn mutation(mutator, mutationContext);\n\t\t\t}, context),\n\t\t);\n\t}\n\n\tgetEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\treturn this.admit(() => this.session.getEntries(ids, context));\n\t}\n\n\tgetEntry(id: string, context: Context): Promise<Entry | undefined> {\n\t\treturn this.admit(() => this.session.getEntry(id, context));\n\t}\n\n\tgetValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\treturn this.admit(() => this.session.getValue(address, context));\n\t}\n\n\tscanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\treturn this.admit(() => this.session.scanValues(prefix, context));\n\t}\n\n\treadList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\treturn this.admit(() => this.session.readList(address, options, context));\n\t}\n\n\tscanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\treturn this.admit(() => this.session.scanBranch(query, context));\n\t}\n\n\tgetStats(context: Context): Promise<SessionStats> {\n\t\treturn this.admit(() => this.session.getStats(context));\n\t}\n\n\tgetName(context: Context): Promise<string | undefined> {\n\t\treturn this.admit(() => this.session.getName(context));\n\t}\n\n\tgetLabel(targetId: string, context: Context): Promise<string | undefined> {\n\t\treturn this.admit(() => this.session.getLabel(targetId, context));\n\t}\n\n\tfindEntries(query: EntryQuery | undefined, context: Context): Promise<Entry[]> {\n\t\treturn this.admit(() => this.session.findEntries(query, context));\n\t}\n\n\tfindEntry(query: EntryQuery | undefined, context: Context): Promise<Entry | undefined> {\n\t\treturn this.admit(() => this.session.findEntry(query, context));\n\t}\n\n\tasync branch(name: string, context: Context): Promise<Branch | undefined> {\n\t\tconst branch = await this.admit(() => this.session.branch(name, context));\n\t\treturn branch === undefined ? undefined : this.wrapBranch(branch);\n\t}\n\n\tasync createBranch(name: string, at: string | null, context: Context): Promise<Branch> {\n\t\treturn this.wrapBranch(await this.admit(() => this.session.createBranch(name, at, context)));\n\t}\n\n\tsetValue<T>(address: Value<T>, next: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setValue(address, next, context));\n\t}\n\n\tdeleteValue<T>(address: Value<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.deleteValue(address, context));\n\t}\n\n\tappendList<T>(address: ValueList<T>, element: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.appendList(address, element, context));\n\t}\n\n\tdeleteList<T>(address: ValueList<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.deleteList(address, context));\n\t}\n\n\tsetName(name: string | undefined, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setName(name, context));\n\t}\n\n\tsetLabel(targetId: string, label: string | undefined, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setLabel(targetId, label, context));\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = Promise.allSettled([...this.admitted]).then(() => {\n\t\t\tthis.state = \"closed\";\n\t\t\tthis.onClose();\n\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tprivate wrapBranch(branch: Branch): Branch {\n\t\treturn {\n\t\t\tname: branch.name,\n\t\t\tgetTipId: (context) => this.admit(() => branch.getTipId(context)),\n\t\t\tfindEntries: (query, context) => this.admit(() => branch.findEntries(query, context)),\n\t\t\tfindEntry: (query, context) => this.admit(() => branch.findEntry(query, context)),\n\t\t\tappendMessage: (message, context) => this.admit(() => branch.appendMessage(message, context)),\n\t\t\tappendCustomEntry: (customType, data, context) =>\n\t\t\t\tthis.admit(() => branch.appendCustomEntry(customType, data, context)),\n\t\t};\n\t}\n\n\tprivate admit<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this.state !== \"open\") return Promise.reject(this.closedError);\n\t\tlet result: Promise<T>;\n\t\ttry {\n\t\t\tresult = operation();\n\t\t} catch (error) {\n\t\t\tresult = Promise.reject(error);\n\t\t}\n\t\tthis.admitted.add(result);\n\t\tvoid result.then(\n\t\t\t() => this.admitted.delete(result),\n\t\t\t() => this.admitted.delete(result),\n\t\t);\n\t\treturn result;\n\t}\n}\n\nexport class MemorySessionRepo implements SessionRepo {\n\tprivate readonly now: () => number;\n\tprivate readonly sessions = new Map<string, MemorySessionRecord>();\n\tprivate readonly pendingIds = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: MemorySessionRepoOptions = {}) {\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: SessionCreateOptions, context: Context): Promise<Session> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tthis.reserveId(id);\n\t\tconst metadata: SessionMetadata = {\n\t\t\tid,\n\t\t\tcreatedAt,\n\t\t\tstorageVersion: MEMORY_STORAGE_VERSION,\n\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t};\n\t\tconst storage = new MemoryStorage({ now: this.now });\n\t\tconst session = new StorageBackedSession(metadata, storage);\n\t\ttry {\n\t\t\tconst record: MemorySessionRecord = {\n\t\t\t\tmetadata,\n\t\t\t\tstorage,\n\t\t\t\tsession,\n\t\t\t\topen: true,\n\t\t\t};\n\t\t\tthis.sessions.set(id, record);\n\t\t\treturn this.openRecord(record);\n\t\t} catch (error) {\n\t\t\tawait session.close(context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingIds.delete(id);\n\t\t}\n\t}\n\n\topen(metadata: SessionMetadata, _context: Context): Promise<Session> {\n\t\t// Memory sessions are always created at the current storage version, so\n\t\t// persistent-backend version gating does not apply here.\n\t\tthis.assertOpen();\n\t\tconst record = this.sessions.get(metadata.id);\n\t\tif (record === undefined) return Promise.reject(new Error(`Unknown session: ${metadata.id}`));\n\t\tif (record.open) return Promise.reject(new Error(`Session is already open: ${metadata.id}`));\n\t\trecord.open = true;\n\t\treturn Promise.resolve(this.openRecord(record));\n\t}\n\n\tlist(_options: undefined, _context: Context): Promise<SessionMetadata[]> {\n\t\tthis.assertOpen();\n\t\treturn Promise.resolve([...this.sessions.values()].map(({ metadata }) => metadata));\n\t}\n\n\tasync delete(metadata: SessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst record = this.sessions.get(metadata.id);\n\t\tif (record === undefined) throw new Error(`Unknown session: ${metadata.id}`);\n\t\tif (record.open) throw new Error(`Session is open: ${metadata.id}`);\n\t\tawait record.session.close(context);\n\t\tthis.sessions.delete(metadata.id);\n\t}\n\n\tasync fork(source: SessionMetadata, options: ForkOptions, context: Context): Promise<Session> {\n\t\tthis.assertOpen();\n\t\tconst sourceRecord = this.sessions.get(source.id);\n\t\tif (sourceRecord === undefined) throw new Error(`Unknown session: ${source.id}`);\n\t\tconst createdAt = this.now();\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tthis.reserveId(id);\n\n\t\ttry {\n\t\t\tconst snapshot = createForkSnapshot(await sourceRecord.storage.captureForkSource(context), options);\n\t\t\tconst storage = MemoryStorage.fromSnapshot({ now: this.now }, snapshot);\n\t\t\tconst metadata: SessionMetadata = {\n\t\t\t\tid,\n\t\t\t\tcreatedAt,\n\t\t\t\tstorageVersion: MEMORY_STORAGE_VERSION,\n\t\t\t\tparentSessionId: sourceRecord.metadata.id,\n\t\t\t};\n\t\t\tconst session = new StorageBackedSession(metadata, storage);\n\t\t\tconst record: MemorySessionRecord = {\n\t\t\t\tmetadata,\n\t\t\t\tstorage,\n\t\t\t\tsession,\n\t\t\t\topen: true,\n\t\t\t};\n\t\t\tthis.sessions.set(id, record);\n\t\t\treturn this.openRecord(record);\n\t\t} finally {\n\t\t\tthis.pendingIds.delete(id);\n\t\t}\n\t}\n\n\tclose(context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\tthis.closePromise = Promise.all([...this.sessions.values()].map(({ session }) => session.close(context))).then(\n\t\t\t() => undefined,\n\t\t);\n\t\treturn this.closePromise;\n\t}\n\n\tprivate openRecord(record: MemorySessionRecord): Session {\n\t\treturn new MemorySessionFacade(record.session, () => {\n\t\t\trecord.open = false;\n\t\t});\n\t}\n\n\tprivate reserveId(id: string): void {\n\t\tif (this.sessions.has(id) || this.pendingIds.has(id)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingIds.add(id);\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"MemorySessionRepo is closed\");\n\t}\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /** Serializes complete read-modify-write jobs for one Session. */
2
+ export declare class MutationLine {
3
+ private tail;
4
+ private sealedError;
5
+ run<T>(operation: () => T | Promise<T>): Promise<T>;
6
+ seal(error: Error): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=mutation-line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-line.d.ts","sourceRoot":"","sources":["../../../src/harness/session/mutation-line.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,qBAAa,YAAY;IACxB,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,WAAW,CAAoB;IAEvC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWlD;IAED,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhC;CACD","sourcesContent":["/** Serializes complete read-modify-write jobs for one Session. */\nexport class MutationLine {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate sealedError: Error | undefined;\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tif (this.sealedError !== undefined) return Promise.reject(this.sealedError);\n\t\tconst result = this.tail.then(() => {\n\t\t\tif (this.sealedError !== undefined) throw this.sealedError;\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tseal(error: Error): Promise<void> {\n\t\tthis.sealedError ??= error;\n\t\treturn this.tail;\n\t}\n}\n"]}
@@ -0,0 +1,21 @@
1
+ /** Serializes complete read-modify-write jobs for one Session. */
2
+ export class MutationLine {
3
+ tail = Promise.resolve();
4
+ sealedError;
5
+ run(operation) {
6
+ if (this.sealedError !== undefined)
7
+ return Promise.reject(this.sealedError);
8
+ const result = this.tail.then(() => {
9
+ if (this.sealedError !== undefined)
10
+ throw this.sealedError;
11
+ return operation();
12
+ });
13
+ this.tail = result.then(() => undefined, () => undefined);
14
+ return result;
15
+ }
16
+ seal(error) {
17
+ this.sealedError ??= error;
18
+ return this.tail;
19
+ }
20
+ }
21
+ //# sourceMappingURL=mutation-line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-line.js","sourceRoot":"","sources":["../../../src/harness/session/mutation-line.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,OAAO,YAAY;IAChB,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACxC,WAAW,CAAoB;IAEvC,GAAG,CAAI,SAA+B,EAAc;QACnD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,WAAW,CAAC;YAC3D,OAAO,SAAS,EAAE,CAAC;QAAA,CACnB,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CACtB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;IAED,IAAI,CAAC,KAAY,EAAiB;QACjC,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC;IAAA,CACjB;CACD","sourcesContent":["/** Serializes complete read-modify-write jobs for one Session. */\nexport class MutationLine {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate sealedError: Error | undefined;\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tif (this.sealedError !== undefined) return Promise.reject(this.sealedError);\n\t\tconst result = this.tail.then(() => {\n\t\t\tif (this.sealedError !== undefined) throw this.sealedError;\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tseal(error: Error): Promise<void> {\n\t\tthis.sealedError ??= error;\n\t\treturn this.tail;\n\t}\n}\n"]}