@smthrs/engine-store 0.0.0-stage → 1.0.0-rc.4

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 (787) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/LICENSE +21 -0
  3. package/README.md +146 -2
  4. package/dist/cjs/ArtifactGc.d.ts +235 -0
  5. package/dist/cjs/ArtifactGc.d.ts.map +1 -0
  6. package/dist/cjs/ArtifactGc.js +183 -0
  7. package/dist/cjs/ArtifactGc.js.map +7 -0
  8. package/dist/cjs/ArtifactSync.d.ts +164 -0
  9. package/dist/cjs/ArtifactSync.d.ts.map +1 -0
  10. package/dist/cjs/ArtifactSync.js +144 -0
  11. package/dist/cjs/ArtifactSync.js.map +7 -0
  12. package/dist/cjs/CacheSync.d.ts +112 -0
  13. package/dist/cjs/CacheSync.d.ts.map +1 -0
  14. package/dist/cjs/CacheSync.js +64 -0
  15. package/dist/cjs/CacheSync.js.map +7 -0
  16. package/dist/cjs/DeferredClockFold.d.ts +354 -0
  17. package/dist/cjs/DeferredClockFold.d.ts.map +1 -0
  18. package/dist/cjs/DeferredClockFold.js +335 -0
  19. package/dist/cjs/DeferredClockFold.js.map +7 -0
  20. package/dist/cjs/DisasterRecovery.d.ts +431 -0
  21. package/dist/cjs/DisasterRecovery.d.ts.map +1 -0
  22. package/dist/cjs/DisasterRecovery.js +453 -0
  23. package/dist/cjs/DisasterRecovery.js.map +7 -0
  24. package/dist/cjs/DurableEngineState.d.ts +776 -0
  25. package/dist/cjs/DurableEngineState.d.ts.map +1 -0
  26. package/dist/cjs/DurableEngineState.js +1536 -0
  27. package/dist/cjs/DurableEngineState.js.map +7 -0
  28. package/dist/cjs/EngineStore.d.ts +158 -0
  29. package/dist/cjs/EngineStore.d.ts.map +1 -0
  30. package/dist/cjs/EngineStore.js +398 -0
  31. package/dist/cjs/EngineStore.js.map +7 -0
  32. package/dist/cjs/EngineStoreMetrics.d.ts +276 -0
  33. package/dist/cjs/EngineStoreMetrics.d.ts.map +1 -0
  34. package/dist/cjs/EngineStoreMetrics.js +135 -0
  35. package/dist/cjs/EngineStoreMetrics.js.map +7 -0
  36. package/dist/cjs/Errors.d.ts +22 -0
  37. package/dist/cjs/Errors.d.ts.map +1 -0
  38. package/dist/cjs/Errors.js +39 -0
  39. package/dist/cjs/Errors.js.map +7 -0
  40. package/dist/cjs/EventTypes.d.ts +27 -0
  41. package/dist/cjs/EventTypes.d.ts.map +1 -0
  42. package/dist/cjs/EventTypes.js +37 -0
  43. package/dist/cjs/EventTypes.js.map +7 -0
  44. package/dist/cjs/ExecutionFacts.d.ts +59 -0
  45. package/dist/cjs/ExecutionFacts.d.ts.map +1 -0
  46. package/dist/cjs/ExecutionFacts.js +123 -0
  47. package/dist/cjs/ExecutionFacts.js.map +7 -0
  48. package/dist/cjs/ExecutionSnapshot.d.ts +117 -0
  49. package/dist/cjs/ExecutionSnapshot.d.ts.map +1 -0
  50. package/dist/cjs/ExecutionSnapshot.js +111 -0
  51. package/dist/cjs/ExecutionSnapshot.js.map +7 -0
  52. package/dist/cjs/Inconsistency.d.ts +154 -0
  53. package/dist/cjs/Inconsistency.d.ts.map +1 -0
  54. package/dist/cjs/Inconsistency.js +135 -0
  55. package/dist/cjs/Inconsistency.js.map +7 -0
  56. package/dist/cjs/Migrations.d.ts +56 -0
  57. package/dist/cjs/Migrations.d.ts.map +1 -0
  58. package/dist/cjs/Migrations.js +78 -0
  59. package/dist/cjs/Migrations.js.map +7 -0
  60. package/dist/cjs/OwnerIdentity.d.ts +91 -0
  61. package/dist/cjs/OwnerIdentity.d.ts.map +1 -0
  62. package/dist/cjs/OwnerIdentity.js +65 -0
  63. package/dist/cjs/OwnerIdentity.js.map +7 -0
  64. package/dist/cjs/PlanInputStore.d.ts +110 -0
  65. package/dist/cjs/PlanInputStore.d.ts.map +1 -0
  66. package/dist/cjs/PlanInputStore.js +224 -0
  67. package/dist/cjs/PlanInputStore.js.map +7 -0
  68. package/dist/cjs/PlanMergeStore.d.ts +113 -0
  69. package/dist/cjs/PlanMergeStore.d.ts.map +1 -0
  70. package/dist/cjs/PlanMergeStore.js +255 -0
  71. package/dist/cjs/PlanMergeStore.js.map +7 -0
  72. package/dist/cjs/PlanScheduler.d.ts +363 -0
  73. package/dist/cjs/PlanScheduler.d.ts.map +1 -0
  74. package/dist/cjs/PlanScheduler.js +1090 -0
  75. package/dist/cjs/PlanScheduler.js.map +7 -0
  76. package/dist/cjs/Reconciliation.d.ts +175 -0
  77. package/dist/cjs/Reconciliation.d.ts.map +1 -0
  78. package/dist/cjs/Reconciliation.js +119 -0
  79. package/dist/cjs/Reconciliation.js.map +7 -0
  80. package/dist/cjs/ReplayOnly.d.ts +91 -0
  81. package/dist/cjs/ReplayOnly.d.ts.map +1 -0
  82. package/dist/cjs/ReplayOnly.js +52 -0
  83. package/dist/cjs/ReplayOnly.js.map +7 -0
  84. package/dist/cjs/Retention.d.ts +113 -0
  85. package/dist/cjs/Retention.d.ts.map +1 -0
  86. package/dist/cjs/Retention.js +99 -0
  87. package/dist/cjs/Retention.js.map +7 -0
  88. package/dist/cjs/RunCatalogRead.d.ts +17 -0
  89. package/dist/cjs/RunCatalogRead.d.ts.map +1 -0
  90. package/dist/cjs/RunCatalogRead.js +33 -0
  91. package/dist/cjs/RunCatalogRead.js.map +7 -0
  92. package/dist/cjs/RunChangeFeed.d.ts +75 -0
  93. package/dist/cjs/RunChangeFeed.d.ts.map +1 -0
  94. package/dist/cjs/RunChangeFeed.js +96 -0
  95. package/dist/cjs/RunChangeFeed.js.map +7 -0
  96. package/dist/cjs/RunState.d.ts +116 -0
  97. package/dist/cjs/RunState.d.ts.map +1 -0
  98. package/dist/cjs/RunState.js +76 -0
  99. package/dist/cjs/RunState.js.map +7 -0
  100. package/dist/cjs/Selection.d.ts +495 -0
  101. package/dist/cjs/Selection.d.ts.map +1 -0
  102. package/dist/cjs/Selection.js +288 -0
  103. package/dist/cjs/Selection.js.map +7 -0
  104. package/dist/cjs/SelectionStore.d.ts +141 -0
  105. package/dist/cjs/SelectionStore.d.ts.map +1 -0
  106. package/dist/cjs/SelectionStore.js +229 -0
  107. package/dist/cjs/SelectionStore.js.map +7 -0
  108. package/dist/cjs/StepBoundary.d.ts +501 -0
  109. package/dist/cjs/StepBoundary.d.ts.map +1 -0
  110. package/dist/cjs/StepBoundary.js +619 -0
  111. package/dist/cjs/StepBoundary.js.map +7 -0
  112. package/dist/cjs/StepCacheFold.d.ts +148 -0
  113. package/dist/cjs/StepCacheFold.d.ts.map +1 -0
  114. package/dist/cjs/StepCacheFold.js +131 -0
  115. package/dist/cjs/StepCacheFold.js.map +7 -0
  116. package/dist/cjs/StepSandbox.d.ts +78 -0
  117. package/dist/cjs/StepSandbox.d.ts.map +1 -0
  118. package/dist/cjs/StepSandbox.js +75 -0
  119. package/dist/cjs/StepSandbox.js.map +7 -0
  120. package/dist/cjs/WakeBus.d.ts +116 -0
  121. package/dist/cjs/WakeBus.d.ts.map +1 -0
  122. package/dist/cjs/WakeBus.js +89 -0
  123. package/dist/cjs/WakeBus.js.map +7 -0
  124. package/dist/cjs/WorkspaceSandbox.d.ts +619 -0
  125. package/dist/cjs/WorkspaceSandbox.d.ts.map +1 -0
  126. package/dist/cjs/WorkspaceSandbox.js +711 -0
  127. package/dist/cjs/WorkspaceSandbox.js.map +7 -0
  128. package/dist/cjs/index.d.ts +157 -0
  129. package/dist/cjs/index.d.ts.map +1 -0
  130. package/dist/cjs/index.js +95 -0
  131. package/dist/cjs/index.js.map +7 -0
  132. package/dist/cjs/internal/ActionPersistence.d.ts +276 -0
  133. package/dist/cjs/internal/ActionPersistence.d.ts.map +1 -0
  134. package/dist/cjs/internal/ActionPersistence.js +1395 -0
  135. package/dist/cjs/internal/ActionPersistence.js.map +7 -0
  136. package/dist/cjs/internal/ArtifactRoots.d.ts +38 -0
  137. package/dist/cjs/internal/ArtifactRoots.d.ts.map +1 -0
  138. package/dist/cjs/internal/ArtifactRoots.js +89 -0
  139. package/dist/cjs/internal/ArtifactRoots.js.map +7 -0
  140. package/dist/cjs/internal/AttemptAdmission.d.ts +53 -0
  141. package/dist/cjs/internal/AttemptAdmission.d.ts.map +1 -0
  142. package/dist/cjs/internal/AttemptAdmission.js +52 -0
  143. package/dist/cjs/internal/AttemptAdmission.js.map +7 -0
  144. package/dist/cjs/internal/AttemptLifecycle.d.ts +245 -0
  145. package/dist/cjs/internal/AttemptLifecycle.d.ts.map +1 -0
  146. package/dist/cjs/internal/AttemptLifecycle.js +112 -0
  147. package/dist/cjs/internal/AttemptLifecycle.js.map +7 -0
  148. package/dist/cjs/internal/AttemptProbe.d.ts +53 -0
  149. package/dist/cjs/internal/AttemptProbe.d.ts.map +1 -0
  150. package/dist/cjs/internal/AttemptProbe.js +66 -0
  151. package/dist/cjs/internal/AttemptProbe.js.map +7 -0
  152. package/dist/cjs/internal/CacheAdmission.d.ts +79 -0
  153. package/dist/cjs/internal/CacheAdmission.d.ts.map +1 -0
  154. package/dist/cjs/internal/CacheAdmission.js +71 -0
  155. package/dist/cjs/internal/CacheAdmission.js.map +7 -0
  156. package/dist/cjs/internal/CacheAgeHistory.d.ts +27 -0
  157. package/dist/cjs/internal/CacheAgeHistory.d.ts.map +1 -0
  158. package/dist/cjs/internal/CacheAgeHistory.js +61 -0
  159. package/dist/cjs/internal/CacheAgeHistory.js.map +7 -0
  160. package/dist/cjs/internal/CacheAgeVerdicts.d.ts +15 -0
  161. package/dist/cjs/internal/CacheAgeVerdicts.d.ts.map +1 -0
  162. package/dist/cjs/internal/CacheAgeVerdicts.js +73 -0
  163. package/dist/cjs/internal/CacheAgeVerdicts.js.map +7 -0
  164. package/dist/cjs/internal/CacheOutputPolicy.d.ts +24 -0
  165. package/dist/cjs/internal/CacheOutputPolicy.d.ts.map +1 -0
  166. package/dist/cjs/internal/CacheOutputPolicy.js +75 -0
  167. package/dist/cjs/internal/CacheOutputPolicy.js.map +7 -0
  168. package/dist/cjs/internal/CachePublication.d.ts +97 -0
  169. package/dist/cjs/internal/CachePublication.d.ts.map +1 -0
  170. package/dist/cjs/internal/CachePublication.js +80 -0
  171. package/dist/cjs/internal/CachePublication.js.map +7 -0
  172. package/dist/cjs/internal/CallFacts.d.ts +15 -0
  173. package/dist/cjs/internal/CallFacts.d.ts.map +1 -0
  174. package/dist/cjs/internal/CallFacts.js +97 -0
  175. package/dist/cjs/internal/CallFacts.js.map +7 -0
  176. package/dist/cjs/internal/CopiedRecord.d.ts +61 -0
  177. package/dist/cjs/internal/CopiedRecord.d.ts.map +1 -0
  178. package/dist/cjs/internal/CopiedRecord.js +134 -0
  179. package/dist/cjs/internal/CopiedRecord.js.map +7 -0
  180. package/dist/cjs/internal/DeferredPersistence.d.ts +108 -0
  181. package/dist/cjs/internal/DeferredPersistence.d.ts.map +1 -0
  182. package/dist/cjs/internal/DeferredPersistence.js +270 -0
  183. package/dist/cjs/internal/DeferredPersistence.js.map +7 -0
  184. package/dist/cjs/internal/EffectRecords.d.ts +92 -0
  185. package/dist/cjs/internal/EffectRecords.d.ts.map +1 -0
  186. package/dist/cjs/internal/EffectRecords.js +63 -0
  187. package/dist/cjs/internal/EffectRecords.js.map +7 -0
  188. package/dist/cjs/internal/EngineJj.d.ts +30 -0
  189. package/dist/cjs/internal/EngineJj.d.ts.map +1 -0
  190. package/dist/cjs/internal/EngineJj.js +42 -0
  191. package/dist/cjs/internal/EngineJj.js.map +7 -0
  192. package/dist/cjs/internal/EngineStateSchema.d.ts +68 -0
  193. package/dist/cjs/internal/EngineStateSchema.d.ts.map +1 -0
  194. package/dist/cjs/internal/EngineStateSchema.js +58 -0
  195. package/dist/cjs/internal/EngineStateSchema.js.map +7 -0
  196. package/dist/cjs/internal/ExecutionSnapshotRead.d.ts +162 -0
  197. package/dist/cjs/internal/ExecutionSnapshotRead.d.ts.map +1 -0
  198. package/dist/cjs/internal/ExecutionSnapshotRead.js +201 -0
  199. package/dist/cjs/internal/ExecutionSnapshotRead.js.map +7 -0
  200. package/dist/cjs/internal/ExecutionSnapshotRelations.d.ts +39 -0
  201. package/dist/cjs/internal/ExecutionSnapshotRelations.d.ts.map +1 -0
  202. package/dist/cjs/internal/ExecutionSnapshotRelations.js +105 -0
  203. package/dist/cjs/internal/ExecutionSnapshotRelations.js.map +7 -0
  204. package/dist/cjs/internal/ExitEncoding.d.ts +180 -0
  205. package/dist/cjs/internal/ExitEncoding.d.ts.map +1 -0
  206. package/dist/cjs/internal/ExitEncoding.js +236 -0
  207. package/dist/cjs/internal/ExitEncoding.js.map +7 -0
  208. package/dist/cjs/internal/FileBoundarySnapshot.d.ts +14 -0
  209. package/dist/cjs/internal/FileBoundarySnapshot.d.ts.map +1 -0
  210. package/dist/cjs/internal/FileBoundarySnapshot.js +51 -0
  211. package/dist/cjs/internal/FileBoundarySnapshot.js.map +7 -0
  212. package/dist/cjs/internal/FileEnumeration.d.ts +127 -0
  213. package/dist/cjs/internal/FileEnumeration.d.ts.map +1 -0
  214. package/dist/cjs/internal/FileEnumeration.js +194 -0
  215. package/dist/cjs/internal/FileEnumeration.js.map +7 -0
  216. package/dist/cjs/internal/HostReflection.d.ts +80 -0
  217. package/dist/cjs/internal/HostReflection.d.ts.map +1 -0
  218. package/dist/cjs/internal/HostReflection.js +43 -0
  219. package/dist/cjs/internal/HostReflection.js.map +7 -0
  220. package/dist/cjs/internal/JournalRecords.d.ts +325 -0
  221. package/dist/cjs/internal/JournalRecords.d.ts.map +1 -0
  222. package/dist/cjs/internal/JournalRecords.js +122 -0
  223. package/dist/cjs/internal/JournalRecords.js.map +7 -0
  224. package/dist/cjs/internal/NodeJournal.d.ts +157 -0
  225. package/dist/cjs/internal/NodeJournal.d.ts.map +1 -0
  226. package/dist/cjs/internal/NodeJournal.js +192 -0
  227. package/dist/cjs/internal/NodeJournal.js.map +7 -0
  228. package/dist/cjs/internal/Ordering.d.ts +14 -0
  229. package/dist/cjs/internal/Ordering.d.ts.map +1 -0
  230. package/dist/cjs/internal/Ordering.js +25 -0
  231. package/dist/cjs/internal/Ordering.js.map +7 -0
  232. package/dist/cjs/internal/PlanInputs.d.ts +14 -0
  233. package/dist/cjs/internal/PlanInputs.d.ts.map +1 -0
  234. package/dist/cjs/internal/PlanInputs.js +78 -0
  235. package/dist/cjs/internal/PlanInputs.js.map +7 -0
  236. package/dist/cjs/internal/PlanMerges.d.ts +178 -0
  237. package/dist/cjs/internal/PlanMerges.d.ts.map +1 -0
  238. package/dist/cjs/internal/PlanMerges.js +125 -0
  239. package/dist/cjs/internal/PlanMerges.js.map +7 -0
  240. package/dist/cjs/internal/ProvenanceSlot.d.ts +30 -0
  241. package/dist/cjs/internal/ProvenanceSlot.d.ts.map +1 -0
  242. package/dist/cjs/internal/ProvenanceSlot.js +53 -0
  243. package/dist/cjs/internal/ProvenanceSlot.js.map +7 -0
  244. package/dist/cjs/internal/ResultEnvelope.d.ts +88 -0
  245. package/dist/cjs/internal/ResultEnvelope.d.ts.map +1 -0
  246. package/dist/cjs/internal/ResultEnvelope.js +90 -0
  247. package/dist/cjs/internal/ResultEnvelope.js.map +7 -0
  248. package/dist/cjs/internal/RetentionOps.d.ts +414 -0
  249. package/dist/cjs/internal/RetentionOps.d.ts.map +1 -0
  250. package/dist/cjs/internal/RetentionOps.js +354 -0
  251. package/dist/cjs/internal/RetentionOps.js.map +7 -0
  252. package/dist/cjs/internal/RunCatalogOps.d.ts +118 -0
  253. package/dist/cjs/internal/RunCatalogOps.d.ts.map +1 -0
  254. package/dist/cjs/internal/RunCatalogOps.js +85 -0
  255. package/dist/cjs/internal/RunCatalogOps.js.map +7 -0
  256. package/dist/cjs/internal/RunCoordinator.d.ts +78 -0
  257. package/dist/cjs/internal/RunCoordinator.d.ts.map +1 -0
  258. package/dist/cjs/internal/RunCoordinator.js +123 -0
  259. package/dist/cjs/internal/RunCoordinator.js.map +7 -0
  260. package/dist/cjs/internal/RunDriver.d.ts +192 -0
  261. package/dist/cjs/internal/RunDriver.d.ts.map +1 -0
  262. package/dist/cjs/internal/RunDriver.js +1586 -0
  263. package/dist/cjs/internal/RunDriver.js.map +7 -0
  264. package/dist/cjs/internal/RunLifecycle.d.ts +22 -0
  265. package/dist/cjs/internal/RunLifecycle.d.ts.map +1 -0
  266. package/dist/cjs/internal/RunLifecycle.js +63 -0
  267. package/dist/cjs/internal/RunLifecycle.js.map +7 -0
  268. package/dist/cjs/internal/RunListing.d.ts +78 -0
  269. package/dist/cjs/internal/RunListing.d.ts.map +1 -0
  270. package/dist/cjs/internal/RunListing.js +171 -0
  271. package/dist/cjs/internal/RunListing.js.map +7 -0
  272. package/dist/cjs/internal/RunListingError.d.ts +35 -0
  273. package/dist/cjs/internal/RunListingError.d.ts.map +1 -0
  274. package/dist/cjs/internal/RunListingError.js +47 -0
  275. package/dist/cjs/internal/RunListingError.js.map +7 -0
  276. package/dist/cjs/internal/RuntimeGraph.d.ts +73 -0
  277. package/dist/cjs/internal/RuntimeGraph.d.ts.map +1 -0
  278. package/dist/cjs/internal/RuntimeGraph.js +180 -0
  279. package/dist/cjs/internal/RuntimeGraph.js.map +7 -0
  280. package/dist/cjs/internal/SandboxedExecution.d.ts +80 -0
  281. package/dist/cjs/internal/SandboxedExecution.d.ts.map +1 -0
  282. package/dist/cjs/internal/SandboxedExecution.js +104 -0
  283. package/dist/cjs/internal/SandboxedExecution.js.map +7 -0
  284. package/dist/cjs/internal/StateTransaction.d.ts +44 -0
  285. package/dist/cjs/internal/StateTransaction.d.ts.map +1 -0
  286. package/dist/cjs/internal/StateTransaction.js +52 -0
  287. package/dist/cjs/internal/StateTransaction.js.map +7 -0
  288. package/dist/cjs/internal/StepFacts.d.ts +14 -0
  289. package/dist/cjs/internal/StepFacts.d.ts.map +1 -0
  290. package/dist/cjs/internal/StepFacts.js +58 -0
  291. package/dist/cjs/internal/StepFacts.js.map +7 -0
  292. package/dist/cjs/internal/TypedEvents.d.ts +14 -0
  293. package/dist/cjs/internal/TypedEvents.d.ts.map +1 -0
  294. package/dist/cjs/internal/TypedEvents.js +37 -0
  295. package/dist/cjs/internal/TypedEvents.js.map +7 -0
  296. package/dist/cjs/migrations/0001_initial.d.ts +17 -0
  297. package/dist/cjs/migrations/0001_initial.d.ts.map +1 -0
  298. package/dist/cjs/migrations/0001_initial.js +61 -0
  299. package/dist/cjs/migrations/0001_initial.js.map +7 -0
  300. package/dist/cjs/migrations/0002_selection_store.d.ts +15 -0
  301. package/dist/cjs/migrations/0002_selection_store.d.ts.map +1 -0
  302. package/dist/cjs/migrations/0002_selection_store.js +56 -0
  303. package/dist/cjs/migrations/0002_selection_store.js.map +7 -0
  304. package/dist/cjs/migrations/0003_plan_inputs.d.ts +13 -0
  305. package/dist/cjs/migrations/0003_plan_inputs.d.ts.map +1 -0
  306. package/dist/cjs/migrations/0003_plan_inputs.js +90 -0
  307. package/dist/cjs/migrations/0003_plan_inputs.js.map +7 -0
  308. package/dist/cjs/migrations/0004_plan_environment.d.ts +14 -0
  309. package/dist/cjs/migrations/0004_plan_environment.d.ts.map +1 -0
  310. package/dist/cjs/migrations/0004_plan_environment.js +56 -0
  311. package/dist/cjs/migrations/0004_plan_environment.js.map +7 -0
  312. package/dist/cjs/migrations/0005_plan_merges.d.ts +14 -0
  313. package/dist/cjs/migrations/0005_plan_merges.d.ts.map +1 -0
  314. package/dist/cjs/migrations/0005_plan_merges.js +82 -0
  315. package/dist/cjs/migrations/0005_plan_merges.js.map +7 -0
  316. package/dist/cjs/migrations/0006_execution_listing.d.ts +15 -0
  317. package/dist/cjs/migrations/0006_execution_listing.d.ts.map +1 -0
  318. package/dist/cjs/migrations/0006_execution_listing.js +101 -0
  319. package/dist/cjs/migrations/0006_execution_listing.js.map +7 -0
  320. package/dist/cjs/migrations/0007_run_parent_sequence.d.ts +15 -0
  321. package/dist/cjs/migrations/0007_run_parent_sequence.d.ts.map +1 -0
  322. package/dist/cjs/migrations/0007_run_parent_sequence.js +40 -0
  323. package/dist/cjs/migrations/0007_run_parent_sequence.js.map +7 -0
  324. package/dist/cjs/migrations/0008_deferred_consumption.d.ts +16 -0
  325. package/dist/cjs/migrations/0008_deferred_consumption.d.ts.map +1 -0
  326. package/dist/cjs/migrations/0008_deferred_consumption.js +45 -0
  327. package/dist/cjs/migrations/0008_deferred_consumption.js.map +7 -0
  328. package/dist/cjs/migrations/0009_deferred_clock_facts.d.ts +24 -0
  329. package/dist/cjs/migrations/0009_deferred_clock_facts.d.ts.map +1 -0
  330. package/dist/cjs/migrations/0009_deferred_clock_facts.js +141 -0
  331. package/dist/cjs/migrations/0009_deferred_clock_facts.js.map +7 -0
  332. package/dist/cjs/migrations/0010_pending_cancellation.d.ts +15 -0
  333. package/dist/cjs/migrations/0010_pending_cancellation.d.ts.map +1 -0
  334. package/dist/cjs/migrations/0010_pending_cancellation.js +41 -0
  335. package/dist/cjs/migrations/0010_pending_cancellation.js.map +7 -0
  336. package/dist/cjs/package.json +1 -0
  337. package/dist/cjs/test/TestStores.d.ts +89 -0
  338. package/dist/cjs/test/TestStores.d.ts.map +1 -0
  339. package/dist/cjs/test/TestStores.js +98 -0
  340. package/dist/cjs/test/TestStores.js.map +7 -0
  341. package/dist/esm/ArtifactGc.d.ts +235 -0
  342. package/dist/esm/ArtifactGc.d.ts.map +1 -0
  343. package/dist/esm/ArtifactGc.js +268 -0
  344. package/dist/esm/ArtifactGc.js.map +1 -0
  345. package/dist/esm/ArtifactSync.d.ts +164 -0
  346. package/dist/esm/ArtifactSync.d.ts.map +1 -0
  347. package/dist/esm/ArtifactSync.js +176 -0
  348. package/dist/esm/ArtifactSync.js.map +1 -0
  349. package/dist/esm/CacheSync.d.ts +112 -0
  350. package/dist/esm/CacheSync.d.ts.map +1 -0
  351. package/dist/esm/CacheSync.js +94 -0
  352. package/dist/esm/CacheSync.js.map +1 -0
  353. package/dist/esm/DeferredClockFold.d.ts +354 -0
  354. package/dist/esm/DeferredClockFold.d.ts.map +1 -0
  355. package/dist/esm/DeferredClockFold.js +472 -0
  356. package/dist/esm/DeferredClockFold.js.map +1 -0
  357. package/dist/esm/DisasterRecovery.d.ts +431 -0
  358. package/dist/esm/DisasterRecovery.d.ts.map +1 -0
  359. package/dist/esm/DisasterRecovery.js +523 -0
  360. package/dist/esm/DisasterRecovery.js.map +1 -0
  361. package/dist/esm/DurableEngineState.d.ts +776 -0
  362. package/dist/esm/DurableEngineState.d.ts.map +1 -0
  363. package/dist/esm/DurableEngineState.js +1648 -0
  364. package/dist/esm/DurableEngineState.js.map +1 -0
  365. package/dist/esm/EngineStore.d.ts +158 -0
  366. package/dist/esm/EngineStore.d.ts.map +1 -0
  367. package/dist/esm/EngineStore.js +403 -0
  368. package/dist/esm/EngineStore.js.map +1 -0
  369. package/dist/esm/EngineStoreMetrics.d.ts +276 -0
  370. package/dist/esm/EngineStoreMetrics.d.ts.map +1 -0
  371. package/dist/esm/EngineStoreMetrics.js +260 -0
  372. package/dist/esm/EngineStoreMetrics.js.map +1 -0
  373. package/dist/esm/Errors.d.ts +22 -0
  374. package/dist/esm/Errors.d.ts.map +1 -0
  375. package/dist/esm/Errors.js +22 -0
  376. package/dist/esm/Errors.js.map +1 -0
  377. package/dist/esm/EventTypes.d.ts +27 -0
  378. package/dist/esm/EventTypes.d.ts.map +1 -0
  379. package/dist/esm/EventTypes.js +27 -0
  380. package/dist/esm/EventTypes.js.map +1 -0
  381. package/dist/esm/ExecutionFacts.d.ts +59 -0
  382. package/dist/esm/ExecutionFacts.d.ts.map +1 -0
  383. package/dist/esm/ExecutionFacts.js +96 -0
  384. package/dist/esm/ExecutionFacts.js.map +1 -0
  385. package/dist/esm/ExecutionSnapshot.d.ts +117 -0
  386. package/dist/esm/ExecutionSnapshot.d.ts.map +1 -0
  387. package/dist/esm/ExecutionSnapshot.js +95 -0
  388. package/dist/esm/ExecutionSnapshot.js.map +1 -0
  389. package/dist/esm/Inconsistency.d.ts +154 -0
  390. package/dist/esm/Inconsistency.d.ts.map +1 -0
  391. package/dist/esm/Inconsistency.js +133 -0
  392. package/dist/esm/Inconsistency.js.map +1 -0
  393. package/dist/esm/Migrations.d.ts +56 -0
  394. package/dist/esm/Migrations.d.ts.map +1 -0
  395. package/dist/esm/Migrations.js +91 -0
  396. package/dist/esm/Migrations.js.map +1 -0
  397. package/dist/esm/OwnerIdentity.d.ts +91 -0
  398. package/dist/esm/OwnerIdentity.d.ts.map +1 -0
  399. package/dist/esm/OwnerIdentity.js +99 -0
  400. package/dist/esm/OwnerIdentity.js.map +1 -0
  401. package/dist/esm/PlanInputStore.d.ts +110 -0
  402. package/dist/esm/PlanInputStore.d.ts.map +1 -0
  403. package/dist/esm/PlanInputStore.js +207 -0
  404. package/dist/esm/PlanInputStore.js.map +1 -0
  405. package/dist/esm/PlanMergeStore.d.ts +113 -0
  406. package/dist/esm/PlanMergeStore.d.ts.map +1 -0
  407. package/dist/esm/PlanMergeStore.js +244 -0
  408. package/dist/esm/PlanMergeStore.js.map +1 -0
  409. package/dist/esm/PlanScheduler.d.ts +363 -0
  410. package/dist/esm/PlanScheduler.d.ts.map +1 -0
  411. package/dist/esm/PlanScheduler.js +1321 -0
  412. package/dist/esm/PlanScheduler.js.map +1 -0
  413. package/dist/esm/Reconciliation.d.ts +175 -0
  414. package/dist/esm/Reconciliation.d.ts.map +1 -0
  415. package/dist/esm/Reconciliation.js +175 -0
  416. package/dist/esm/Reconciliation.js.map +1 -0
  417. package/dist/esm/ReplayOnly.d.ts +91 -0
  418. package/dist/esm/ReplayOnly.d.ts.map +1 -0
  419. package/dist/esm/ReplayOnly.js +59 -0
  420. package/dist/esm/ReplayOnly.js.map +1 -0
  421. package/dist/esm/Retention.d.ts +113 -0
  422. package/dist/esm/Retention.d.ts.map +1 -0
  423. package/dist/esm/Retention.js +139 -0
  424. package/dist/esm/Retention.js.map +1 -0
  425. package/dist/esm/RunCatalogRead.d.ts +17 -0
  426. package/dist/esm/RunCatalogRead.d.ts.map +1 -0
  427. package/dist/esm/RunCatalogRead.js +17 -0
  428. package/dist/esm/RunCatalogRead.js.map +1 -0
  429. package/dist/esm/RunChangeFeed.d.ts +75 -0
  430. package/dist/esm/RunChangeFeed.d.ts.map +1 -0
  431. package/dist/esm/RunChangeFeed.js +81 -0
  432. package/dist/esm/RunChangeFeed.js.map +1 -0
  433. package/dist/esm/RunState.d.ts +116 -0
  434. package/dist/esm/RunState.d.ts.map +1 -0
  435. package/dist/esm/RunState.js +109 -0
  436. package/dist/esm/RunState.js.map +1 -0
  437. package/dist/esm/Selection.d.ts +495 -0
  438. package/dist/esm/Selection.d.ts.map +1 -0
  439. package/dist/esm/Selection.js +482 -0
  440. package/dist/esm/Selection.js.map +1 -0
  441. package/dist/esm/SelectionStore.d.ts +141 -0
  442. package/dist/esm/SelectionStore.d.ts.map +1 -0
  443. package/dist/esm/SelectionStore.js +215 -0
  444. package/dist/esm/SelectionStore.js.map +1 -0
  445. package/dist/esm/StepBoundary.d.ts +501 -0
  446. package/dist/esm/StepBoundary.d.ts.map +1 -0
  447. package/dist/esm/StepBoundary.js +919 -0
  448. package/dist/esm/StepBoundary.js.map +1 -0
  449. package/dist/esm/StepCacheFold.d.ts +148 -0
  450. package/dist/esm/StepCacheFold.d.ts.map +1 -0
  451. package/dist/esm/StepCacheFold.js +201 -0
  452. package/dist/esm/StepCacheFold.js.map +1 -0
  453. package/dist/esm/StepSandbox.d.ts +78 -0
  454. package/dist/esm/StepSandbox.d.ts.map +1 -0
  455. package/dist/esm/StepSandbox.js +70 -0
  456. package/dist/esm/StepSandbox.js.map +1 -0
  457. package/dist/esm/WakeBus.d.ts +116 -0
  458. package/dist/esm/WakeBus.d.ts.map +1 -0
  459. package/dist/esm/WakeBus.js +121 -0
  460. package/dist/esm/WakeBus.js.map +1 -0
  461. package/dist/esm/WorkspaceSandbox.d.ts +619 -0
  462. package/dist/esm/WorkspaceSandbox.d.ts.map +1 -0
  463. package/dist/esm/WorkspaceSandbox.js +985 -0
  464. package/dist/esm/WorkspaceSandbox.js.map +1 -0
  465. package/dist/esm/index.d.ts +157 -0
  466. package/dist/esm/index.d.ts.map +1 -0
  467. package/dist/esm/index.js +157 -0
  468. package/dist/esm/index.js.map +1 -0
  469. package/dist/esm/internal/ActionPersistence.d.ts +276 -0
  470. package/dist/esm/internal/ActionPersistence.d.ts.map +1 -0
  471. package/dist/esm/internal/ActionPersistence.js +2306 -0
  472. package/dist/esm/internal/ActionPersistence.js.map +1 -0
  473. package/dist/esm/internal/ArtifactRoots.d.ts +38 -0
  474. package/dist/esm/internal/ArtifactRoots.d.ts.map +1 -0
  475. package/dist/esm/internal/ArtifactRoots.js +76 -0
  476. package/dist/esm/internal/ArtifactRoots.js.map +1 -0
  477. package/dist/esm/internal/AttemptAdmission.d.ts +53 -0
  478. package/dist/esm/internal/AttemptAdmission.d.ts.map +1 -0
  479. package/dist/esm/internal/AttemptAdmission.js +52 -0
  480. package/dist/esm/internal/AttemptAdmission.js.map +1 -0
  481. package/dist/esm/internal/AttemptLifecycle.d.ts +245 -0
  482. package/dist/esm/internal/AttemptLifecycle.d.ts.map +1 -0
  483. package/dist/esm/internal/AttemptLifecycle.js +104 -0
  484. package/dist/esm/internal/AttemptLifecycle.js.map +1 -0
  485. package/dist/esm/internal/AttemptProbe.d.ts +53 -0
  486. package/dist/esm/internal/AttemptProbe.d.ts.map +1 -0
  487. package/dist/esm/internal/AttemptProbe.js +83 -0
  488. package/dist/esm/internal/AttemptProbe.js.map +1 -0
  489. package/dist/esm/internal/CacheAdmission.d.ts +79 -0
  490. package/dist/esm/internal/CacheAdmission.d.ts.map +1 -0
  491. package/dist/esm/internal/CacheAdmission.js +72 -0
  492. package/dist/esm/internal/CacheAdmission.js.map +1 -0
  493. package/dist/esm/internal/CacheAgeHistory.d.ts +27 -0
  494. package/dist/esm/internal/CacheAgeHistory.d.ts.map +1 -0
  495. package/dist/esm/internal/CacheAgeHistory.js +49 -0
  496. package/dist/esm/internal/CacheAgeHistory.js.map +1 -0
  497. package/dist/esm/internal/CacheAgeVerdicts.d.ts +15 -0
  498. package/dist/esm/internal/CacheAgeVerdicts.d.ts.map +1 -0
  499. package/dist/esm/internal/CacheAgeVerdicts.js +54 -0
  500. package/dist/esm/internal/CacheAgeVerdicts.js.map +1 -0
  501. package/dist/esm/internal/CacheOutputPolicy.d.ts +24 -0
  502. package/dist/esm/internal/CacheOutputPolicy.d.ts.map +1 -0
  503. package/dist/esm/internal/CacheOutputPolicy.js +73 -0
  504. package/dist/esm/internal/CacheOutputPolicy.js.map +1 -0
  505. package/dist/esm/internal/CachePublication.d.ts +97 -0
  506. package/dist/esm/internal/CachePublication.d.ts.map +1 -0
  507. package/dist/esm/internal/CachePublication.js +116 -0
  508. package/dist/esm/internal/CachePublication.js.map +1 -0
  509. package/dist/esm/internal/CallFacts.d.ts +15 -0
  510. package/dist/esm/internal/CallFacts.d.ts.map +1 -0
  511. package/dist/esm/internal/CallFacts.js +83 -0
  512. package/dist/esm/internal/CallFacts.js.map +1 -0
  513. package/dist/esm/internal/CopiedRecord.d.ts +61 -0
  514. package/dist/esm/internal/CopiedRecord.d.ts.map +1 -0
  515. package/dist/esm/internal/CopiedRecord.js +165 -0
  516. package/dist/esm/internal/CopiedRecord.js.map +1 -0
  517. package/dist/esm/internal/DeferredPersistence.d.ts +108 -0
  518. package/dist/esm/internal/DeferredPersistence.d.ts.map +1 -0
  519. package/dist/esm/internal/DeferredPersistence.js +240 -0
  520. package/dist/esm/internal/DeferredPersistence.js.map +1 -0
  521. package/dist/esm/internal/EffectRecords.d.ts +92 -0
  522. package/dist/esm/internal/EffectRecords.d.ts.map +1 -0
  523. package/dist/esm/internal/EffectRecords.js +94 -0
  524. package/dist/esm/internal/EffectRecords.js.map +1 -0
  525. package/dist/esm/internal/EngineJj.d.ts +30 -0
  526. package/dist/esm/internal/EngineJj.d.ts.map +1 -0
  527. package/dist/esm/internal/EngineJj.js +29 -0
  528. package/dist/esm/internal/EngineJj.js.map +1 -0
  529. package/dist/esm/internal/EngineStateSchema.d.ts +68 -0
  530. package/dist/esm/internal/EngineStateSchema.d.ts.map +1 -0
  531. package/dist/esm/internal/EngineStateSchema.js +53 -0
  532. package/dist/esm/internal/EngineStateSchema.js.map +1 -0
  533. package/dist/esm/internal/ExecutionSnapshotRead.d.ts +162 -0
  534. package/dist/esm/internal/ExecutionSnapshotRead.d.ts.map +1 -0
  535. package/dist/esm/internal/ExecutionSnapshotRead.js +218 -0
  536. package/dist/esm/internal/ExecutionSnapshotRead.js.map +1 -0
  537. package/dist/esm/internal/ExecutionSnapshotRelations.d.ts +39 -0
  538. package/dist/esm/internal/ExecutionSnapshotRelations.d.ts.map +1 -0
  539. package/dist/esm/internal/ExecutionSnapshotRelations.js +81 -0
  540. package/dist/esm/internal/ExecutionSnapshotRelations.js.map +1 -0
  541. package/dist/esm/internal/ExitEncoding.d.ts +180 -0
  542. package/dist/esm/internal/ExitEncoding.d.ts.map +1 -0
  543. package/dist/esm/internal/ExitEncoding.js +361 -0
  544. package/dist/esm/internal/ExitEncoding.js.map +1 -0
  545. package/dist/esm/internal/FileBoundarySnapshot.d.ts +14 -0
  546. package/dist/esm/internal/FileBoundarySnapshot.d.ts.map +1 -0
  547. package/dist/esm/internal/FileBoundarySnapshot.js +29 -0
  548. package/dist/esm/internal/FileBoundarySnapshot.js.map +1 -0
  549. package/dist/esm/internal/FileEnumeration.d.ts +127 -0
  550. package/dist/esm/internal/FileEnumeration.d.ts.map +1 -0
  551. package/dist/esm/internal/FileEnumeration.js +236 -0
  552. package/dist/esm/internal/FileEnumeration.js.map +1 -0
  553. package/dist/esm/internal/HostReflection.d.ts +80 -0
  554. package/dist/esm/internal/HostReflection.d.ts.map +1 -0
  555. package/dist/esm/internal/HostReflection.js +98 -0
  556. package/dist/esm/internal/HostReflection.js.map +1 -0
  557. package/dist/esm/internal/JournalRecords.d.ts +325 -0
  558. package/dist/esm/internal/JournalRecords.d.ts.map +1 -0
  559. package/dist/esm/internal/JournalRecords.js +306 -0
  560. package/dist/esm/internal/JournalRecords.js.map +1 -0
  561. package/dist/esm/internal/NodeJournal.d.ts +157 -0
  562. package/dist/esm/internal/NodeJournal.d.ts.map +1 -0
  563. package/dist/esm/internal/NodeJournal.js +298 -0
  564. package/dist/esm/internal/NodeJournal.js.map +1 -0
  565. package/dist/esm/internal/Ordering.d.ts +14 -0
  566. package/dist/esm/internal/Ordering.d.ts.map +1 -0
  567. package/dist/esm/internal/Ordering.js +14 -0
  568. package/dist/esm/internal/Ordering.js.map +1 -0
  569. package/dist/esm/internal/PlanInputs.d.ts +14 -0
  570. package/dist/esm/internal/PlanInputs.d.ts.map +1 -0
  571. package/dist/esm/internal/PlanInputs.js +57 -0
  572. package/dist/esm/internal/PlanInputs.js.map +1 -0
  573. package/dist/esm/internal/PlanMerges.d.ts +178 -0
  574. package/dist/esm/internal/PlanMerges.d.ts.map +1 -0
  575. package/dist/esm/internal/PlanMerges.js +113 -0
  576. package/dist/esm/internal/PlanMerges.js.map +1 -0
  577. package/dist/esm/internal/ProvenanceSlot.d.ts +30 -0
  578. package/dist/esm/internal/ProvenanceSlot.d.ts.map +1 -0
  579. package/dist/esm/internal/ProvenanceSlot.js +39 -0
  580. package/dist/esm/internal/ProvenanceSlot.js.map +1 -0
  581. package/dist/esm/internal/ResultEnvelope.d.ts +88 -0
  582. package/dist/esm/internal/ResultEnvelope.d.ts.map +1 -0
  583. package/dist/esm/internal/ResultEnvelope.js +83 -0
  584. package/dist/esm/internal/ResultEnvelope.js.map +1 -0
  585. package/dist/esm/internal/RetentionOps.d.ts +414 -0
  586. package/dist/esm/internal/RetentionOps.d.ts.map +1 -0
  587. package/dist/esm/internal/RetentionOps.js +576 -0
  588. package/dist/esm/internal/RetentionOps.js.map +1 -0
  589. package/dist/esm/internal/RunCatalogOps.d.ts +118 -0
  590. package/dist/esm/internal/RunCatalogOps.d.ts.map +1 -0
  591. package/dist/esm/internal/RunCatalogOps.js +120 -0
  592. package/dist/esm/internal/RunCatalogOps.js.map +1 -0
  593. package/dist/esm/internal/RunCoordinator.d.ts +78 -0
  594. package/dist/esm/internal/RunCoordinator.d.ts.map +1 -0
  595. package/dist/esm/internal/RunCoordinator.js +115 -0
  596. package/dist/esm/internal/RunCoordinator.js.map +1 -0
  597. package/dist/esm/internal/RunDriver.d.ts +192 -0
  598. package/dist/esm/internal/RunDriver.d.ts.map +1 -0
  599. package/dist/esm/internal/RunDriver.js +2334 -0
  600. package/dist/esm/internal/RunDriver.js.map +1 -0
  601. package/dist/esm/internal/RunLifecycle.d.ts +22 -0
  602. package/dist/esm/internal/RunLifecycle.d.ts.map +1 -0
  603. package/dist/esm/internal/RunLifecycle.js +49 -0
  604. package/dist/esm/internal/RunLifecycle.js.map +1 -0
  605. package/dist/esm/internal/RunListing.d.ts +78 -0
  606. package/dist/esm/internal/RunListing.d.ts.map +1 -0
  607. package/dist/esm/internal/RunListing.js +146 -0
  608. package/dist/esm/internal/RunListing.js.map +1 -0
  609. package/dist/esm/internal/RunListingError.d.ts +35 -0
  610. package/dist/esm/internal/RunListingError.d.ts.map +1 -0
  611. package/dist/esm/internal/RunListingError.js +27 -0
  612. package/dist/esm/internal/RunListingError.js.map +1 -0
  613. package/dist/esm/internal/RuntimeGraph.d.ts +73 -0
  614. package/dist/esm/internal/RuntimeGraph.d.ts.map +1 -0
  615. package/dist/esm/internal/RuntimeGraph.js +182 -0
  616. package/dist/esm/internal/RuntimeGraph.js.map +1 -0
  617. package/dist/esm/internal/SandboxedExecution.d.ts +80 -0
  618. package/dist/esm/internal/SandboxedExecution.d.ts.map +1 -0
  619. package/dist/esm/internal/SandboxedExecution.js +107 -0
  620. package/dist/esm/internal/SandboxedExecution.js.map +1 -0
  621. package/dist/esm/internal/StateTransaction.d.ts +44 -0
  622. package/dist/esm/internal/StateTransaction.d.ts.map +1 -0
  623. package/dist/esm/internal/StateTransaction.js +54 -0
  624. package/dist/esm/internal/StateTransaction.js.map +1 -0
  625. package/dist/esm/internal/StepFacts.d.ts +14 -0
  626. package/dist/esm/internal/StepFacts.d.ts.map +1 -0
  627. package/dist/esm/internal/StepFacts.js +35 -0
  628. package/dist/esm/internal/StepFacts.js.map +1 -0
  629. package/dist/esm/internal/TypedEvents.d.ts +14 -0
  630. package/dist/esm/internal/TypedEvents.d.ts.map +1 -0
  631. package/dist/esm/internal/TypedEvents.js +14 -0
  632. package/dist/esm/internal/TypedEvents.js.map +1 -0
  633. package/dist/esm/migrations/0001_initial.d.ts +17 -0
  634. package/dist/esm/migrations/0001_initial.d.ts.map +1 -0
  635. package/dist/esm/migrations/0001_initial.js +41 -0
  636. package/dist/esm/migrations/0001_initial.js.map +1 -0
  637. package/dist/esm/migrations/0002_selection_store.d.ts +15 -0
  638. package/dist/esm/migrations/0002_selection_store.d.ts.map +1 -0
  639. package/dist/esm/migrations/0002_selection_store.js +34 -0
  640. package/dist/esm/migrations/0002_selection_store.js.map +1 -0
  641. package/dist/esm/migrations/0003_plan_inputs.d.ts +13 -0
  642. package/dist/esm/migrations/0003_plan_inputs.d.ts.map +1 -0
  643. package/dist/esm/migrations/0003_plan_inputs.js +70 -0
  644. package/dist/esm/migrations/0003_plan_inputs.js.map +1 -0
  645. package/dist/esm/migrations/0004_plan_environment.d.ts +14 -0
  646. package/dist/esm/migrations/0004_plan_environment.d.ts.map +1 -0
  647. package/dist/esm/migrations/0004_plan_environment.js +33 -0
  648. package/dist/esm/migrations/0004_plan_environment.js.map +1 -0
  649. package/dist/esm/migrations/0005_plan_merges.d.ts +14 -0
  650. package/dist/esm/migrations/0005_plan_merges.d.ts.map +1 -0
  651. package/dist/esm/migrations/0005_plan_merges.js +59 -0
  652. package/dist/esm/migrations/0005_plan_merges.js.map +1 -0
  653. package/dist/esm/migrations/0006_execution_listing.d.ts +15 -0
  654. package/dist/esm/migrations/0006_execution_listing.d.ts.map +1 -0
  655. package/dist/esm/migrations/0006_execution_listing.js +81 -0
  656. package/dist/esm/migrations/0006_execution_listing.js.map +1 -0
  657. package/dist/esm/migrations/0007_run_parent_sequence.d.ts +15 -0
  658. package/dist/esm/migrations/0007_run_parent_sequence.d.ts.map +1 -0
  659. package/dist/esm/migrations/0007_run_parent_sequence.js +18 -0
  660. package/dist/esm/migrations/0007_run_parent_sequence.js.map +1 -0
  661. package/dist/esm/migrations/0008_deferred_consumption.d.ts +16 -0
  662. package/dist/esm/migrations/0008_deferred_consumption.d.ts.map +1 -0
  663. package/dist/esm/migrations/0008_deferred_consumption.js +24 -0
  664. package/dist/esm/migrations/0008_deferred_consumption.js.map +1 -0
  665. package/dist/esm/migrations/0009_deferred_clock_facts.d.ts +24 -0
  666. package/dist/esm/migrations/0009_deferred_clock_facts.d.ts.map +1 -0
  667. package/dist/esm/migrations/0009_deferred_clock_facts.js +127 -0
  668. package/dist/esm/migrations/0009_deferred_clock_facts.js.map +1 -0
  669. package/dist/esm/migrations/0010_pending_cancellation.d.ts +15 -0
  670. package/dist/esm/migrations/0010_pending_cancellation.d.ts.map +1 -0
  671. package/dist/esm/migrations/0010_pending_cancellation.js +19 -0
  672. package/dist/esm/migrations/0010_pending_cancellation.js.map +1 -0
  673. package/dist/esm/test/TestStores.d.ts +89 -0
  674. package/dist/esm/test/TestStores.d.ts.map +1 -0
  675. package/dist/esm/test/TestStores.js +103 -0
  676. package/dist/esm/test/TestStores.js.map +1 -0
  677. package/docs/README.md +113 -0
  678. package/docs/api.md +1494 -0
  679. package/docs/concepts/attempts-and-replay.md +149 -0
  680. package/docs/concepts/cache-admission.md +265 -0
  681. package/docs/concepts/call-facts.md +86 -0
  682. package/docs/concepts/durable-waits.md +175 -0
  683. package/docs/concepts/execution-facts.md +90 -0
  684. package/docs/concepts/ownership-and-fencing.md +128 -0
  685. package/docs/concepts/step-boundaries.md +148 -0
  686. package/docs/concepts/workspace-transactions.md +199 -0
  687. package/docs/event-types.md +14 -0
  688. package/docs/guides/back-up-and-restore.md +164 -0
  689. package/docs/guides/collect-unreferenced-artifacts.md +128 -0
  690. package/docs/guides/compose-a-durable-engine.md +146 -0
  691. package/docs/guides/coordinate-two-processes.md +120 -0
  692. package/docs/guides/defer-work-with-selection.md +171 -0
  693. package/docs/guides/delete-old-run-history.md +154 -0
  694. package/docs/guides/drive-a-plan.md +314 -0
  695. package/docs/guides/observe-engine-metrics.md +98 -0
  696. package/docs/guides/observe-executions.md +187 -0
  697. package/docs/guides/reclaim-runs-from-a-dead-host.md +133 -0
  698. package/docs/guides/share-a-cache-across-machines.md +134 -0
  699. package/docs/guides/testing.md +123 -0
  700. package/docs/installation.md +102 -0
  701. package/docs/quickstart.md +215 -0
  702. package/docs/troubleshooting.md +347 -0
  703. package/package.json +438 -3
  704. package/src/ArtifactGc.ts +408 -0
  705. package/src/ArtifactSync.ts +278 -0
  706. package/src/CacheSync.ts +131 -0
  707. package/src/DeferredClockFold.ts +586 -0
  708. package/src/DisasterRecovery.ts +888 -0
  709. package/src/DurableEngineState.ts +2656 -0
  710. package/src/EngineStore.ts +656 -0
  711. package/src/EngineStoreMetrics.ts +331 -0
  712. package/src/Errors.ts +28 -0
  713. package/src/EventTypes.ts +27 -0
  714. package/src/ExecutionFacts.ts +125 -0
  715. package/src/ExecutionSnapshot.ts +186 -0
  716. package/src/Inconsistency.ts +253 -0
  717. package/src/Migrations.ts +95 -0
  718. package/src/OwnerIdentity.ts +125 -0
  719. package/src/PlanInputStore.ts +292 -0
  720. package/src/PlanMergeStore.ts +330 -0
  721. package/src/PlanScheduler.ts +1806 -0
  722. package/src/Reconciliation.ts +224 -0
  723. package/src/ReplayOnly.ts +95 -0
  724. package/src/Retention.ts +214 -0
  725. package/src/RunCatalogRead.ts +27 -0
  726. package/src/RunChangeFeed.ts +125 -0
  727. package/src/RunState.ts +137 -0
  728. package/src/Selection.ts +683 -0
  729. package/src/SelectionStore.ts +353 -0
  730. package/src/StepBoundary.ts +1165 -0
  731. package/src/StepCacheFold.ts +244 -0
  732. package/src/StepSandbox.ts +110 -0
  733. package/src/WakeBus.ts +167 -0
  734. package/src/WorkspaceSandbox.ts +1604 -0
  735. package/src/index.ts +185 -0
  736. package/src/internal/ActionPersistence.ts +2687 -0
  737. package/src/internal/ArtifactRoots.ts +92 -0
  738. package/src/internal/AttemptAdmission.ts +76 -0
  739. package/src/internal/AttemptLifecycle.ts +163 -0
  740. package/src/internal/AttemptProbe.ts +90 -0
  741. package/src/internal/CacheAdmission.ts +133 -0
  742. package/src/internal/CacheAgeHistory.ts +58 -0
  743. package/src/internal/CacheAgeVerdicts.ts +61 -0
  744. package/src/internal/CacheOutputPolicy.ts +82 -0
  745. package/src/internal/CachePublication.ts +153 -0
  746. package/src/internal/CallFacts.ts +87 -0
  747. package/src/internal/CopiedRecord.ts +201 -0
  748. package/src/internal/DeferredPersistence.ts +459 -0
  749. package/src/internal/EffectRecords.ts +136 -0
  750. package/src/internal/EngineJj.ts +30 -0
  751. package/src/internal/EngineStateSchema.ts +92 -0
  752. package/src/internal/ExecutionSnapshotRead.ts +300 -0
  753. package/src/internal/ExecutionSnapshotRelations.ts +121 -0
  754. package/src/internal/ExitEncoding.ts +453 -0
  755. package/src/internal/FileBoundarySnapshot.ts +39 -0
  756. package/src/internal/FileEnumeration.ts +334 -0
  757. package/src/internal/HostReflection.ts +128 -0
  758. package/src/internal/JournalRecords.ts +396 -0
  759. package/src/internal/NodeJournal.ts +340 -0
  760. package/src/internal/Ordering.ts +14 -0
  761. package/src/internal/PlanInputs.ts +62 -0
  762. package/src/internal/PlanMerges.ts +123 -0
  763. package/src/internal/ProvenanceSlot.ts +52 -0
  764. package/src/internal/ResultEnvelope.ts +118 -0
  765. package/src/internal/RetentionOps.ts +865 -0
  766. package/src/internal/RunCatalogOps.ts +174 -0
  767. package/src/internal/RunCoordinator.ts +215 -0
  768. package/src/internal/RunDriver.ts +3154 -0
  769. package/src/internal/RunLifecycle.ts +53 -0
  770. package/src/internal/RunListing.ts +210 -0
  771. package/src/internal/RunListingError.ts +37 -0
  772. package/src/internal/RuntimeGraph.ts +253 -0
  773. package/src/internal/SandboxedExecution.ts +165 -0
  774. package/src/internal/StateTransaction.ts +71 -0
  775. package/src/internal/StepFacts.ts +36 -0
  776. package/src/internal/TypedEvents.ts +29 -0
  777. package/src/migrations/0001_initial.ts +51 -0
  778. package/src/migrations/0002_selection_store.ts +38 -0
  779. package/src/migrations/0003_plan_inputs.ts +75 -0
  780. package/src/migrations/0004_plan_environment.ts +34 -0
  781. package/src/migrations/0005_plan_merges.ts +60 -0
  782. package/src/migrations/0006_execution_listing.ts +86 -0
  783. package/src/migrations/0007_run_parent_sequence.ts +19 -0
  784. package/src/migrations/0008_deferred_consumption.ts +27 -0
  785. package/src/migrations/0009_deferred_clock_facts.ts +163 -0
  786. package/src/migrations/0010_pending_cancellation.ts +20 -0
  787. package/src/test/TestStores.ts +145 -0
@@ -0,0 +1,523 @@
1
+ /**
2
+ * Hot backup, verified restore, and restore-time fencing for the durable
3
+ * flows store.
4
+ *
5
+ * A backup captures the whole SQLite database — journal, run store, step
6
+ * cache, engine state, and the out-of-ladder objects created by
7
+ * `internal/EngineStateSchema.ts` — with `VACUUM INTO`, which reads one
8
+ * consistent snapshot under WAL while writers stay live. The content-addressed
9
+ * artifact blobs are copied beside it, digest-verified, after the database
10
+ * snapshot: results reference artifacts only after publication
11
+ * (`packages/smithers/flows/step-cache/docs/api.md`), so a blob walk taken after the
12
+ * database snapshot is a superset of every digest the snapshot references.
13
+ * A manifest written last records the digests a restore must verify, so a
14
+ * partial backup is detectable by its missing manifest.
15
+ *
16
+ * Restore never lets a pre-backup owner resurrect. The fencing token is the
17
+ * `OwnerId` triple mirrored on `flows_runs` and arbitrated by the journal's
18
+ * `flows_consensus_leases` — Temporal's shard `rangeID` equality check reduced
19
+ * to one SQL predicate (`reference/temporal`
20
+ * `service/history/shard/context_impl.go`, `renewRangeLocked`). Temporal
21
+ * fences a restored shard by bumping the persisted epoch above anything a
22
+ * surviving owner could hold; the equivalent bump for an identity fence is
23
+ * {@link fence}: clear every persisted claim, owner, and consensus lease in
24
+ * one serialized write transaction, so every pre-backup `OwnerId` fails its
25
+ * equality compare-and-swap (`FenceLost`, journal `fence_lost`) and the
26
+ * restored runs are claimable immediately instead of after the heartbeat
27
+ * staleness cutoff.
28
+ *
29
+ * Host access arrives through Effect's `FileSystem` and `SqlClient` tags and
30
+ * hashing through the injected `Crypto` service, so the module carries no
31
+ * platform binding. The SQL dialect is SQLite — a non-SQLite backend fails
32
+ * with the `sql` code rather than pretending to snapshot. Every file is
33
+ * stat-checked before it is buffered for hashing or copying. The configurable
34
+ * ceiling defaults to {@link defaultMaxFileSizeBytes}; an oversized file fails
35
+ * with the typed `io` code instead of reaching the host's allocation limit.
36
+ *
37
+ * @since 0.1.0
38
+ */
39
+ import * as ArtifactBackupLease from "@smthrs/artifacts/ArtifactBackupLease";
40
+ import { Sha256 } from "@smthrs/crypto";
41
+ import { DurableWriter } from "@smthrs/database/DurableWriter";
42
+ import * as Clock from "effect/Clock";
43
+ import * as Effect from "effect/Effect";
44
+ import * as FileSystem from "effect/FileSystem";
45
+ import * as Schema from "effect/Schema";
46
+ import * as SqlClient from "effect/unstable/sql/SqlClient";
47
+ import * as ArtifactRoots from "./internal/ArtifactRoots.js";
48
+ /**
49
+ * The database file name inside a backup directory and a restored store
50
+ * directory.
51
+ *
52
+ * @since 0.1.0
53
+ * @category constants
54
+ */
55
+ export const databaseFileName = "store.sqlite3";
56
+ /**
57
+ * The manifest file name inside a backup directory. It is written last, so
58
+ * its presence marks a complete backup.
59
+ *
60
+ * @since 0.1.0
61
+ * @category constants
62
+ */
63
+ export const manifestFileName = "manifest.json";
64
+ /**
65
+ * The artifact blob directory name inside a backup directory and a restored
66
+ * store directory, laid out with the store's own two-hex-prefix fanout.
67
+ *
68
+ * @since 0.1.0
69
+ * @category constants
70
+ */
71
+ export const objectsDirectoryName = "objects";
72
+ /**
73
+ * The marker file a restore writes into the target directory, recording when
74
+ * the restore happened and which backup it came from.
75
+ *
76
+ * @since 0.1.0
77
+ * @category constants
78
+ */
79
+ export const restoredMarkerFileName = "restored.json";
80
+ /**
81
+ * Default ceiling for one backup file read into memory: 512 MiB.
82
+ *
83
+ * @since 1.0.0
84
+ * @category constants
85
+ */
86
+ export const defaultMaxFileSizeBytes = 512 * 1024 * 1024;
87
+ /**
88
+ * One applied row of the shared `flows_migrations` table, recorded at backup
89
+ * time and re-verified at fence time as the schema version of the snapshot.
90
+ *
91
+ * @since 0.1.0
92
+ * @category schemas
93
+ */
94
+ export const AppliedMigration = Schema.Struct({
95
+ migrationId: Schema.Number,
96
+ name: Schema.String
97
+ });
98
+ /**
99
+ * One captured artifact blob. `sizeBytes` is informational for operators; the
100
+ * digest is the integrity check.
101
+ *
102
+ * @since 0.1.0
103
+ * @category schemas
104
+ */
105
+ export const ArtifactEntry = Schema.Struct({
106
+ digest: Sha256.Digest,
107
+ sizeBytes: Schema.Number
108
+ });
109
+ /**
110
+ * The verification contract of a backup: the database snapshot's digest and
111
+ * schema version, and the digest of every captured artifact blob.
112
+ *
113
+ * @since 0.1.0
114
+ * @category schemas
115
+ */
116
+ export const BackupManifest = Schema.Struct({
117
+ formatVersion: Schema.Literal(1),
118
+ createdAtMs: Schema.Number,
119
+ database: Schema.Struct({
120
+ file: Schema.Literal(databaseFileName),
121
+ sha256: Sha256.Digest,
122
+ sizeBytes: Schema.Number,
123
+ migrations: Schema.Array(AppliedMigration)
124
+ }),
125
+ artifacts: Schema.Array(ArtifactEntry)
126
+ });
127
+ /** JSON text carrying a decoded backup manifest. */
128
+ const ManifestFromJsonString = Schema.fromJsonString(BackupManifest);
129
+ /**
130
+ * Stable failure codes surfaced by backup, verify, restore, and fence.
131
+ * `invalid_options` reports a public option that cannot be admitted safely.
132
+ *
133
+ * @since 0.1.0
134
+ * @category errors
135
+ */
136
+ export const DisasterRecoveryErrorCode = Schema.Literals([
137
+ "invalid_options",
138
+ "not_empty",
139
+ "invalid_manifest",
140
+ "missing_file",
141
+ "digest_mismatch",
142
+ "artifact_corruption",
143
+ "snapshot_incomplete",
144
+ "schema_mismatch",
145
+ "io",
146
+ "sql"
147
+ ]);
148
+ /**
149
+ * A normalized backup or restore failure. The identity string equals this
150
+ * module's package path, per the house rule that a new identity is the
151
+ * defining module path.
152
+ *
153
+ * @since 0.1.0
154
+ * @category errors
155
+ */
156
+ export class DisasterRecoveryError extends Schema.TaggedError()("@smthrs/engine-store/DisasterRecoveryError", {
157
+ code: DisasterRecoveryErrorCode,
158
+ method: Schema.String,
159
+ message: Schema.String,
160
+ cause: Schema.Unknown
161
+ }) {
162
+ }
163
+ const error = (method, code, message, cause) => new DisasterRecoveryError({
164
+ code,
165
+ method,
166
+ message: `${code}: DisasterRecovery.${method}: ${message}`,
167
+ cause
168
+ });
169
+ /**
170
+ * One mapper per failure family, shared across every call site so the
171
+ * vocabulary stays uniform.
172
+ */
173
+ const ioFailure = (method, subject) => (cause) => error(method, "io", `the host filesystem refused ${subject}`, cause);
174
+ const sqlFailure = (method, subject) => (cause) => error(method, "sql", `the database refused ${subject}`, cause);
175
+ /** Hashes bytes with the injected crypto service; a broken host is a defect. */
176
+ const measure = (bytes) => Schema.decodeUnknownEffect(Sha256)(bytes).pipe(Effect.orDie);
177
+ /** Resolves and validates the shared whole-file buffering ceiling. */
178
+ const fileSizeLimit = (method, options) => {
179
+ const limit = options.maxFileSizeBytes;
180
+ if (limit === undefined)
181
+ return defaultMaxFileSizeBytes;
182
+ if (Number.isSafeInteger(limit) && limit >= 0)
183
+ return limit;
184
+ return error(method, "invalid_options", `maxFileSizeBytes must be a finite non-negative safe integer; received ${String(limit)}`, limit);
185
+ };
186
+ /**
187
+ * Refuses an oversized file before a whole-file read allocates its buffer.
188
+ * Every caller admits `limit` through `fileSizeLimit`, so `BigInt` cannot
189
+ * reject it.
190
+ */
191
+ const checkFileSize = (fs, method, path, limit) => Effect.gen(function* () {
192
+ const info = yield* fs.stat(path).pipe(Effect.mapError(ioFailure(method, `stating ${path}`)));
193
+ if (info.size <= BigInt(limit))
194
+ return;
195
+ const message = `${path} is ${info.size} bytes, which exceeds the ${limit}-byte file limit`;
196
+ return yield* Effect.fail(error(method, "io", message, new RangeError(message)));
197
+ });
198
+ /**
199
+ * Admits a target directory that does not exist yet — created recursively —
200
+ * or exists empty. Anything else is refused rather than merged over.
201
+ */
202
+ const ensureEmptyDirectory = (fs, method, directory) => Effect.gen(function* () {
203
+ const present = yield* fs.exists(directory).pipe(Effect.mapError(ioFailure(method, `probing ${directory}`)));
204
+ if (!present) {
205
+ return yield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.mapError(ioFailure(method, `creating ${directory}`)));
206
+ }
207
+ const entries = yield* fs.readDirectory(directory).pipe(Effect.mapError(ioFailure(method, `listing ${directory}`)));
208
+ if (entries.length > 0) {
209
+ return yield* Effect.fail(error(method, "not_empty", `${directory} already holds ${entries.length} entries`, directory));
210
+ }
211
+ });
212
+ /**
213
+ * A relative blob path in the store's fanout layout: a two-hex directory
214
+ * holding a 64-hex digest that begins with it. Anything else under the
215
+ * objects directory — a scratch `.tmp-*` file, the fanout directory itself —
216
+ * is not part of the store's address space.
217
+ */
218
+ const blobEntry = (entry) => {
219
+ const match = entry.match(/^([0-9a-f]{2})[/\\]([0-9a-f]{64})$/);
220
+ if (match === null || !match[2].startsWith(match[1]))
221
+ return undefined;
222
+ return match[2];
223
+ };
224
+ const blobPath = (directory, digest) => `${directory}/${digest.slice(0, 2)}/${digest}`;
225
+ /** The applied rows of the shared migrations table, in ladder order. */
226
+ const appliedMigrations = (sql, method) => sql `
227
+ SELECT migration_id, name FROM flows_migrations ORDER BY migration_id ASC
228
+ `.withoutTransform.pipe(Effect.mapError(sqlFailure(method, "reading flows_migrations")), Effect.map((rows) => rows.map((row) => ({ migrationId: Number(row.migration_id), name: row.name }))));
229
+ /** Reads every artifact root from the frozen database, never the live one. */
230
+ const inspectSnapshot = (sql) => Effect.gen(function* () {
231
+ const migrations = yield* appliedMigrations(sql, "backup");
232
+ const cacheRows = yield* sql `
233
+ SELECT meta_json FROM flows_step_cache
234
+ `.withoutTransform.pipe(Effect.mapError(sqlFailure("backup", "reading artifact roots from snapshot step cache")));
235
+ const attemptRows = yield* sql `
236
+ SELECT checkpoint_json, meta_json FROM flows_attempts
237
+ `.withoutTransform.pipe(Effect.mapError(sqlFailure("backup", "reading artifact roots from snapshot attempts")));
238
+ const artifactRoots = new Set();
239
+ const decodeFailure = (cause) => error("backup", "snapshot_incomplete", cause.message, cause.cause);
240
+ for (const row of cacheRows) {
241
+ for (const digest of yield* ArtifactRoots.rootDigests("flows_step_cache", row.meta_json).pipe(Effect.mapError(decodeFailure)))
242
+ artifactRoots.add(digest);
243
+ }
244
+ for (const row of attemptRows) {
245
+ for (const digest of yield* ArtifactRoots.rootDigests("flows_attempts", row.meta_json).pipe(Effect.mapError(decodeFailure)))
246
+ artifactRoots.add(digest);
247
+ for (const digest of yield* ArtifactRoots.checkpointDigests(row.checkpoint_json).pipe(Effect.mapError(decodeFailure)))
248
+ artifactRoots.add(digest);
249
+ }
250
+ return { migrations, artifactRoots };
251
+ });
252
+ /** Reads and decodes the manifest a backup directory must carry. */
253
+ const readManifest = (fs, method, backupDirectory, maxFileSizeBytes) => Effect.gen(function* () {
254
+ const path = `${backupDirectory}/${manifestFileName}`;
255
+ const present = yield* fs.exists(path).pipe(Effect.mapError(ioFailure(method, `probing ${path}`)));
256
+ if (!present) {
257
+ return yield* Effect.fail(error(method, "missing_file", `${path} does not exist — the backup is incomplete or not a backup`, path));
258
+ }
259
+ yield* checkFileSize(fs, method, path, maxFileSizeBytes);
260
+ const text = yield* fs.readFileString(path).pipe(Effect.mapError(ioFailure(method, `reading ${path}`)));
261
+ return yield* Schema.decodeUnknownEffect(ManifestFromJsonString)(text).pipe(Effect.mapError((cause) => error(method, "invalid_manifest", `${path} does not decode as a backup manifest`, cause)));
262
+ });
263
+ /** Reads a backup file and refuses bytes that no longer hash to the manifest. */
264
+ const checkedFile = (fs, method, path, expected, maxFileSizeBytes) => Effect.gen(function* () {
265
+ const present = yield* fs.exists(path).pipe(Effect.mapError(ioFailure(method, `probing ${path}`)));
266
+ if (!present) {
267
+ return yield* Effect.fail(error(method, "missing_file", `${path} does not exist`, path));
268
+ }
269
+ yield* checkFileSize(fs, method, path, maxFileSizeBytes);
270
+ const bytes = yield* fs.readFile(path).pipe(Effect.mapError(ioFailure(method, `reading ${path}`)));
271
+ const measured = yield* measure(bytes);
272
+ if (measured !== expected) {
273
+ return yield* Effect.fail(error(method, "digest_mismatch", `${path} hashes to ${measured}, the manifest records ${expected}`, path));
274
+ }
275
+ return bytes;
276
+ });
277
+ /**
278
+ * Captures a hot backup of the live store into an empty directory.
279
+ *
280
+ * The database is snapshotted first with `VACUUM INTO` — a read transaction
281
+ * under WAL, so live writers are never blocked and the copy is one consistent
282
+ * point in time. The artifact walk runs after it, so every digest the
283
+ * snapshot references is captured (publication precedes reference). Blobs are
284
+ * digest-verified as they are copied; a blob whose bytes no longer hash to
285
+ * its address fails the backup loudly rather than capturing corruption. The
286
+ * manifest is encoded and admitted under the same file-size ceiling before it
287
+ * is written last, so a successful backup remains readable with its own
288
+ * options.
289
+ *
290
+ * With an `objectsDirectory`, the whole capture holds the artifact backup
291
+ * lease, so concurrent sweep deletion cannot remove a referenced blob
292
+ * mid-copy. Without one, no lease is taken; the frozen-root verification
293
+ * still fails the backup loudly when the snapshot references any blob, so an
294
+ * unfenced capture can never report success while missing artifact bytes.
295
+ *
296
+ * @since 0.1.0
297
+ * @category operations
298
+ */
299
+ export const backup = (options) => Effect.gen(function* () {
300
+ const limit = fileSizeLimit("backup", options);
301
+ if (typeof limit !== "number")
302
+ return yield* Effect.fail(limit);
303
+ const maxFileSizeBytes = limit;
304
+ const sql = yield* Effect.service(SqlClient.SqlClient);
305
+ const fs = yield* FileSystem.FileSystem;
306
+ const createdAtMs = yield* Clock.currentTimeMillis.pipe(Effect.map(Math.floor));
307
+ yield* ensureEmptyDirectory(fs, "backup", options.directory);
308
+ const capture = Effect.gen(function* () {
309
+ const databasePath = `${options.directory}/${databaseFileName}`;
310
+ yield* sql `VACUUM INTO ${databasePath}`.pipe(Effect.mapError(sqlFailure("backup", `snapshotting the database into ${databasePath}`)));
311
+ const snapshot = yield* Effect.flatMap(Effect.service(SqlClient.SqlClient), inspectSnapshot).pipe(Effect.provide(options.snapshotDatabaseLayer(databasePath)));
312
+ // Opening the frozen file may normalize SQLite journal metadata, so its
313
+ // manifest digest is measured only after the inspection connection closes.
314
+ yield* checkFileSize(fs, "backup", databasePath, maxFileSizeBytes);
315
+ const databaseBytes = yield* fs.readFile(databasePath).pipe(Effect.mapError(ioFailure("backup", `reading ${databasePath} back`)));
316
+ const sha256 = yield* measure(databaseBytes);
317
+ const artifacts = [];
318
+ const captured = new Set();
319
+ if (options.objectsDirectory !== undefined) {
320
+ const objectsDirectory = options.objectsDirectory;
321
+ const entries = yield* fs.readDirectory(objectsDirectory, { recursive: true }).pipe(Effect.mapError(ioFailure("backup", `listing ${objectsDirectory}`)));
322
+ for (const entry of [...entries].sort()) {
323
+ const digest = blobEntry(entry);
324
+ if (digest === undefined)
325
+ continue;
326
+ const source = blobPath(objectsDirectory, digest);
327
+ yield* checkFileSize(fs, "backup", source, maxFileSizeBytes);
328
+ const bytes = yield* fs.readFile(source).pipe(Effect.mapError(ioFailure("backup", `reading ${source}`)));
329
+ const measured = yield* measure(bytes);
330
+ if (measured !== digest) {
331
+ return yield* Effect.fail(error("backup", "artifact_corruption", `${source} hashes to ${measured}; repair the store before backing it up`, source));
332
+ }
333
+ const target = blobPath(`${options.directory}/${objectsDirectoryName}`, digest);
334
+ yield* fs.makeDirectory(`${options.directory}/${objectsDirectoryName}/${digest.slice(0, 2)}`, {
335
+ recursive: true
336
+ }).pipe(Effect.mapError(ioFailure("backup", `creating the objects directory for ${digest}`)));
337
+ yield* fs.writeFile(target, bytes).pipe(Effect.mapError(ioFailure("backup", `writing ${target}`)));
338
+ artifacts.push({ digest: measured, sizeBytes: bytes.length });
339
+ captured.add(measured);
340
+ }
341
+ }
342
+ const missing = [...snapshot.artifactRoots].filter((digest) => !captured.has(digest)).sort();
343
+ if (missing.length > 0) {
344
+ return yield* Effect.fail(error("backup", "snapshot_incomplete", `the frozen database references ${missing.length} artifact blobs absent from the backup`, { missing }));
345
+ }
346
+ const manifest = {
347
+ formatVersion: 1,
348
+ createdAtMs,
349
+ database: {
350
+ file: databaseFileName,
351
+ sha256,
352
+ sizeBytes: databaseBytes.length,
353
+ migrations: snapshot.migrations
354
+ },
355
+ artifacts
356
+ };
357
+ const manifestPath = `${options.directory}/${manifestFileName}`;
358
+ const manifestBytes = new TextEncoder().encode(`${JSON.stringify(manifest, null, 2)}\n`);
359
+ if (manifestBytes.byteLength > maxFileSizeBytes) {
360
+ const message = `${manifestPath} is ${manifestBytes.byteLength} bytes, which exceeds the ${maxFileSizeBytes}-byte file limit`;
361
+ return yield* Effect.fail(error("backup", "io", message, new RangeError(message)));
362
+ }
363
+ yield* fs.writeFile(manifestPath, manifestBytes).pipe(Effect.mapError(ioFailure("backup", `writing ${manifestFileName}`)));
364
+ return manifest;
365
+ });
366
+ // The directory was empty when the capture began, so everything in it is
367
+ // this capture's: the snapshot, any SQLite sidecar the inspection
368
+ // connection left, and the copied blobs. A failed capture removes them and
369
+ // leaves the directory reusable for a retry. Cleanup is best effort; the
370
+ // original failure is the one reported.
371
+ const discardPartial = fs.readDirectory(options.directory).pipe(Effect.flatMap((entries) => Effect.forEach(entries, (entry) => fs.remove(`${options.directory}/${entry}`, { recursive: true, force: true }), { discard: true })), Effect.ignore);
372
+ return yield* (options.objectsDirectory === undefined
373
+ ? capture
374
+ : ArtifactBackupLease.withLease(fs, options.objectsDirectory, capture, ioFailure("backup", `coordinating artifact backup in ${options.objectsDirectory}`))).pipe(Effect.onError(() => discardPartial));
375
+ }).pipe(Effect.withSpan("DisasterRecovery.backup"));
376
+ /**
377
+ * Verifies a backup directory against its manifest without restoring it:
378
+ * the manifest decodes, the database snapshot hashes to its recorded digest,
379
+ * and every listed artifact blob is present and hashes to its address.
380
+ *
381
+ * @since 0.1.0
382
+ * @category operations
383
+ */
384
+ export const verify = Effect.fn("DisasterRecovery.verify")(function* (backupDirectory, options = {}) {
385
+ const limit = fileSizeLimit("verify", options);
386
+ if (typeof limit !== "number")
387
+ return yield* Effect.fail(limit);
388
+ const maxFileSizeBytes = limit;
389
+ const fs = yield* FileSystem.FileSystem;
390
+ const manifest = yield* readManifest(fs, "verify", backupDirectory, maxFileSizeBytes);
391
+ yield* checkedFile(fs, "verify", `${backupDirectory}/${manifest.database.file}`, manifest.database.sha256, maxFileSizeBytes);
392
+ for (const entry of manifest.artifacts) {
393
+ yield* checkedFile(fs, "verify", blobPath(`${backupDirectory}/${objectsDirectoryName}`, entry.digest), entry.digest, maxFileSizeBytes);
394
+ }
395
+ return manifest;
396
+ });
397
+ /**
398
+ * Restores a verified backup into an empty target directory.
399
+ *
400
+ * Every byte is re-verified against the manifest as it is copied, so a backup
401
+ * that rotted in storage is refused rather than restored. The target holds
402
+ * the database file, the objects directory, and a `restored.json` marker; it
403
+ * is a fresh store directory to compose `NodeDatabase.layer` and
404
+ * `ArtifactStore.layerFileSystem` over. The database is restored with the
405
+ * pre-backup owner fences still in place — run {@link fence} against it
406
+ * before any engine adopts it.
407
+ *
408
+ * @since 0.1.0
409
+ * @category operations
410
+ */
411
+ export const restore = Effect.fn("DisasterRecovery.restore")(function* (options) {
412
+ const limit = fileSizeLimit("restore", options);
413
+ if (typeof limit !== "number")
414
+ return yield* Effect.fail(limit);
415
+ const maxFileSizeBytes = limit;
416
+ const fs = yield* FileSystem.FileSystem;
417
+ const manifest = yield* readManifest(fs, "restore", options.backupDirectory, maxFileSizeBytes);
418
+ yield* ensureEmptyDirectory(fs, "restore", options.targetDirectory);
419
+ const databaseBytes = yield* checkedFile(fs, "restore", `${options.backupDirectory}/${manifest.database.file}`, manifest.database.sha256, maxFileSizeBytes);
420
+ const databaseFile = `${options.targetDirectory}/${databaseFileName}`;
421
+ yield* fs.writeFile(databaseFile, databaseBytes).pipe(Effect.mapError(ioFailure("restore", `writing ${databaseFile}`)));
422
+ const objectsDirectory = `${options.targetDirectory}/${objectsDirectoryName}`;
423
+ for (const entry of manifest.artifacts) {
424
+ const bytes = yield* checkedFile(fs, "restore", blobPath(`${options.backupDirectory}/${objectsDirectoryName}`, entry.digest), entry.digest, maxFileSizeBytes);
425
+ yield* fs.makeDirectory(`${objectsDirectory}/${entry.digest.slice(0, 2)}`, { recursive: true }).pipe(Effect.mapError(ioFailure("restore", `creating the objects directory for ${entry.digest}`)));
426
+ yield* fs.writeFile(blobPath(objectsDirectory, entry.digest), bytes).pipe(Effect.mapError(ioFailure("restore", `writing the blob for ${entry.digest}`)));
427
+ }
428
+ const restoredAtMs = yield* Clock.currentTimeMillis.pipe(Effect.map(Math.floor));
429
+ const marker = {
430
+ formatVersion: 1,
431
+ restoredAtMs,
432
+ backupCreatedAtMs: manifest.createdAtMs,
433
+ databaseSha256: manifest.database.sha256
434
+ };
435
+ yield* fs.writeFileString(`${options.targetDirectory}/${restoredMarkerFileName}`, `${JSON.stringify(marker, null, 2)}\n`).pipe(Effect.mapError(ioFailure("restore", `writing ${restoredMarkerFileName}`)));
436
+ return { databaseFile, objectsDirectory, manifest };
437
+ });
438
+ /**
439
+ * Bumps the restored store's fencing epoch so pre-backup owners are fenced
440
+ * out.
441
+ *
442
+ * The store's fence is `OwnerId` equality, so the epoch bump is fence
443
+ * invalidation: in one serialized write transaction every pending claim is
444
+ * cleared, every run that was `running` at backup time is suspended with its
445
+ * owner and heartbeat cleared, and every consensus lease is deleted. A
446
+ * surviving pre-backup owner then fails every fenced operation against the
447
+ * restored store — `heartbeat` and `transitionOwned` report `FenceLost`,
448
+ * fenced journal appends fail `fence_lost` — exactly as a stale Temporal owner
449
+ * fails its `rangeID` compare-and-swap. The suspended runs are claimable
450
+ * immediately, without waiting out the heartbeat staleness cutoff and without
451
+ * liveness evidence.
452
+ *
453
+ * Every migration recorded in the manifest must remain applied with the same
454
+ * ID and namespaced name. Forward additions within any installed block are
455
+ * compatible, including engine-store `3006` below an existing plan `4003`;
456
+ * the current database layer applies them on open. A missing or renamed
457
+ * historical entry fails `schema_mismatch` before ownership is cleared.
458
+ *
459
+ * In-flight attempt rows are deliberately untouched: attempt writes are
460
+ * fenced on the run row's ownership, and the resuming engine adopts or
461
+ * retries them under its own fresh owner.
462
+ *
463
+ * @since 0.1.0
464
+ * @category operations
465
+ */
466
+ export const fence = Effect.fn("DisasterRecovery.fence")(function* (manifest) {
467
+ const sql = yield* Effect.service(SqlClient.SqlClient);
468
+ const writer = yield* DurableWriter;
469
+ const applied = yield* appliedMigrations(sql, "fence");
470
+ const expected = manifest.database.migrations;
471
+ const key = (migration) => `${migration.migrationId}:${migration.name}`;
472
+ // IDs identify migrations within their reserved blocks. Compare historical
473
+ // identities independently so additions in lower blocks cannot shift them.
474
+ const appliedById = new Map(applied.map((migration) => [migration.migrationId, migration.name]));
475
+ if (expected.some((migration) => appliedById.get(migration.migrationId) !== migration.name)) {
476
+ return yield* Effect.fail(error("fence", "schema_mismatch", `the restored database applied [${applied.map(key).join(", ")}] but the manifest records [${expected.map(key).join(", ")}]`, { applied, expected }));
477
+ }
478
+ return yield* writer.write(Effect.gen(function* () {
479
+ const claims = yield* sql `
480
+ UPDATE flows_runs
481
+ SET
482
+ claim_host_id = NULL,
483
+ claim_pid = NULL,
484
+ claim_nonce = NULL,
485
+ claimed_at_ms = NULL
486
+ WHERE claim_host_id IS NOT NULL
487
+ RETURNING run_id
488
+ `.withoutTransform;
489
+ const running = yield* sql `
490
+ UPDATE flows_runs
491
+ SET
492
+ status = 'suspended',
493
+ owner_host_id = NULL,
494
+ owner_pid = NULL,
495
+ owner_nonce = NULL,
496
+ heartbeat_at_ms = NULL,
497
+ waiting_reason = 'released',
498
+ waiting_wake_at_ms = NULL,
499
+ waiting_token = NULL
500
+ WHERE status = 'running'
501
+ RETURNING run_id
502
+ `.withoutTransform;
503
+ yield* sql `DELETE FROM flows_consensus_leases`.withoutTransform;
504
+ return { clearedClaims: claims.length, suspendedRuns: running.length };
505
+ })).pipe(Effect.mapError(sqlFailure("fence", "invalidating the persisted fences")));
506
+ });
507
+ /**
508
+ * Restores a backup and immediately fences the restored database.
509
+ *
510
+ * This is the one-shot operator API for disaster recovery. The database
511
+ * driver itself still arrives through a caller-supplied Layer so this module
512
+ * remains host-neutral and browser-bundleable; the bundled Node script passes
513
+ * `NodeDatabase.layer` for the restored file.
514
+ *
515
+ * @since 0.1.0
516
+ * @category operations
517
+ */
518
+ export const restoreAndFence = (options) => Effect.gen(function* () {
519
+ const restored = yield* restore(options);
520
+ const summary = yield* fence(restored.manifest).pipe(Effect.provide(options.databaseLayer(restored.databaseFile)));
521
+ return { ...restored, fence: summary };
522
+ });
523
+ //# sourceMappingURL=DisasterRecovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DisasterRecovery.js","sourceRoot":"","sources":["../../src/DisasterRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hot backup, verified restore, and restore-time fencing for the durable\n * flows store.\n *\n * A backup captures the whole SQLite database — journal, run store, step\n * cache, engine state, and the out-of-ladder objects created by\n * `internal/EngineStateSchema.ts` — with `VACUUM INTO`, which reads one\n * consistent snapshot under WAL while writers stay live. The content-addressed\n * artifact blobs are copied beside it, digest-verified, after the database\n * snapshot: results reference artifacts only after publication\n * (`packages/smithers/flows/step-cache/docs/api.md`), so a blob walk taken after the\n * database snapshot is a superset of every digest the snapshot references.\n * A manifest written last records the digests a restore must verify, so a\n * partial backup is detectable by its missing manifest.\n *\n * Restore never lets a pre-backup owner resurrect. The fencing token is the\n * `OwnerId` triple mirrored on `flows_runs` and arbitrated by the journal's\n * `flows_consensus_leases` — Temporal's shard `rangeID` equality check reduced\n * to one SQL predicate (`reference/temporal`\n * `service/history/shard/context_impl.go`, `renewRangeLocked`). Temporal\n * fences a restored shard by bumping the persisted epoch above anything a\n * surviving owner could hold; the equivalent bump for an identity fence is\n * {@link fence}: clear every persisted claim, owner, and consensus lease in\n * one serialized write transaction, so every pre-backup `OwnerId` fails its\n * equality compare-and-swap (`FenceLost`, journal `fence_lost`) and the\n * restored runs are claimable immediately instead of after the heartbeat\n * staleness cutoff.\n *\n * Host access arrives through Effect's `FileSystem` and `SqlClient` tags and\n * hashing through the injected `Crypto` service, so the module carries no\n * platform binding. The SQL dialect is SQLite — a non-SQLite backend fails\n * with the `sql` code rather than pretending to snapshot. Every file is\n * stat-checked before it is buffered for hashing or copying. The configurable\n * ceiling defaults to {@link defaultMaxFileSizeBytes}; an oversized file fails\n * with the typed `io` code instead of reaching the host's allocation limit.\n *\n * @since 0.1.0\n */\n\nimport * as ArtifactBackupLease from \"@smthrs/artifacts/ArtifactBackupLease\"\nimport { Sha256 } from \"@smthrs/crypto\"\nimport { DurableWriter } from \"@smthrs/database/DurableWriter\"\nimport * as Clock from \"effect/Clock\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Effect from \"effect/Effect\"\nimport * as FileSystem from \"effect/FileSystem\"\nimport type * as Layer from \"effect/Layer\"\nimport * as Schema from \"effect/Schema\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\nimport * as ArtifactRoots from \"./internal/ArtifactRoots.ts\"\n\n/**\n * The database file name inside a backup directory and a restored store\n * directory.\n *\n * @since 0.1.0\n * @category constants\n */\nexport const databaseFileName = \"store.sqlite3\"\n\n/**\n * The manifest file name inside a backup directory. It is written last, so\n * its presence marks a complete backup.\n *\n * @since 0.1.0\n * @category constants\n */\nexport const manifestFileName = \"manifest.json\"\n\n/**\n * The artifact blob directory name inside a backup directory and a restored\n * store directory, laid out with the store's own two-hex-prefix fanout.\n *\n * @since 0.1.0\n * @category constants\n */\nexport const objectsDirectoryName = \"objects\"\n\n/**\n * The marker file a restore writes into the target directory, recording when\n * the restore happened and which backup it came from.\n *\n * @since 0.1.0\n * @category constants\n */\nexport const restoredMarkerFileName = \"restored.json\"\n\n/**\n * Default ceiling for one backup file read into memory: 512 MiB.\n *\n * @since 1.0.0\n * @category constants\n */\nexport const defaultMaxFileSizeBytes = 512 * 1024 * 1024\n\n/**\n * One applied row of the shared `flows_migrations` table, recorded at backup\n * time and re-verified at fence time as the schema version of the snapshot.\n *\n * @since 0.1.0\n * @category schemas\n */\nexport const AppliedMigration = Schema.Struct({\n migrationId: Schema.Number,\n name: Schema.String\n})\n\n/**\n * One applied row of the shared `flows_migrations` table.\n *\n * @since 0.1.0\n * @category models\n */\nexport type AppliedMigration = typeof AppliedMigration.Type\n\n/**\n * One captured artifact blob. `sizeBytes` is informational for operators; the\n * digest is the integrity check.\n *\n * @since 0.1.0\n * @category schemas\n */\nexport const ArtifactEntry = Schema.Struct({\n digest: Sha256.Digest,\n sizeBytes: Schema.Number\n})\n\n/**\n * One captured artifact blob.\n *\n * @since 0.1.0\n * @category models\n */\nexport type ArtifactEntry = typeof ArtifactEntry.Type\n\n/**\n * The verification contract of a backup: the database snapshot's digest and\n * schema version, and the digest of every captured artifact blob.\n *\n * @since 0.1.0\n * @category schemas\n */\nexport const BackupManifest = Schema.Struct({\n formatVersion: Schema.Literal(1),\n createdAtMs: Schema.Number,\n database: Schema.Struct({\n file: Schema.Literal(databaseFileName),\n sha256: Sha256.Digest,\n sizeBytes: Schema.Number,\n migrations: Schema.Array(AppliedMigration)\n }),\n artifacts: Schema.Array(ArtifactEntry)\n})\n\n/**\n * The verification contract of a backup.\n *\n * @since 0.1.0\n * @category models\n */\nexport type BackupManifest = typeof BackupManifest.Type\n\n/** JSON text carrying a decoded backup manifest. */\nconst ManifestFromJsonString = Schema.fromJsonString(BackupManifest)\n\n/**\n * Stable failure codes surfaced by backup, verify, restore, and fence.\n * `invalid_options` reports a public option that cannot be admitted safely.\n *\n * @since 0.1.0\n * @category errors\n */\nexport const DisasterRecoveryErrorCode = Schema.Literals([\n \"invalid_options\",\n \"not_empty\",\n \"invalid_manifest\",\n \"missing_file\",\n \"digest_mismatch\",\n \"artifact_corruption\",\n \"snapshot_incomplete\",\n \"schema_mismatch\",\n \"io\",\n \"sql\"\n])\n\n/**\n * A stable disaster-recovery failure code.\n *\n * @since 0.1.0\n * @category errors\n */\nexport type DisasterRecoveryErrorCode = typeof DisasterRecoveryErrorCode.Type\n\n/**\n * A normalized backup or restore failure. The identity string equals this\n * module's package path, per the house rule that a new identity is the\n * defining module path.\n *\n * @since 0.1.0\n * @category errors\n */\nexport class DisasterRecoveryError extends Schema.TaggedError<DisasterRecoveryError>()(\n \"@smthrs/engine-store/DisasterRecoveryError\",\n {\n code: DisasterRecoveryErrorCode,\n method: Schema.String,\n message: Schema.String,\n cause: Schema.Unknown\n }\n) {}\n\n/**\n * Shared buffering limit for backup, verification, and restore operations.\n *\n * @since 1.0.0\n * @category models\n */\nexport interface FileSizeOptions {\n /**\n * Largest file, in bytes, that backup, verification, or restore may buffer.\n * The value must be a finite non-negative safe integer. Defaults to\n * {@link defaultMaxFileSizeBytes}.\n */\n readonly maxFileSizeBytes?: number | undefined\n}\n\n/**\n * Where a backup is written and which artifact store it captures.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface BackupOptions<R = never, E = never> extends FileSizeOptions {\n /** The directory the backup is written into. Created when absent; must be empty when present. */\n readonly directory: string\n /**\n * The live store's content-addressed objects directory (the\n * `ArtifactStore.layerFileSystem` directory). When set, the whole capture\n * holds the cross-process artifact backup lease, so a concurrent\n * `ArtifactGc.gc` sweep cannot delete a blob between the database snapshot\n * and its copy. Absent means the composition has no filesystem artifact\n * tier: the backup carries no blobs and takes no lease, because there is\n * no objects directory to fence, and a frozen snapshot that references any\n * artifact digest fails with `snapshot_incomplete` instead of reporting\n * success. A filesystem-backed composition must therefore pass the same\n * directory it gives `ArtifactStore.layerFileSystem`.\n */\n readonly objectsDirectory?: string | undefined\n /**\n * Opens the frozen `VACUUM INTO` file so backup can enumerate artifact\n * roots and migrations from that exact snapshot, independently of the live\n * connection. The host should open this file without applying migrations.\n */\n readonly snapshotDatabaseLayer: (databaseFile: string) => Layer.Layer<SqlClient.SqlClient, E, R>\n}\n\n/**\n * Which backup to restore and where the restored store lands.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface RestoreOptions extends FileSizeOptions {\n /** The directory a previous {@link backup} wrote. */\n readonly backupDirectory: string\n /** The fresh directory the restored store is written into. Created when absent; must be empty when present. */\n readonly targetDirectory: string\n}\n\n/**\n * Which backup to restore and how to open the freshly restored SQLite file\n * for restore-time fencing.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface RestoreAndFenceOptions<R = never, E = never> extends RestoreOptions {\n /**\n * Builds the database and durable-writer layer for the newly restored file.\n * This keeps database opening as the caller's host composition rather than\n * importing a Node-only driver into this browser-safe module.\n */\n readonly databaseLayer: (databaseFile: string) => Layer.Layer<DurableWriter | SqlClient.SqlClient, E, R>\n}\n\n/**\n * The restored store's on-disk locations, ready to compose database and\n * artifact layers over.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface RestoredStore {\n readonly databaseFile: string\n readonly objectsDirectory: string\n readonly manifest: BackupManifest\n}\n\n/**\n * A restored store after restore-time fencing has invalidated pre-backup\n * owners.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface FencedRestoredStore extends RestoredStore {\n readonly fence: FenceSummary\n}\n\n/**\n * What {@link fence} invalidated on the restored store.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface FenceSummary {\n /** Runs whose pending claim columns were cleared. */\n readonly clearedClaims: number\n /** Runs that were `running` at backup time, now suspended with their owner fence cleared. */\n readonly suspendedRuns: number\n}\n\nconst error = (\n method: string,\n code: DisasterRecoveryErrorCode,\n message: string,\n cause: unknown\n): DisasterRecoveryError =>\n new DisasterRecoveryError({\n code,\n method,\n message: `${code}: DisasterRecovery.${method}: ${message}`,\n cause\n })\n\n/**\n * One mapper per failure family, shared across every call site so the\n * vocabulary stays uniform.\n */\nconst ioFailure = (method: string, subject: string) => (cause: unknown): DisasterRecoveryError =>\n error(method, \"io\", `the host filesystem refused ${subject}`, cause)\n\nconst sqlFailure = (method: string, subject: string) => (cause: unknown): DisasterRecoveryError =>\n error(method, \"sql\", `the database refused ${subject}`, cause)\n\n/** Hashes bytes with the injected crypto service; a broken host is a defect. */\nconst measure = (bytes: Uint8Array): Effect.Effect<typeof Sha256.Digest.Type, never, Crypto.Crypto> =>\n Schema.decodeUnknownEffect(Sha256)(bytes).pipe(Effect.orDie)\n\n/** Resolves and validates the shared whole-file buffering ceiling. */\nconst fileSizeLimit = (\n method: string,\n options: FileSizeOptions\n): number | DisasterRecoveryError => {\n const limit = options.maxFileSizeBytes\n if (limit === undefined) return defaultMaxFileSizeBytes\n if (Number.isSafeInteger(limit) && limit >= 0) return limit\n return error(\n method,\n \"invalid_options\",\n `maxFileSizeBytes must be a finite non-negative safe integer; received ${String(limit)}`,\n limit\n )\n}\n\n/**\n * Refuses an oversized file before a whole-file read allocates its buffer.\n * Every caller admits `limit` through `fileSizeLimit`, so `BigInt` cannot\n * reject it.\n */\nconst checkFileSize = (\n fs: FileSystem.FileSystem,\n method: string,\n path: string,\n limit: number\n): Effect.Effect<void, DisasterRecoveryError> =>\n Effect.gen(function*() {\n const info = yield* fs.stat(path).pipe(Effect.mapError(ioFailure(method, `stating ${path}`)))\n if (info.size <= BigInt(limit)) return\n const message = `${path} is ${info.size} bytes, which exceeds the ${limit}-byte file limit`\n return yield* Effect.fail(error(method, \"io\", message, new RangeError(message)))\n })\n\n/**\n * Admits a target directory that does not exist yet — created recursively —\n * or exists empty. Anything else is refused rather than merged over.\n */\nconst ensureEmptyDirectory = (\n fs: FileSystem.FileSystem,\n method: string,\n directory: string\n): Effect.Effect<void, DisasterRecoveryError> =>\n Effect.gen(function*() {\n const present = yield* fs.exists(directory).pipe(Effect.mapError(ioFailure(method, `probing ${directory}`)))\n if (!present) {\n return yield* fs.makeDirectory(directory, { recursive: true }).pipe(\n Effect.mapError(ioFailure(method, `creating ${directory}`))\n )\n }\n const entries = yield* fs.readDirectory(directory).pipe(\n Effect.mapError(ioFailure(method, `listing ${directory}`))\n )\n if (entries.length > 0) {\n return yield* Effect.fail(\n error(method, \"not_empty\", `${directory} already holds ${entries.length} entries`, directory)\n )\n }\n })\n\n/**\n * A relative blob path in the store's fanout layout: a two-hex directory\n * holding a 64-hex digest that begins with it. Anything else under the\n * objects directory — a scratch `.tmp-*` file, the fanout directory itself —\n * is not part of the store's address space.\n */\nconst blobEntry = (entry: string): string | undefined => {\n const match = entry.match(/^([0-9a-f]{2})[/\\\\]([0-9a-f]{64})$/)\n if (match === null || !match[2]!.startsWith(match[1]!)) return undefined\n return match[2]\n}\n\nconst blobPath = (directory: string, digest: string): string => `${directory}/${digest.slice(0, 2)}/${digest}`\n\n/** The applied rows of the shared migrations table, in ladder order. */\nconst appliedMigrations = (\n sql: SqlClient.SqlClient,\n method: string\n): Effect.Effect<Array<AppliedMigration>, DisasterRecoveryError> =>\n sql<{ readonly migration_id: number; readonly name: string }>`\n SELECT migration_id, name FROM flows_migrations ORDER BY migration_id ASC\n `.withoutTransform.pipe(\n Effect.mapError(sqlFailure(method, \"reading flows_migrations\")),\n Effect.map((rows) => rows.map((row) => ({ migrationId: Number(row.migration_id), name: row.name })))\n )\n\ninterface SnapshotState {\n readonly migrations: Array<AppliedMigration>\n readonly artifactRoots: ReadonlySet<string>\n}\n\n/** Reads every artifact root from the frozen database, never the live one. */\nconst inspectSnapshot = (\n sql: SqlClient.SqlClient\n): Effect.Effect<SnapshotState, DisasterRecoveryError> =>\n Effect.gen(function*() {\n const migrations = yield* appliedMigrations(sql, \"backup\")\n const cacheRows = yield* sql<{ readonly meta_json: string }>`\n SELECT meta_json FROM flows_step_cache\n `.withoutTransform.pipe(\n Effect.mapError(sqlFailure(\"backup\", \"reading artifact roots from snapshot step cache\"))\n )\n const attemptRows = yield* sql<{\n readonly checkpoint_json: string | null\n readonly meta_json: string\n }>`\n SELECT checkpoint_json, meta_json FROM flows_attempts\n `.withoutTransform.pipe(\n Effect.mapError(sqlFailure(\"backup\", \"reading artifact roots from snapshot attempts\"))\n )\n const artifactRoots = new Set<string>()\n const decodeFailure = (cause: ArtifactRoots.ArtifactRootDecodeError): DisasterRecoveryError =>\n error(\"backup\", \"snapshot_incomplete\", cause.message, cause.cause)\n for (const row of cacheRows) {\n for (\n const digest of yield* ArtifactRoots.rootDigests(\"flows_step_cache\", row.meta_json).pipe(\n Effect.mapError(decodeFailure)\n )\n ) artifactRoots.add(digest)\n }\n for (const row of attemptRows) {\n for (\n const digest of yield* ArtifactRoots.rootDigests(\"flows_attempts\", row.meta_json).pipe(\n Effect.mapError(decodeFailure)\n )\n ) artifactRoots.add(digest)\n for (\n const digest of yield* ArtifactRoots.checkpointDigests(row.checkpoint_json).pipe(\n Effect.mapError(decodeFailure)\n )\n ) artifactRoots.add(digest)\n }\n return { migrations, artifactRoots }\n })\n\n/** Reads and decodes the manifest a backup directory must carry. */\nconst readManifest = (\n fs: FileSystem.FileSystem,\n method: string,\n backupDirectory: string,\n maxFileSizeBytes: number\n): Effect.Effect<BackupManifest, DisasterRecoveryError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const path = `${backupDirectory}/${manifestFileName}`\n const present = yield* fs.exists(path).pipe(Effect.mapError(ioFailure(method, `probing ${path}`)))\n if (!present) {\n return yield* Effect.fail(\n error(method, \"missing_file\", `${path} does not exist — the backup is incomplete or not a backup`, path)\n )\n }\n yield* checkFileSize(fs, method, path, maxFileSizeBytes)\n const text = yield* fs.readFileString(path).pipe(Effect.mapError(ioFailure(method, `reading ${path}`)))\n return yield* Schema.decodeUnknownEffect(ManifestFromJsonString)(text).pipe(\n Effect.mapError((cause) =>\n error(method, \"invalid_manifest\", `${path} does not decode as a backup manifest`, cause)\n )\n )\n })\n\n/** Reads a backup file and refuses bytes that no longer hash to the manifest. */\nconst checkedFile = (\n fs: FileSystem.FileSystem,\n method: string,\n path: string,\n expected: string,\n maxFileSizeBytes: number\n): Effect.Effect<Uint8Array, DisasterRecoveryError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const present = yield* fs.exists(path).pipe(Effect.mapError(ioFailure(method, `probing ${path}`)))\n if (!present) {\n return yield* Effect.fail(error(method, \"missing_file\", `${path} does not exist`, path))\n }\n yield* checkFileSize(fs, method, path, maxFileSizeBytes)\n const bytes = yield* fs.readFile(path).pipe(Effect.mapError(ioFailure(method, `reading ${path}`)))\n const measured = yield* measure(bytes)\n if (measured !== expected) {\n return yield* Effect.fail(\n error(method, \"digest_mismatch\", `${path} hashes to ${measured}, the manifest records ${expected}`, path)\n )\n }\n return bytes\n })\n\n/**\n * Captures a hot backup of the live store into an empty directory.\n *\n * The database is snapshotted first with `VACUUM INTO` — a read transaction\n * under WAL, so live writers are never blocked and the copy is one consistent\n * point in time. The artifact walk runs after it, so every digest the\n * snapshot references is captured (publication precedes reference). Blobs are\n * digest-verified as they are copied; a blob whose bytes no longer hash to\n * its address fails the backup loudly rather than capturing corruption. The\n * manifest is encoded and admitted under the same file-size ceiling before it\n * is written last, so a successful backup remains readable with its own\n * options.\n *\n * With an `objectsDirectory`, the whole capture holds the artifact backup\n * lease, so concurrent sweep deletion cannot remove a referenced blob\n * mid-copy. Without one, no lease is taken; the frozen-root verification\n * still fails the backup loudly when the snapshot references any blob, so an\n * unfenced capture can never report success while missing artifact bytes.\n *\n * @since 0.1.0\n * @category operations\n */\nexport const backup = <R = never, E = never>(\n options: BackupOptions<R, E>\n): Effect.Effect<\n BackupManifest,\n DisasterRecoveryError | E,\n SqlClient.SqlClient | FileSystem.FileSystem | Crypto.Crypto | R\n> =>\n Effect.gen(function*() {\n const limit = fileSizeLimit(\"backup\", options)\n if (typeof limit !== \"number\") return yield* Effect.fail(limit)\n const maxFileSizeBytes = limit\n const sql = yield* Effect.service(SqlClient.SqlClient)\n const fs = yield* FileSystem.FileSystem\n const createdAtMs = yield* Clock.currentTimeMillis.pipe(Effect.map(Math.floor))\n yield* ensureEmptyDirectory(fs, \"backup\", options.directory)\n\n const capture = Effect.gen(function*() {\n const databasePath = `${options.directory}/${databaseFileName}`\n yield* sql`VACUUM INTO ${databasePath}`.pipe(\n Effect.mapError(sqlFailure(\"backup\", `snapshotting the database into ${databasePath}`))\n )\n const snapshot = yield* Effect.flatMap(\n Effect.service(SqlClient.SqlClient),\n inspectSnapshot\n ).pipe(Effect.provide(options.snapshotDatabaseLayer(databasePath)))\n // Opening the frozen file may normalize SQLite journal metadata, so its\n // manifest digest is measured only after the inspection connection closes.\n yield* checkFileSize(fs, \"backup\", databasePath, maxFileSizeBytes)\n const databaseBytes = yield* fs.readFile(databasePath).pipe(\n Effect.mapError(ioFailure(\"backup\", `reading ${databasePath} back`))\n )\n const sha256 = yield* measure(databaseBytes)\n\n const artifacts: Array<ArtifactEntry> = []\n const captured = new Set<string>()\n if (options.objectsDirectory !== undefined) {\n const objectsDirectory = options.objectsDirectory\n const entries = yield* fs.readDirectory(objectsDirectory, { recursive: true }).pipe(\n Effect.mapError(ioFailure(\"backup\", `listing ${objectsDirectory}`))\n )\n for (const entry of [...entries].sort()) {\n const digest = blobEntry(entry)\n if (digest === undefined) continue\n const source = blobPath(objectsDirectory, digest)\n yield* checkFileSize(fs, \"backup\", source, maxFileSizeBytes)\n const bytes = yield* fs.readFile(source).pipe(\n Effect.mapError(ioFailure(\"backup\", `reading ${source}`))\n )\n const measured = yield* measure(bytes)\n if (measured !== digest) {\n return yield* Effect.fail(\n error(\n \"backup\",\n \"artifact_corruption\",\n `${source} hashes to ${measured}; repair the store before backing it up`,\n source\n )\n )\n }\n const target = blobPath(`${options.directory}/${objectsDirectoryName}`, digest)\n yield* fs.makeDirectory(`${options.directory}/${objectsDirectoryName}/${digest.slice(0, 2)}`, {\n recursive: true\n }).pipe(Effect.mapError(ioFailure(\"backup\", `creating the objects directory for ${digest}`)))\n yield* fs.writeFile(target, bytes).pipe(Effect.mapError(ioFailure(\"backup\", `writing ${target}`)))\n artifacts.push({ digest: measured, sizeBytes: bytes.length })\n captured.add(measured)\n }\n }\n\n const missing = [...snapshot.artifactRoots].filter((digest) => !captured.has(digest)).sort()\n if (missing.length > 0) {\n return yield* Effect.fail(\n error(\n \"backup\",\n \"snapshot_incomplete\",\n `the frozen database references ${missing.length} artifact blobs absent from the backup`,\n { missing }\n )\n )\n }\n\n const manifest: BackupManifest = {\n formatVersion: 1,\n createdAtMs,\n database: {\n file: databaseFileName,\n sha256,\n sizeBytes: databaseBytes.length,\n migrations: snapshot.migrations\n },\n artifacts\n }\n const manifestPath = `${options.directory}/${manifestFileName}`\n const manifestBytes = new TextEncoder().encode(`${JSON.stringify(manifest, null, 2)}\\n`)\n if (manifestBytes.byteLength > maxFileSizeBytes) {\n const message =\n `${manifestPath} is ${manifestBytes.byteLength} bytes, which exceeds the ${maxFileSizeBytes}-byte file limit`\n return yield* Effect.fail(error(\"backup\", \"io\", message, new RangeError(message)))\n }\n yield* fs.writeFile(manifestPath, manifestBytes).pipe(\n Effect.mapError(ioFailure(\"backup\", `writing ${manifestFileName}`))\n )\n return manifest\n })\n\n // The directory was empty when the capture began, so everything in it is\n // this capture's: the snapshot, any SQLite sidecar the inspection\n // connection left, and the copied blobs. A failed capture removes them and\n // leaves the directory reusable for a retry. Cleanup is best effort; the\n // original failure is the one reported.\n const discardPartial = fs.readDirectory(options.directory).pipe(\n Effect.flatMap((entries) =>\n Effect.forEach(\n entries,\n (entry) => fs.remove(`${options.directory}/${entry}`, { recursive: true, force: true }),\n { discard: true }\n )\n ),\n Effect.ignore\n )\n\n return yield* (options.objectsDirectory === undefined\n ? capture\n : ArtifactBackupLease.withLease(\n fs,\n options.objectsDirectory,\n capture,\n ioFailure(\"backup\", `coordinating artifact backup in ${options.objectsDirectory}`)\n )).pipe(Effect.onError(() => discardPartial))\n }).pipe(Effect.withSpan(\"DisasterRecovery.backup\"))\n\n/**\n * Verifies a backup directory against its manifest without restoring it:\n * the manifest decodes, the database snapshot hashes to its recorded digest,\n * and every listed artifact blob is present and hashes to its address.\n *\n * @since 0.1.0\n * @category operations\n */\nexport const verify = Effect.fn(\"DisasterRecovery.verify\")(function*(\n backupDirectory: string,\n options: FileSizeOptions = {}\n) {\n const limit = fileSizeLimit(\"verify\", options)\n if (typeof limit !== \"number\") return yield* Effect.fail(limit)\n const maxFileSizeBytes = limit\n const fs = yield* FileSystem.FileSystem\n const manifest = yield* readManifest(fs, \"verify\", backupDirectory, maxFileSizeBytes)\n yield* checkedFile(\n fs,\n \"verify\",\n `${backupDirectory}/${manifest.database.file}`,\n manifest.database.sha256,\n maxFileSizeBytes\n )\n for (const entry of manifest.artifacts) {\n yield* checkedFile(\n fs,\n \"verify\",\n blobPath(`${backupDirectory}/${objectsDirectoryName}`, entry.digest),\n entry.digest,\n maxFileSizeBytes\n )\n }\n return manifest\n})\n\n/**\n * Restores a verified backup into an empty target directory.\n *\n * Every byte is re-verified against the manifest as it is copied, so a backup\n * that rotted in storage is refused rather than restored. The target holds\n * the database file, the objects directory, and a `restored.json` marker; it\n * is a fresh store directory to compose `NodeDatabase.layer` and\n * `ArtifactStore.layerFileSystem` over. The database is restored with the\n * pre-backup owner fences still in place — run {@link fence} against it\n * before any engine adopts it.\n *\n * @since 0.1.0\n * @category operations\n */\nexport const restore = Effect.fn(\"DisasterRecovery.restore\")(function*(options: RestoreOptions) {\n const limit = fileSizeLimit(\"restore\", options)\n if (typeof limit !== \"number\") return yield* Effect.fail(limit)\n const maxFileSizeBytes = limit\n const fs = yield* FileSystem.FileSystem\n const manifest = yield* readManifest(fs, \"restore\", options.backupDirectory, maxFileSizeBytes)\n yield* ensureEmptyDirectory(fs, \"restore\", options.targetDirectory)\n\n const databaseBytes = yield* checkedFile(\n fs,\n \"restore\",\n `${options.backupDirectory}/${manifest.database.file}`,\n manifest.database.sha256,\n maxFileSizeBytes\n )\n const databaseFile = `${options.targetDirectory}/${databaseFileName}`\n yield* fs.writeFile(databaseFile, databaseBytes).pipe(\n Effect.mapError(ioFailure(\"restore\", `writing ${databaseFile}`))\n )\n\n const objectsDirectory = `${options.targetDirectory}/${objectsDirectoryName}`\n for (const entry of manifest.artifacts) {\n const bytes = yield* checkedFile(\n fs,\n \"restore\",\n blobPath(`${options.backupDirectory}/${objectsDirectoryName}`, entry.digest),\n entry.digest,\n maxFileSizeBytes\n )\n yield* fs.makeDirectory(`${objectsDirectory}/${entry.digest.slice(0, 2)}`, { recursive: true }).pipe(\n Effect.mapError(ioFailure(\"restore\", `creating the objects directory for ${entry.digest}`))\n )\n yield* fs.writeFile(blobPath(objectsDirectory, entry.digest), bytes).pipe(\n Effect.mapError(ioFailure(\"restore\", `writing the blob for ${entry.digest}`))\n )\n }\n\n const restoredAtMs = yield* Clock.currentTimeMillis.pipe(Effect.map(Math.floor))\n const marker = {\n formatVersion: 1,\n restoredAtMs,\n backupCreatedAtMs: manifest.createdAtMs,\n databaseSha256: manifest.database.sha256\n }\n yield* fs.writeFileString(\n `${options.targetDirectory}/${restoredMarkerFileName}`,\n `${JSON.stringify(marker, null, 2)}\\n`\n ).pipe(Effect.mapError(ioFailure(\"restore\", `writing ${restoredMarkerFileName}`)))\n return { databaseFile, objectsDirectory, manifest } satisfies RestoredStore\n})\n\n/**\n * Bumps the restored store's fencing epoch so pre-backup owners are fenced\n * out.\n *\n * The store's fence is `OwnerId` equality, so the epoch bump is fence\n * invalidation: in one serialized write transaction every pending claim is\n * cleared, every run that was `running` at backup time is suspended with its\n * owner and heartbeat cleared, and every consensus lease is deleted. A\n * surviving pre-backup owner then fails every fenced operation against the\n * restored store — `heartbeat` and `transitionOwned` report `FenceLost`,\n * fenced journal appends fail `fence_lost` — exactly as a stale Temporal owner\n * fails its `rangeID` compare-and-swap. The suspended runs are claimable\n * immediately, without waiting out the heartbeat staleness cutoff and without\n * liveness evidence.\n *\n * Every migration recorded in the manifest must remain applied with the same\n * ID and namespaced name. Forward additions within any installed block are\n * compatible, including engine-store `3006` below an existing plan `4003`;\n * the current database layer applies them on open. A missing or renamed\n * historical entry fails `schema_mismatch` before ownership is cleared.\n *\n * In-flight attempt rows are deliberately untouched: attempt writes are\n * fenced on the run row's ownership, and the resuming engine adopts or\n * retries them under its own fresh owner.\n *\n * @since 0.1.0\n * @category operations\n */\nexport const fence = Effect.fn(\"DisasterRecovery.fence\")(function*(manifest: BackupManifest) {\n const sql = yield* Effect.service(SqlClient.SqlClient)\n const writer = yield* DurableWriter\n const applied = yield* appliedMigrations(sql, \"fence\")\n const expected = manifest.database.migrations\n const key = (migration: AppliedMigration): string => `${migration.migrationId}:${migration.name}`\n // IDs identify migrations within their reserved blocks. Compare historical\n // identities independently so additions in lower blocks cannot shift them.\n const appliedById = new Map(applied.map((migration) => [migration.migrationId, migration.name]))\n if (expected.some((migration) => appliedById.get(migration.migrationId) !== migration.name)) {\n return yield* Effect.fail(\n error(\n \"fence\",\n \"schema_mismatch\",\n `the restored database applied [${applied.map(key).join(\", \")}] but the manifest records [${\n expected.map(key).join(\", \")\n }]`,\n { applied, expected }\n )\n )\n }\n return yield* writer.write(\n Effect.gen(function*() {\n const claims = yield* sql<{ readonly run_id: string }>`\n UPDATE flows_runs\n SET\n claim_host_id = NULL,\n claim_pid = NULL,\n claim_nonce = NULL,\n claimed_at_ms = NULL\n WHERE claim_host_id IS NOT NULL\n RETURNING run_id\n `.withoutTransform\n const running = yield* sql<{ readonly run_id: string }>`\n UPDATE flows_runs\n SET\n status = 'suspended',\n owner_host_id = NULL,\n owner_pid = NULL,\n owner_nonce = NULL,\n heartbeat_at_ms = NULL,\n waiting_reason = 'released',\n waiting_wake_at_ms = NULL,\n waiting_token = NULL\n WHERE status = 'running'\n RETURNING run_id\n `.withoutTransform\n yield* sql`DELETE FROM flows_consensus_leases`.withoutTransform\n return { clearedClaims: claims.length, suspendedRuns: running.length } satisfies FenceSummary\n })\n ).pipe(Effect.mapError(sqlFailure(\"fence\", \"invalidating the persisted fences\")))\n})\n\n/**\n * Restores a backup and immediately fences the restored database.\n *\n * This is the one-shot operator API for disaster recovery. The database\n * driver itself still arrives through a caller-supplied Layer so this module\n * remains host-neutral and browser-bundleable; the bundled Node script passes\n * `NodeDatabase.layer` for the restored file.\n *\n * @since 0.1.0\n * @category operations\n */\nexport const restoreAndFence = <R = never, E = never>(\n options: RestoreAndFenceOptions<R, E>\n): Effect.Effect<FencedRestoredStore, DisasterRecoveryError | E, FileSystem.FileSystem | Crypto.Crypto | R> =>\n Effect.gen(function*() {\n const restored = yield* restore(options)\n const summary = yield* fence(restored.manifest).pipe(\n Effect.provide(options.databaseLayer(restored.databaseFile))\n )\n return { ...restored, fence: summary } satisfies FencedRestoredStore\n })\n"]}