footprintjs 9.48.2 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/AGENTS.md +12 -10
  2. package/CLAUDE.md +21 -23
  3. package/README.md +1 -1
  4. package/dist/advanced.js +71 -128
  5. package/dist/esm/advanced.d.ts +24 -58
  6. package/dist/esm/advanced.js +13 -51
  7. package/dist/esm/index.d.ts +5 -8
  8. package/dist/esm/index.js +3 -3
  9. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +1 -1
  10. package/dist/esm/lib/builder/FlowChartBuilder.js +3 -3
  11. package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +1 -1
  12. package/dist/esm/lib/builder/structure/StructureRecorder.js +1 -1
  13. package/dist/esm/lib/capture/index.d.ts +0 -1
  14. package/dist/esm/lib/capture/index.js +1 -2
  15. package/dist/esm/lib/engine/graph/prefixNodeTree.js +2 -2
  16. package/dist/esm/lib/engine/handlers/ResumeEntry.d.ts +3 -3
  17. package/dist/esm/lib/engine/handlers/ResumeEntry.js +4 -4
  18. package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
  19. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +4 -8
  20. package/dist/esm/lib/engine/index.d.ts +1 -1
  21. package/dist/esm/lib/engine/index.js +1 -1
  22. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
  23. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
  24. package/dist/esm/lib/engine/narrative/index.d.ts +1 -1
  25. package/dist/esm/lib/engine/narrative/index.js +1 -1
  26. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +1 -11
  27. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  28. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
  29. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +4 -6
  30. package/dist/esm/lib/engine/traversalContext.d.ts +1 -1
  31. package/dist/esm/lib/engine/traversalContext.js +2 -2
  32. package/dist/esm/lib/engine/types.d.ts +2 -10
  33. package/dist/esm/lib/engine/types.js +1 -1
  34. package/dist/esm/lib/engine/walkSubflowSpec.js +2 -2
  35. package/dist/esm/lib/ids/reservedIds.js +2 -2
  36. package/dist/esm/lib/memory/DiagnosticCollector.js +2 -2
  37. package/dist/esm/lib/memory/StageContext.d.ts +2 -4
  38. package/dist/esm/lib/memory/StageContext.js +2 -2
  39. package/dist/esm/lib/memory/borrowedMutation.js +2 -2
  40. package/dist/esm/lib/memory/index.d.ts +6 -21
  41. package/dist/esm/lib/memory/index.js +4 -22
  42. package/dist/esm/lib/memory/redaction.d.ts +1 -1
  43. package/dist/esm/lib/memory/redaction.js +2 -2
  44. package/dist/esm/lib/memory/runPolicy.d.ts +3 -2
  45. package/dist/esm/lib/memory/runPolicy.js +1 -1
  46. package/dist/esm/lib/reactive/createTypedScope.js +2 -2
  47. package/dist/esm/lib/reactive/writeTraps.js +2 -2
  48. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +3 -2
  49. package/dist/esm/lib/recorder/ControlDepRecorder.js +3 -2
  50. package/dist/esm/lib/recorder/EmitRecorder.d.ts +1 -1
  51. package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
  52. package/dist/esm/lib/recorder/InOutRecorder.js +2 -2
  53. package/dist/esm/lib/recorder/qualityTrace.d.ts +1 -1
  54. package/dist/esm/lib/recorder/qualityTrace.js +2 -2
  55. package/dist/esm/lib/runner/DeferredObserverTier.js +2 -2
  56. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -5
  57. package/dist/esm/lib/runner/ExecutionRuntime.js +2 -5
  58. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +1 -1
  59. package/dist/esm/lib/runner/FlowChartExecutor.js +1 -1
  60. package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +1 -1
  61. package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -4
  62. package/dist/esm/lib/runner/resume.js +2 -2
  63. package/dist/esm/lib/runner/snapshot.js +3 -2
  64. package/dist/esm/lib/scope/ScopeFacade.js +2 -2
  65. package/dist/esm/lib/scope/state/zod/scopeFactory.js +2 -2
  66. package/dist/esm/recorders.d.ts +2 -3
  67. package/dist/esm/recorders.js +1 -1
  68. package/dist/esm/trace.d.ts +11 -57
  69. package/dist/esm/trace.js +10 -68
  70. package/dist/index.js +3 -3
  71. package/dist/lib/builder/FlowChartBuilder.js +5 -5
  72. package/dist/lib/builder/structure/StructureRecorder.js +1 -1
  73. package/dist/lib/capture/index.js +2 -4
  74. package/dist/lib/engine/graph/prefixNodeTree.js +5 -5
  75. package/dist/lib/engine/handlers/ResumeEntry.js +4 -4
  76. package/dist/lib/engine/handlers/SubflowExecutor.js +5 -9
  77. package/dist/lib/engine/index.js +1 -1
  78. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
  79. package/dist/lib/engine/narrative/index.js +1 -1
  80. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  81. package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -10
  82. package/dist/lib/engine/traversalContext.js +4 -4
  83. package/dist/lib/engine/types.js +1 -1
  84. package/dist/lib/engine/walkSubflowSpec.js +3 -3
  85. package/dist/lib/ids/reservedIds.js +5 -5
  86. package/dist/lib/memory/DiagnosticCollector.js +3 -3
  87. package/dist/lib/memory/StageContext.js +3 -3
  88. package/dist/lib/memory/borrowedMutation.js +3 -3
  89. package/dist/lib/memory/index.js +7 -42
  90. package/dist/lib/memory/redaction.js +3 -3
  91. package/dist/lib/memory/runPolicy.js +1 -1
  92. package/dist/lib/reactive/createTypedScope.js +3 -3
  93. package/dist/lib/reactive/writeTraps.js +4 -4
  94. package/dist/lib/recorder/ControlDepRecorder.js +3 -2
  95. package/dist/lib/recorder/EmitRecorder.js +1 -1
  96. package/dist/lib/recorder/InOutRecorder.js +3 -3
  97. package/dist/lib/recorder/qualityTrace.js +4 -4
  98. package/dist/lib/runner/DeferredObserverTier.js +3 -3
  99. package/dist/lib/runner/ExecutionRuntime.js +6 -9
  100. package/dist/lib/runner/FlowChartExecutor.js +1 -1
  101. package/dist/lib/runner/getSubtreeSnapshot.js +6 -6
  102. package/dist/lib/runner/resume.js +3 -3
  103. package/dist/lib/runner/snapshot.js +6 -5
  104. package/dist/lib/scope/ScopeFacade.js +3 -3
  105. package/dist/lib/scope/state/zod/scopeFactory.js +4 -4
  106. package/dist/recorders.js +1 -1
  107. package/dist/trace.js +18 -120
  108. package/dist/types/advanced.d.ts +24 -58
  109. package/dist/types/index.d.ts +5 -8
  110. package/dist/types/lib/builder/FlowChartBuilder.d.ts +1 -1
  111. package/dist/types/lib/builder/structure/StructureRecorder.d.ts +1 -1
  112. package/dist/types/lib/capture/index.d.ts +0 -1
  113. package/dist/types/lib/engine/handlers/ResumeEntry.d.ts +3 -3
  114. package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
  115. package/dist/types/lib/engine/index.d.ts +1 -1
  116. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
  117. package/dist/types/lib/engine/narrative/index.d.ts +1 -1
  118. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +1 -11
  119. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
  120. package/dist/types/lib/engine/traversalContext.d.ts +1 -1
  121. package/dist/types/lib/engine/types.d.ts +2 -10
  122. package/dist/types/lib/memory/StageContext.d.ts +2 -4
  123. package/dist/types/lib/memory/index.d.ts +6 -21
  124. package/dist/types/lib/memory/redaction.d.ts +1 -1
  125. package/dist/types/lib/memory/runPolicy.d.ts +3 -2
  126. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +3 -2
  127. package/dist/types/lib/recorder/EmitRecorder.d.ts +1 -1
  128. package/dist/types/lib/recorder/qualityTrace.d.ts +1 -1
  129. package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -5
  130. package/dist/types/lib/runner/FlowChartExecutor.d.ts +1 -1
  131. package/dist/types/lib/runner/getSubtreeSnapshot.d.ts +1 -1
  132. package/dist/types/recorders.d.ts +2 -3
  133. package/dist/types/trace.d.ts +11 -57
  134. package/package.json +6 -15
  135. package/dist/esm/lib/capture/freeze.d.ts +0 -91
  136. package/dist/esm/lib/capture/freeze.js +0 -314
  137. package/dist/esm/lib/capture/ownData.d.ts +0 -7
  138. package/dist/esm/lib/capture/ownData.js +0 -15
  139. package/dist/esm/lib/capture/valueKinds.d.ts +0 -57
  140. package/dist/esm/lib/capture/valueKinds.js +0 -142
  141. package/dist/esm/lib/ids/runtimeStageId.d.ts +0 -173
  142. package/dist/esm/lib/ids/runtimeStageId.js +0 -194
  143. package/dist/esm/lib/memory/EventLog.d.ts +0 -105
  144. package/dist/esm/lib/memory/EventLog.js +0 -148
  145. package/dist/esm/lib/memory/RecordFrame.d.ts +0 -232
  146. package/dist/esm/lib/memory/RecordFrame.js +0 -296
  147. package/dist/esm/lib/memory/SharedMemory.d.ts +0 -46
  148. package/dist/esm/lib/memory/SharedMemory.js +0 -88
  149. package/dist/esm/lib/memory/TransactionBuffer.d.ts +0 -521
  150. package/dist/esm/lib/memory/TransactionBuffer.js +0 -946
  151. package/dist/esm/lib/memory/admission.d.ts +0 -81
  152. package/dist/esm/lib/memory/admission.js +0 -153
  153. package/dist/esm/lib/memory/backtrack.d.ts +0 -286
  154. package/dist/esm/lib/memory/backtrack.js +0 -457
  155. package/dist/esm/lib/memory/commitLogUtils.d.ts +0 -217
  156. package/dist/esm/lib/memory/commitLogUtils.js +0 -384
  157. package/dist/esm/lib/memory/deltaEncoding.d.ts +0 -66
  158. package/dist/esm/lib/memory/deltaEncoding.js +0 -122
  159. package/dist/esm/lib/memory/equality.d.ts +0 -93
  160. package/dist/esm/lib/memory/equality.js +0 -262
  161. package/dist/esm/lib/memory/eventPosition.d.ts +0 -18
  162. package/dist/esm/lib/memory/eventPosition.js +0 -2
  163. package/dist/esm/lib/memory/honesty.d.ts +0 -93
  164. package/dist/esm/lib/memory/honesty.js +0 -92
  165. package/dist/esm/lib/memory/keyPaths.d.ts +0 -125
  166. package/dist/esm/lib/memory/keyPaths.js +0 -227
  167. package/dist/esm/lib/memory/logModel.d.ts +0 -76
  168. package/dist/esm/lib/memory/logModel.js +0 -364
  169. package/dist/esm/lib/memory/merge.d.ts +0 -26
  170. package/dist/esm/lib/memory/merge.js +0 -60
  171. package/dist/esm/lib/memory/pathOps.d.ts +0 -115
  172. package/dist/esm/lib/memory/pathOps.js +0 -290
  173. package/dist/esm/lib/memory/paths.d.ts +0 -52
  174. package/dist/esm/lib/memory/paths.js +0 -57
  175. package/dist/esm/lib/memory/placeholders.d.ts +0 -39
  176. package/dist/esm/lib/memory/placeholders.js +0 -40
  177. package/dist/esm/lib/memory/recordCommit.d.ts +0 -45
  178. package/dist/esm/lib/memory/recordCommit.js +0 -61
  179. package/dist/esm/lib/memory/scrub.d.ts +0 -53
  180. package/dist/esm/lib/memory/scrub.js +0 -74
  181. package/dist/esm/lib/memory/types.d.ts +0 -209
  182. package/dist/esm/lib/memory/types.js +0 -10
  183. package/dist/esm/lib/memory/utils.d.ts +0 -73
  184. package/dist/esm/lib/memory/utils.js +0 -159
  185. package/dist/esm/lib/memory/verbs.d.ts +0 -333
  186. package/dist/esm/lib/memory/verbs.js +0 -427
  187. package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +0 -147
  188. package/dist/esm/lib/recorder/CommitRangeIndex.js +0 -207
  189. package/dist/esm/lib/scope/detectCircular.d.ts +0 -13
  190. package/dist/esm/lib/scope/detectCircular.js +0 -14
  191. package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +0 -5
  192. package/dist/esm/lib/scope/recorders/summarizeValue.js +0 -6
  193. package/dist/esm/lib/slice/elementProvenance.d.ts +0 -81
  194. package/dist/esm/lib/slice/elementProvenance.js +0 -190
  195. package/dist/esm/lib/slice/forwardSliceForKey.d.ts +0 -88
  196. package/dist/esm/lib/slice/forwardSliceForKey.js +0 -243
  197. package/dist/esm/lib/slice/index.d.ts +0 -25
  198. package/dist/esm/lib/slice/index.js +0 -25
  199. package/dist/esm/lib/slice/keyIndex.d.ts +0 -137
  200. package/dist/esm/lib/slice/keyIndex.js +0 -293
  201. package/dist/esm/lib/slice/keyTimeline.d.ts +0 -49
  202. package/dist/esm/lib/slice/keyTimeline.js +0 -113
  203. package/dist/esm/lib/slice/keysReadSources.d.ts +0 -51
  204. package/dist/esm/lib/slice/keysReadSources.js +0 -95
  205. package/dist/esm/lib/slice/serialize.d.ts +0 -78
  206. package/dist/esm/lib/slice/serialize.js +0 -278
  207. package/dist/esm/lib/slice/sliceForKey.d.ts +0 -47
  208. package/dist/esm/lib/slice/sliceForKey.js +0 -88
  209. package/dist/esm/lib/slice/types.d.ts +0 -567
  210. package/dist/esm/lib/slice/types.js +0 -25
  211. package/dist/esm/lib/time-travel/axis.d.ts +0 -119
  212. package/dist/esm/lib/time-travel/axis.js +0 -179
  213. package/dist/esm/lib/time-travel/bundles.d.ts +0 -77
  214. package/dist/esm/lib/time-travel/bundles.js +0 -136
  215. package/dist/esm/lib/time-travel/chain.d.ts +0 -93
  216. package/dist/esm/lib/time-travel/chain.js +0 -188
  217. package/dist/esm/lib/time-travel/commitStops.d.ts +0 -55
  218. package/dist/esm/lib/time-travel/commitStops.js +0 -202
  219. package/dist/esm/lib/time-travel/index.d.ts +0 -22
  220. package/dist/esm/lib/time-travel/index.js +0 -21
  221. package/dist/esm/lib/time-travel/stateAt.d.ts +0 -102
  222. package/dist/esm/lib/time-travel/stateAt.js +0 -153
  223. package/dist/esm/lib/time-travel/tagStops.d.ts +0 -72
  224. package/dist/esm/lib/time-travel/tagStops.js +0 -102
  225. package/dist/esm/lib/time-travel/timeTravel.d.ts +0 -70
  226. package/dist/esm/lib/time-travel/timeTravel.js +0 -360
  227. package/dist/esm/lib/time-travel/types.d.ts +0 -470
  228. package/dist/esm/lib/time-travel/types.js +0 -23
  229. package/dist/esm/write.d.ts +0 -47
  230. package/dist/esm/write.js +0 -46
  231. package/dist/lib/capture/freeze.js +0 -320
  232. package/dist/lib/capture/ownData.js +0 -19
  233. package/dist/lib/capture/valueKinds.js +0 -146
  234. package/dist/lib/ids/runtimeStageId.js +0 -210
  235. package/dist/lib/memory/EventLog.js +0 -152
  236. package/dist/lib/memory/RecordFrame.js +0 -300
  237. package/dist/lib/memory/SharedMemory.js +0 -92
  238. package/dist/lib/memory/TransactionBuffer.js +0 -950
  239. package/dist/lib/memory/admission.js +0 -159
  240. package/dist/lib/memory/backtrack.js +0 -463
  241. package/dist/lib/memory/commitLogUtils.js +0 -399
  242. package/dist/lib/memory/deltaEncoding.js +0 -128
  243. package/dist/lib/memory/equality.js +0 -266
  244. package/dist/lib/memory/eventPosition.js +0 -3
  245. package/dist/lib/memory/honesty.js +0 -95
  246. package/dist/lib/memory/keyPaths.js +0 -243
  247. package/dist/lib/memory/logModel.js +0 -372
  248. package/dist/lib/memory/merge.js +0 -64
  249. package/dist/lib/memory/pathOps.js +0 -306
  250. package/dist/lib/memory/paths.js +0 -62
  251. package/dist/lib/memory/placeholders.js +0 -43
  252. package/dist/lib/memory/recordCommit.js +0 -65
  253. package/dist/lib/memory/scrub.js +0 -79
  254. package/dist/lib/memory/types.js +0 -11
  255. package/dist/lib/memory/utils.js +0 -178
  256. package/dist/lib/memory/verbs.js +0 -444
  257. package/dist/lib/recorder/CommitRangeIndex.js +0 -211
  258. package/dist/lib/scope/detectCircular.js +0 -21
  259. package/dist/lib/scope/recorders/summarizeValue.js +0 -10
  260. package/dist/lib/slice/elementProvenance.js +0 -195
  261. package/dist/lib/slice/forwardSliceForKey.js +0 -247
  262. package/dist/lib/slice/index.js +0 -42
  263. package/dist/lib/slice/keyIndex.js +0 -313
  264. package/dist/lib/slice/keyTimeline.js +0 -117
  265. package/dist/lib/slice/keysReadSources.js +0 -101
  266. package/dist/lib/slice/serialize.js +0 -286
  267. package/dist/lib/slice/sliceForKey.js +0 -93
  268. package/dist/lib/slice/types.js +0 -26
  269. package/dist/lib/time-travel/axis.js +0 -184
  270. package/dist/lib/time-travel/bundles.js +0 -144
  271. package/dist/lib/time-travel/chain.js +0 -193
  272. package/dist/lib/time-travel/commitStops.js +0 -206
  273. package/dist/lib/time-travel/index.js +0 -32
  274. package/dist/lib/time-travel/stateAt.js +0 -160
  275. package/dist/lib/time-travel/tagStops.js +0 -106
  276. package/dist/lib/time-travel/timeTravel.js +0 -364
  277. package/dist/lib/time-travel/types.js +0 -24
  278. package/dist/types/lib/capture/freeze.d.ts +0 -91
  279. package/dist/types/lib/capture/ownData.d.ts +0 -7
  280. package/dist/types/lib/capture/valueKinds.d.ts +0 -57
  281. package/dist/types/lib/ids/runtimeStageId.d.ts +0 -173
  282. package/dist/types/lib/memory/EventLog.d.ts +0 -105
  283. package/dist/types/lib/memory/RecordFrame.d.ts +0 -232
  284. package/dist/types/lib/memory/SharedMemory.d.ts +0 -46
  285. package/dist/types/lib/memory/TransactionBuffer.d.ts +0 -521
  286. package/dist/types/lib/memory/admission.d.ts +0 -81
  287. package/dist/types/lib/memory/backtrack.d.ts +0 -286
  288. package/dist/types/lib/memory/commitLogUtils.d.ts +0 -217
  289. package/dist/types/lib/memory/deltaEncoding.d.ts +0 -66
  290. package/dist/types/lib/memory/equality.d.ts +0 -93
  291. package/dist/types/lib/memory/eventPosition.d.ts +0 -18
  292. package/dist/types/lib/memory/honesty.d.ts +0 -93
  293. package/dist/types/lib/memory/keyPaths.d.ts +0 -125
  294. package/dist/types/lib/memory/logModel.d.ts +0 -76
  295. package/dist/types/lib/memory/merge.d.ts +0 -26
  296. package/dist/types/lib/memory/pathOps.d.ts +0 -115
  297. package/dist/types/lib/memory/paths.d.ts +0 -52
  298. package/dist/types/lib/memory/placeholders.d.ts +0 -39
  299. package/dist/types/lib/memory/recordCommit.d.ts +0 -45
  300. package/dist/types/lib/memory/scrub.d.ts +0 -53
  301. package/dist/types/lib/memory/types.d.ts +0 -209
  302. package/dist/types/lib/memory/utils.d.ts +0 -73
  303. package/dist/types/lib/memory/verbs.d.ts +0 -333
  304. package/dist/types/lib/recorder/CommitRangeIndex.d.ts +0 -147
  305. package/dist/types/lib/scope/detectCircular.d.ts +0 -13
  306. package/dist/types/lib/scope/recorders/summarizeValue.d.ts +0 -5
  307. package/dist/types/lib/slice/elementProvenance.d.ts +0 -81
  308. package/dist/types/lib/slice/forwardSliceForKey.d.ts +0 -88
  309. package/dist/types/lib/slice/index.d.ts +0 -25
  310. package/dist/types/lib/slice/keyIndex.d.ts +0 -137
  311. package/dist/types/lib/slice/keyTimeline.d.ts +0 -49
  312. package/dist/types/lib/slice/keysReadSources.d.ts +0 -51
  313. package/dist/types/lib/slice/serialize.d.ts +0 -78
  314. package/dist/types/lib/slice/sliceForKey.d.ts +0 -47
  315. package/dist/types/lib/slice/types.d.ts +0 -567
  316. package/dist/types/lib/time-travel/axis.d.ts +0 -119
  317. package/dist/types/lib/time-travel/bundles.d.ts +0 -77
  318. package/dist/types/lib/time-travel/chain.d.ts +0 -93
  319. package/dist/types/lib/time-travel/commitStops.d.ts +0 -55
  320. package/dist/types/lib/time-travel/index.d.ts +0 -22
  321. package/dist/types/lib/time-travel/stateAt.d.ts +0 -102
  322. package/dist/types/lib/time-travel/tagStops.d.ts +0 -72
  323. package/dist/types/lib/time-travel/timeTravel.d.ts +0 -70
  324. package/dist/types/lib/time-travel/types.d.ts +0 -470
  325. package/dist/types/write.d.ts +0 -47
  326. package/dist/write.js +0 -52
@@ -1,57 +0,0 @@
1
- /**
2
- * valueKinds.ts — what KIND of value a record holds: the one classifier.
3
- *
4
- * WHY. Committed state is what survives `structuredClone` (an engine invariant), so the values a
5
- * record holds are the kinds the clone keeps. Two laws need the kind, and both ask here:
6
- *
7
- * - what counts as a CHANGE (`memory/equality.ts · deepEqual`): two values are equal when a record
8
- * holds the same thing for both, compared kind by kind. Until 9.44.2 only Date, Map and Set had a
9
- * kind; a RegExp, an Error, a boxed number, a buffer, a DataView or a Blob was compared as an
10
- * object with no own keys — equal to any other of its kind — so replacing one committed no row
11
- * and live state kept the old value;
12
- * - what a served record must COPY (`capture/freeze.ts · freezeRecord` / `serveRecord`):
13
- * `Object.freeze` seals only the kinds whose content is their own properties ({@link SEALABLE}).
14
- *
15
- * A leaf: imports nothing (`capture/` is L0, below `memory/`).
16
- *
17
- * @example
18
- * ```typescript
19
- * kindOf(new Date(0)); // 'date'
20
- * kindOf(new (class Point { x = 1 })()); // 'plain' — its clone is a plain object
21
- * kindOf(new Blob(['a'])); // 'opaque' — its clone keeps content this library cannot read
22
- * SEALABLE.date; // false — setTime writes a slot Object.freeze cannot reach
23
- * ```
24
- */
25
- /** Every kind a record can hold. */
26
- export type ValueKind =
27
- /** An object the clone keeps as its own enumerable keys — a class instance included. */
28
- 'plain' | 'array' | 'date' | 'regexp' | 'map' | 'set' | 'error'
29
- /** A boxed primitive: `new Number(1)`, `new String('a')`, `new Boolean(true)`, `Object(1n)`. */
30
- | 'boxed'
31
- /** An `ArrayBuffer` (a `SharedArrayBuffer` too: shared memory is out of contract for state). */
32
- | 'buffer'
33
- /** A typed array or a `DataView`. */
34
- | 'view'
35
- /** Any other object the clone keeps as itself (a Blob, a File, a `DOMException`): content unread here. */
36
- | 'opaque';
37
- /**
38
- * Does `Object.freeze` seal every part of a value of this kind? True only where the content is the
39
- * value's own properties (or a slot nothing can write). A `Record`, so a new kind does not compile
40
- * until it is decided here.
41
- */
42
- export declare const SEALABLE: {
43
- readonly [K in ValueKind]: boolean;
44
- };
45
- /**
46
- * The kind of an object, as a record holds it. A plain object or an array — the bulk of state —
47
- * costs one `Array.isArray` and one `getPrototypeOf`; a built-in a tag and one brand-checked read.
48
- * The brand is the value's own slot, so a subclass (a `Map` subclass is a `'map'`, Node's `Buffer` a
49
- * `'view'`) and a value from another realm land on their kind.
50
- *
51
- * Any other object is classified by WHAT ITS CLONE IS, once per prototype: a class instance comes
52
- * back a plain object (`'plain'`), a fake built-in (`Object.create(Date.prototype)`, or a class whose
53
- * `Symbol.toStringTag` says `'Date'`) comes back `{}` (`'plain'`), and a host object comes back as
54
- * itself (`'opaque'`). A prototype whose instance the clone refuses is `'opaque'` — remembered too:
55
- * it cannot be held, and its commit will refuse it.
56
- */
57
- export declare function kindOf(value: object): ValueKind;
@@ -1,173 +0,0 @@
1
- /**
2
- * runtimeStageId — unique identifier for each execution step during traversal.
3
- *
4
- * Format: [subflowPath/]stageId#executionIndex
5
- *
6
- * Components:
7
- * stageId — stable node ID from the builder ('call-llm', 'seed')
8
- * executionIndex — monotonic counter incremented per stage execution (0, 1, 2...)
9
- * subflowPath — optional path for subflow stages ('sf-tools', 'sf-outer/sf-inner')
10
- *
11
- * Properties:
12
- * - Unique within a run (executionIndex never repeats)
13
- * - Execution-ordered (sort by executionIndex = execution order)
14
- * - Human-readable ('sf-tools/execute-tool-calls#8')
15
- * - Parseable (split on '#' for stageId and index, split stageId on '/' for subflow path)
16
- *
17
- * Naming-collision warning
18
- * ────────────────────────
19
- * The parsed-output `.stageId` field below is the LOCAL form (segment
20
- * after the last '/'). This is NOT the same as `spec.id` / `node.id`
21
- * for subflow-nested stages, which carry the FULL prefixed form
22
- * (`'sf-tools/execute-tool-calls'`). To compare safely, use
23
- * `splitStageId(spec.id)` to decompose the prefixed form the same
24
- * way `parseRuntimeStageId` decomposes a runtimeStageId.
25
- *
26
- * @example
27
- * ```
28
- * buildRuntimeStageId('call-llm', 5) // 'call-llm#5'
29
- * buildRuntimeStageId('execute-tool-calls', 8, 'sf-tools') // 'sf-tools/execute-tool-calls#8'
30
- * buildRuntimeStageId('validate', 3, 'sf-outer/sf-inner') // 'sf-outer/sf-inner/validate#3'
31
- * ```
32
- *
33
- * ## The one owner (F7, 9.37.0)
34
- *
35
- * This module is the ONE place the grammar is spelled. Every reader asks it —
36
- * `isExecutionKey`, `stageIdOf`, `subflowPathOf`, `subflowSegmentsOf`,
37
- * `lastSegmentOf`, `isWithinSubflow` — and every composer joins through
38
- * `joinPath` / `buildRuntimeStageId`; no other file splits on `#` or `/`.
39
- * It builds, parses and reads ids, and imports nothing: it is the record's
40
- * (C6). The delimiters are RESERVED (RFC 3986 §2.2 style): the engine's id
41
- * doors refuse them in user-authored ids through ONE function,
42
- * `reservedIds.ts · refuseReservedId`, which reads them here — so
43
- * last-delimiter parsing is sound by construction rather than by hope. Stores
44
- * and the prefixer never refuse — they hold runtime ids and prefixed ids,
45
- * which carry the delimiters on purpose.
46
- */
47
- /** Separates subflow path segments from each other and from the stage id. */
48
- export declare const PATH_DELIMITER = "/";
49
- /** Separates the (prefixed) stage id from the execution index. */
50
- export declare const EXECUTION_DELIMITER = "#";
51
- declare const RUNTIME_STAGE_ID: unique symbol;
52
- declare const EXECUTION_INDEX: unique symbol;
53
- declare const COMMIT_IDX: unique symbol;
54
- /** A `[subflowPath/]stageId#executionIndex` string the grammar produced. Assignable to `string`. */
55
- export type RuntimeStageId = string & {
56
- readonly [RUNTIME_STAGE_ID]: true;
57
- };
58
- /** The run-global, monotonic position of one stage execution (the `#N`). Assignable to `number`. */
59
- export type ExecutionIndex = number & {
60
- readonly [EXECUTION_INDEX]: true;
61
- };
62
- /** A bundle's position in a commit log (`bundle.idx`). Assignable to `number`. */
63
- export type CommitIdx = number & {
64
- readonly [COMMIT_IDX]: true;
65
- };
66
- /**
67
- * Build a runtimeStageId from its components.
68
- *
69
- * Note: The traverser does NOT use the subflowPath parameter — node.id already
70
- * includes the subflow prefix from the builder. This parameter exists for external
71
- * consumers constructing IDs from parsed components (round-trip via parseRuntimeStageId).
72
- */
73
- export declare function buildRuntimeStageId(stageId: string, executionIndex: number, subflowPath?: string): RuntimeStageId;
74
- /**
75
- * Parse a runtimeStageId into its components.
76
- *
77
- * IMPORTANT — naming collision: the returned `stageId` is the LOCAL
78
- * form (the segment between the last '/' and the '#'). This is NOT
79
- * the same as `spec.id` or `node.id` for subflow-nested stages,
80
- * which contain the FULL prefixed form.
81
- *
82
- * parseRuntimeStageId('sf-tools/execute-tool-calls#8').stageId
83
- * // → 'execute-tool-calls' (LOCAL)
84
- *
85
- * node.id // (post-mount, in a spec that contains subflows)
86
- * // → 'sf-tools/execute-tool-calls' (FULL prefixed)
87
- *
88
- * To compare these two safely, use `splitStageId(node.id)` to get
89
- * the local form, OR reconstruct the full form via
90
- * `(subflowPath ? subflowPath + '/' : '') + stageId`.
91
- */
92
- export declare function parseRuntimeStageId(runtimeStageId: string): {
93
- stageId: string;
94
- executionIndex: ExecutionIndex;
95
- subflowPath: string | undefined;
96
- };
97
- /**
98
- * Decompose a (possibly prefixed) stage id into its components.
99
- *
100
- * Use this when you have an id WITHOUT the `#N` execution suffix and
101
- * need the local stage name and/or the subflow path. Common sources
102
- * of such ids:
103
- * - `spec.id` (post-mount the id includes any subflow prefix)
104
- * - `CommitBundle.stageId` (post-mount id)
105
- * - `node.id` from xyflow nodes built off the spec
106
- * - the segment of `runtimeStageId` BEFORE the `#` (use
107
- * `parseRuntimeStageId` directly for full runtimeStageId strings)
108
- *
109
- * Mirrors the decomposition `parseRuntimeStageId` performs on the
110
- * stageId portion of a runtimeStageId, so the two helpers stay in
111
- * lockstep on naming and behavior.
112
- *
113
- * @example
114
- * splitStageId('sf-tools/execute-tool-calls')
115
- * // → { localStageId: 'execute-tool-calls', subflowPath: 'sf-tools' }
116
- *
117
- * splitStageId('execute-tool-calls')
118
- * // → { localStageId: 'execute-tool-calls', subflowPath: undefined }
119
- *
120
- * splitStageId('sf-outer/sf-inner/validate')
121
- * // → { localStageId: 'validate', subflowPath: 'sf-outer/sf-inner' }
122
- */
123
- export declare function splitStageId(prefixedStageId: string): {
124
- localStageId: string;
125
- subflowPath: string | undefined;
126
- };
127
- /**
128
- * True when `key` names one EXECUTION (`…#N`) rather than a stage or a subflow
129
- * path. Its presence alone decides: the delimiter is reserved in every
130
- * user-authored id (`reservedIds.ts · refuseReservedId`), so only the grammar
131
- * puts it there.
132
- *
133
- * Asked where a map is keyed by both — `subflowResults` is dual-keyed by
134
- * subflow path AND by mount runtimeStageId.
135
- */
136
- export declare function isExecutionKey(key: string): boolean;
137
- /**
138
- * The FULL (subflow-prefixed) stage id of a runtimeStageId — everything before
139
- * the last `#`, i.e. what `node.id` / `CommitBundle.stageId` hold. A string
140
- * with no `#` is returned whole.
141
- *
142
- * @example stageIdOf('sf-tools/execute#8') // 'sf-tools/execute'
143
- */
144
- export declare function stageIdOf(runtimeStageId: string): string;
145
- /** The execution index of a runtimeStageId, or `NaN` when it carries none. */
146
- export declare function executionIndexOf(runtimeStageId: string): number;
147
- /**
148
- * The subflow path a runtimeStageId executes in (`'sf-a/sf-b'`), or
149
- * `undefined` at the top level. Reads the stage-id part, so it agrees with
150
- * `splitStageId(stageIdOf(rid)).subflowPath`.
151
- */
152
- export declare function subflowPathOf(runtimeStageId: string): string | undefined;
153
- /** The subflow path of a runtimeStageId as segments (`['sf-a', 'sf-b']`); `[]` at the top level. */
154
- export declare function subflowSegmentsOf(runtimeStageId: string): string[];
155
- /** The non-empty segments of a subflow path or prefixed id (`'a//b/'` → `['a', 'b']`). */
156
- export declare function pathSegments(path: string): string[];
157
- /** The last segment of a path or prefixed id (`'sf-a/sf-b'` → `'sf-b'`); the whole string when it has none. */
158
- export declare function lastSegmentOf(path: string): string;
159
- /** Join path segments with the grammar's delimiter (`joinPath('sf', 'stage')` → `'sf/stage'`). */
160
- export declare function joinPath(...segments: readonly string[]): string;
161
- /** True when the (prefixed) id `id` sits INSIDE the subflow at `path` — at any depth below it. */
162
- export declare function isWithinSubflow(id: string, path: string): boolean;
163
- /**
164
- * Shared mutable counter for execution index.
165
- * Passed by reference to child traversers (subflows) so they
166
- * continue the global numbering instead of restarting at 0.
167
- */
168
- export interface ExecutionCounter {
169
- value: number;
170
- }
171
- /** Create a new execution counter starting at 0. */
172
- export declare function createExecutionCounter(): ExecutionCounter;
173
- export {};
@@ -1,105 +0,0 @@
1
- /**
2
- * EventLog — Time-travel snapshot storage for flowchart execution
3
- *
4
- * Like git history: stores commit bundles (diffs), not full snapshots.
5
- *
6
- * THE RECORD IS IMMUTABLE FROM `record` (F3, ruling R3). Every bundle is deep-frozen as it is
7
- * recorded — the bundle, `overwrite` and `updates` at every depth, the trace and each row, the
8
- * row's `readKeys`, `redactedPaths`, `tags`, `untrackedSources` — so a holder of a snapshot can no
9
- * longer rewrite the history every later answer is folded from: an assignment into a bundle throws
10
- * a `TypeError` in strict code. Safe because nothing outside the log holds a bundle's containers:
11
- * the log's payload is the commit's own copy (`recordCommit` hands it the output of
12
- * `scrubPatch`), and live state, the redacted mirror and write retention each take their own copy
13
- * (`verbs.ts · foldRows` detaches, `StageContext · retainedForm` clones) — pinned by
14
- * test/lib/memory/property/record-reachability.property.test.ts.
15
- *
16
- * What `Object.freeze` cannot seal — a Date's time, a Map's or Set's entries, a buffer's bytes, a
17
- * RegExp, an Error's stack — is never handed out to a reader (9.44.2): `record` remembers that a
18
- * bundle holds such a value (`capture/freeze.ts · freezeRecord`), and `list()` — like the public
19
- * snapshot, `runner/snapshot.ts · servedSnapshot` — serves that bundle as a copy of its open paths
20
- * (`serveRecord`, mapped at its first serve): fresh frozen containers down to each such value, a
21
- * fresh copy of it, every other part the log's own. A reader edits only its own copy; every later
22
- * serve reads the record as recorded. `recorded()` is the engine's own, unserved read. Named holes: an object hung on an array EXPANDO (arrays are walked
23
- * by index — the `'indices'` walk, which keeps the freeze inside its budget; an expando is out of
24
- * contract for state) and a `SharedArrayBuffer` (every copy shares its memory). A frozen RegExp's
25
- * `lastIndex` is read-only, so a `/g` or `/y` regex read from a bundle throws when `exec` or
26
- * `replace` advance it.
27
- */
28
- import type { EmitSourcePosition, LogAddress } from './eventPosition.js';
29
- import type { CommitBundle } from './types.js';
30
- export declare class EventLog {
31
- /** Base snapshot BEFORE the first stage mutates anything. */
32
- private base;
33
- /** Ordered list of commit bundles. */
34
- private steps;
35
- private sourceAddress?;
36
- private sourceAddressRetired;
37
- constructor(initialMemory: any);
38
- /**
39
- * The fold BASE — the state as it stood before the first commit.
40
- *
41
- * This is the other half of the commit log: bundles are DIFFS, so a log
42
- * alone cannot reconstruct state that was seeded before the run (an
43
- * executor `initialContext`, `defaultValuesForContext`, a resume's
44
- * `checkpoint.sharedState`, a subflow's `inputMapper` seed). Travelling
45
- * with the log — `RuntimeSnapshot.initialState` — is what lets an OFFLINE
46
- * consumer fold; without it the honest answer is a partial one
47
- * (`stateAt`'s `basis: 'log-only'`).
48
- *
49
- * Returns a fresh detached clone on every call — the caller owns it.
50
- */
51
- getInitialState(): any;
52
- /**
53
- * Reconstructs the full state at any given step.
54
- * Replays commits from the beginning — O(n) but low memory footprint.
55
- *
56
- * INDEX CONVENTION — `stepIdx` is EXCLUSIVE: `materialise(3)` folds commits
57
- * 0, 1 and 2. `stateAt(source, commitIdx)` (footprintjs/trace) folds the
58
- * same log but its `commitIdx` is INCLUSIVE, because a reader's cursor asks
59
- * "the state AT this stop", which must include that stop's own commit. Two
60
- * folds over one log with opposite conventions: check which one you hold.
61
- *
62
- * One clone of the base per call, then every bundle replayed INTO that
63
- * private copy (`applySmartMergeInto` — the live commit's copy-on-write law
64
- * below the root, 9.29.0, so the fold and the live state agree at every
65
- * path). The result is the caller's: it shares nothing with the base or
66
- * the log.
67
- *
68
- * @deprecated Since 9.33.0 — use `stateAt` from `footprintjs/trace`, which folds the same log
69
- * from the same base (`RuntimeSnapshot.initialState`) and says how it was derived (`basis`).
70
- * Nothing in the library calls this; it stays for one minor and is then removed. Mind the
71
- * index: `materialise(n)` folds commits `0..n-1`, `stateAt(source, n - 1)` the same commits.
72
- */
73
- materialise(stepIdx?: number): any;
74
- /**
75
- * Persists a commit bundle for a finished stage, and FREEZES it (see the module doc): the bundle
76
- * is stamped with its position, then deep-frozen, then appended. The engine hands it a bundle
77
- * built for the log alone; a caller of this class (`footprintjs/write`) hands over a bundle it
78
- * will no longer edit — its own object is the one frozen.
79
- */
80
- record(bundle: CommitBundle): void;
81
- /**
82
- * Every recorded commit bundle, AS SERVED (9.44.2): a new array each call; a bundle freezing sealed
83
- * whole is the log's own (frozen) object, one holding a Date, Map, buffer … is a copy of its open
84
- * paths (`capture/freeze.ts · serveRecord`) — the reader's own, so no edit reaches the log.
85
- */
86
- list(): CommitBundle[];
87
- /**
88
- * @internal The bundles as the log holds them — each frozen, NOT served — in a new array, so a holder's
89
- * `splice` reaches only its own. For the engine's own snapshot (`ExecutionRuntime · getSnapshot`, which
90
- * a subflow mount takes once per mount), so the run serves nothing; a reader is served by `list()` and
91
- * `getSnapshot().commitLog`. A known open door (CHANGELOG 9.44.2): a holder of these bundles can still
92
- * edit a Date, Map or buffer inside them.
93
- */
94
- recorded(): CommitBundle[];
95
- /** Number of recorded commits. */
96
- get length(): number;
97
- /** Immutable identity of this log, absent until the engine binds it. */
98
- get address(): LogAddress | undefined;
99
- /** @internal Bind once; resuming the same log must not rename its earlier positions. */
100
- bindAddress(logRunId: string, drillPath: readonly string[]): void;
101
- /** O(1) source-time capture. No counter, observer bookkeeping, or future commit prediction. */
102
- capturePosition(runId: string): EmitSourcePosition | undefined;
103
- /** Wipes history (useful for test resets). */
104
- clear(): void;
105
- }
@@ -1,232 +0,0 @@
1
- /**
2
- * RecordFrame — the record half of one stage's frame (C3, L3).
3
- *
4
- * What a stage's frame needs to READ and WRITE the record, and nothing about the stage inside a run:
5
- * where it writes (its address), what it read first (the first-touch base), what it staged (the lazy
6
- * transaction buffer) and which of it the log must not show (the scrub of each write), which keys it
7
- * read (the readKeys list), and where a commit lands (live state, the redacted mirror, the log —
8
- * through `recordCommit`). The engine's frame (`StageContext`, L4) composes one and keeps the rest:
9
- * retention, diagnostics, the dev-mode warnings, the commit observer and the redaction DECISION —
10
- * which value is secret (`redaction.ts · decideWrite`); the frame writes the bytes it is handed (C4).
11
- *
12
- * THE LAW:
13
- * 1. ADDRESS. The frame reads and writes at its address, a path prefix the engine computed and hands
14
- * over as data (C2: `['runs', <id>]` or `[]`, the root). It moves only before the first write:
15
- * the buffer keeps the address it was built at (the engine refuses a later move).
16
- * 2. FIRST TOUCH. The committed generation the frame first touched — its first read OR first write —
17
- * is held by reference, never cloned: the read view before the first write and the buffer's
18
- * net-change diff base after it.
19
- * 3. TWO TIERS. A read is served from the stage's own view (the buffer's working copy once the stage
20
- * wrote, else the first-touch base); a key absent there is served from LIVE state (at the
21
- * address, then the root). After the first write the buffer's diff base is first given a private
22
- * copy at that path (`TransactionBuffer · detachBase`).
23
- * 4. LAZY BUFFER. The buffer is built at the first write — on the first-touch base, at the address,
24
- * under the encoding. A frame that never writes builds none, and its commit is the empty bundle.
25
- * 5. READ KEYS. Under `writeProvenance: 'reads-prefix'` every noted read puts its user-level key
26
- * (dotted for a nested path) on the frame's list, once, in order; each staged row carries a copy
27
- * of the list as it stands when the row is staged.
28
- * 6. COMMIT, RELEASE, DISCARD. `commit` takes the buffer's payload (none = the empty commit), then
29
- * the names, and hands both to `recordCommit`. `release` drops the buffer and the base; a frame
30
- * touched again re-anchors on the state as it stands then. The readKeys list survives a release,
31
- * and goes with `discard` (a failed attempt never happened).
32
- * 7. WRITE. `write(path, value, verb, scrub?)` is the one way to stage: `set`, `merge` or `delete`
33
- * at an absolute path (the address already joined — `at`), with the bytes of a redaction
34
- * verdict. `whole` → the log and the mirror carry `LOG_PLACEHOLDER` at the path; `fields` → at
35
- * each field inside the value (a literal key and, when dotted, the nested path) — wherever it
36
- * holds a value at commit (`scrub.ts`). No scrub → the value as it is. The frame never decides
37
- * a scrub, and nothing outside it reaches its buffer.
38
- */
39
- import type { OpVerb } from './deltaEncoding.js';
40
- import type { EventLog } from './EventLog.js';
41
- import { type CommitStamp } from './recordCommit.js';
42
- import type { SharedMemory } from './SharedMemory.js';
43
- import type { CommitValuesMode, WriteProvenanceMode } from './types.js';
44
- /**
45
- * The two dials that shape a frame's bytes: the log's value encoding and the per-row read prefix.
46
- * Held by reference and swapped whole (`useEncoding`), never edited — the engine hands the run's
47
- * frozen policy itself. Absent: `'full'` values and no read prefix.
48
- */
49
- export interface RecordEncoding {
50
- readonly commitValues: CommitValuesMode;
51
- readonly writeProvenance: WriteProvenanceMode;
52
- }
53
- /**
54
- * What a stage can stage (law 7) — the transaction buffer's op verbs (`deltaEncoding.ts · OpVerb`), one
55
- * union. `append` is not one: it is how the log encodes a grown array (`'delta'`).
56
- */
57
- export type WriteVerb = OpVerb;
58
- /**
59
- * The bytes of a redaction verdict for one write (law 7): which of it the commit log and the redacted
60
- * mirror must not show. The engine decides it (`redaction.ts · decideWrite`); the frame only writes it.
61
- */
62
- export interface WriteScrub {
63
- /** The whole value: `LOG_PLACEHOLDER` at the write's path. */
64
- readonly whole?: boolean;
65
- /** Dot-paths INSIDE the value, relative to it: `LOG_PLACEHOLDER` at each one that holds a value. */
66
- readonly fields?: readonly string[];
67
- }
68
- export declare class RecordFrame {
69
- /** Live committed state — the heap every frame of the run shares. */
70
- readonly state: SharedMemory;
71
- /** The log the frame's commits land on, when the run keeps one. */
72
- readonly log?: EventLog;
73
- /** The redacted mirror the frame's commits land on, when the run keeps one ({@link useMirror}). */
74
- private _mirror?;
75
- /** Where the frame reads and writes (law 1). */
76
- private _address;
77
- /** The two dials (law 4, 5); absent → the record's defaults. */
78
- private encoding?;
79
- /**
80
- * The committed generation at the frame's FIRST touch (law 2) — held by REFERENCE, never cloned.
81
- * See {@link firstTouch} for the algorithm and the immutability invariant that makes a bare
82
- * reference safe.
83
- */
84
- private base?;
85
- /** The stage's staged writes — built at its first write (law 4), released at commit. */
86
- private buffer?;
87
- /**
88
- * Keys tracked-read so far, in order (law 5) — the source of each staged row's `readKeys`. Only
89
- * allocated under `'reads-prefix'`; insertion-ordered (a Set) and monotonic, which is what makes
90
- * "last write's prefix == union" hold in delta mode.
91
- */
92
- private readKeys?;
93
- constructor(state: SharedMemory, log?: EventLog, address?: readonly string[]);
94
- /** Where the frame reads and writes (law 1). */
95
- get address(): readonly string[];
96
- /**
97
- * Read and write at `address` from now on — before the frame's first write (law 1): the buffer keeps
98
- * the address it was built at. The engine's one caller, `StageContext · useAddressOf`, refuses a move
99
- * once the frame has staged.
100
- */
101
- useAddress(address: readonly string[]): void;
102
- /** The two dials the frame encodes under from its next buffer and its next read on (law 4, 5). */
103
- useEncoding(encoding: RecordEncoding): void;
104
- /** The redacted mirror, if the run keeps one. */
105
- get mirror(): SharedMemory | undefined;
106
- /** Land every commit from now on on `mirror` too, with the scrubbed rows the log takes (`recordCommit`). */
107
- useMirror(mirror: SharedMemory | undefined): void;
108
- /** The absolute path of `key` under `path`: the frame's address, then the path, then the key. */
109
- at(path: readonly string[], key: string): string[];
110
- /**
111
- * ── The first-touch base (#13) ───────────────────────────────────────────
112
- *
113
- * WHAT: returns the committed shared state as it was at this frame's FIRST touch (first read or
114
- * first write), capturing the reference on first call. Serves two consumers: reads before the first
115
- * write ({@link read}) and the transaction buffer's diff base ({@link getTransactionBuffer}).
116
- *
117
- * WHY A BARE REFERENCE IS SAFE — the invariant this rests on: committed state is
118
- * immutable-after-swap. Every write to `SharedMemory` builds the NEXT generation and swaps it in
119
- * (copy-on-write, 9.29.0: `applyPatch` via `nextGeneration`, and `setValue`/`updateValue` too) — it
120
- * copies the root and the containers on each written path, shares the rest, and never edits a
121
- * container of the generation a stage captured here. Holding the reference therefore gives this
122
- * stage a stable snapshot at zero cost — no clone, which is the entire point of #13. The transaction
123
- * buffer's net-change diff base rests on the same guarantee: it IS this view.
124
- *
125
- * WHY FIRST TOUCH, not first write: the pre-#13 eager engine cloned the state into the buffer at
126
- * the stage's first ACCESS, anchoring both its snapshot reads and its commit baseline (the
127
- * net-change diff base) there. #13's first cut anchored the lazy buffer at first WRITE — observably
128
- * different when something else commits in the gap between this stage's first read and its first
129
- * write. That gap is REACHABLE: fork siblings are namespace-isolated for run-scoped keys (each child
130
- * writes under `runs/<childId>/`), but ROOT-level keys are shared — written via `setGlobal` from
131
- * consumer scope code and, critically, by `SubflowInputMapper`'s output mapping
132
- * (`parentContext.setGlobal`), which is exactly what runs when a subflow is a fork branch. A
133
- * sibling's root-key commit landing in the gap would shift this stage's diff base, making its
134
- * CommitBundle record a phantom change (or swallow a real one) relative to the eager engine.
135
- * Anchoring the view at first touch restores the EXACT eager semantics — sequential AND parallel —
136
- * at zero clone cost.
137
- *
138
- * Read visibility is two-tier, matching eager byte-for-byte: keys present in the view at first
139
- * touch read repeatably from it; keys ABSENT from it fall back to LIVE state (the eager engine's
140
- * exact fallback — a mid-flight sibling root-key write was always visible to reads, and stays
141
- * visible; only the DIFF BASE is pinned).
142
- */
143
- private firstTouch;
144
- /**
145
- * The transaction buffer, created lazily on the frame's FIRST WRITE (#13).
146
- *
147
- * Reads NEVER construct it: read-your-writes only matters once a staged write exists, so before that
148
- * {@link read} serves from the first-touch base and {@link commit} records an empty bundle — all with
149
- * ZERO `structuredClone`s of the shared state.
150
- *
151
- * The buffer's base is the FIRST-TOUCH view, NOT the live state at write time: under parallel forks
152
- * a sibling may have committed between this frame's first read and this write, and the net-change
153
- * diff base must stay anchored at first touch to match the eager engine — see {@link firstTouch}.
154
- *
155
- * Private since C4: every write goes through {@link write}, so the scrub travels with the op.
156
- */
157
- private getTransactionBuffer;
158
- /**
159
- * Stage one write (law 7): `verb` at `path` — an absolute path, the address already joined
160
- * ({@link at}) — and the bytes of its redaction verdict. The first write builds the buffer (law 4).
161
- *
162
- * The scrub registers paths, never values: `whole` marks the op's own path, `fields` each field
163
- * inside the value (a literal key and, when dotted, the nested path); `recordCommit` puts the
164
- * log's placeholder wherever one of them holds a value at commit, for the mirror and the log only
165
- * (`scrub.ts`). Live state takes the value as it is. A path marked by a write that the net-change
166
- * filter drops goes with it.
167
- */
168
- write(path: (string | number)[], value: unknown, verb: WriteVerb, scrub?: WriteScrub): void;
169
- /** Has the frame staged a write since its last release — does its buffer exist? */
170
- get hasStaged(): boolean;
171
- /**
172
- * The frame's read, mirroring the eager engine's read order byte-for-byte (law 3):
173
- *
174
- * 1. staged writes + first-touch snapshot — `buffer.get` over its workingCopy when the buffer
175
- * exists, else `nativeGet` over the zero-clone first-touch base (the buffer's base IS that
176
- * view, so the two tiers agree on content);
177
- * 2. LIVE state via `SharedMemory · getValue` for keys absent from the snapshot — including its
178
- * address→root fallback. The eager engine had this exact live fallback for snapshot-missing
179
- * keys; byte-identity over purity. After the frame's first write such a value can be the very
180
- * container the buffer's diff base holds at the path (the stage deleted or unset it, or
181
- * replaced a container above it), so the base is detached there first
182
- * (`TransactionBuffer · detachBase`): an in-place edit of the value (out of contract) written
183
- * back is recorded, as on 9.28.0, whose base was a clone taken at the first write.
184
- *
185
- * Reads never construct the buffer (#13): a frame that never writes performs zero clones of the
186
- * shared state.
187
- */
188
- read(path: string[], key?: string): unknown;
189
- /** Put a tracked read's user-level key on the readKeys list (law 5) — a no-op unless the frame keeps one. */
190
- noteRead(path: readonly string[], key: string): void;
191
- /**
192
- * Live committed state at `key`: at the frame's address, else at the root — never the stage's own
193
- * view. Typed as `SharedMemory · getValue` types it, which `StageContext · getRoot` hands on.
194
- */
195
- readLive(key: string): any;
196
- /** Live committed state at `key` at the root — typed as `SharedMemory · getValue` (`StageContext · getGlobal`). */
197
- readGlobal(key: string): any;
198
- /** Did a staged op touch `path` — on it, above it or below it? (A report's question; never the hot path.) */
199
- wasStaged(path: (string | number)[]): boolean;
200
- /**
201
- * The value at `path` in what the stage has seen — its working copy once it wrote, else its
202
- * first-touch base — WITHOUT taking a private copy: for a report that only compares.
203
- */
204
- peek(path: (string | number)[]): unknown;
205
- /** The value at `path` in the first-touch base — committed state as the frame first touched it. */
206
- baseAt(path: (string | number)[]): unknown;
207
- /**
208
- * Record what the frame staged (law 6): the buffer's payload first — none, the empty commit, when
209
- * it staged nothing (#13: zero clones) — then the names (`stampOf()`), read once the payload is
210
- * built, and both to `recordCommit`. User code can run while the payload is built (a getter on a
211
- * staged value, which the net-change compare and the clone invoke); what it adds to the names —
212
- * an untracked read, say — is on the bundle.
213
- */
214
- commit(stampOf: () => CommitStamp): void;
215
- /**
216
- * End the frame's hold on state (#13b, law 6): drop the buffer (its working copy and whatever private
217
- * copies its reads took) and the first-touch base (a reference that pins one committed-state
218
- * GENERATION). Both re-create lazily: a later read re-anchors on the CURRENT committed state, and a
219
- * later write builds a fresh buffer on it — so a second commit diffs against the state after the
220
- * first. Without the release, the execution tree — which retains every frame for the lifetime of
221
- * the run — retains one state generation per executed stage (measured O(N²) before copy-on-write;
222
- * a 500-iteration agent OOMed a default Node heap, backlog #18).
223
- */
224
- release(): void;
225
- /**
226
- * Throw away everything the frame staged and read (law 6): the buffer, the first-touch base (the next
227
- * attempt re-anchors on committed state as it stands NOW) and the readKeys list — a discarded
228
- * attempt's reads must never reach the next attempt's `TraceEntry.readKeys`, or a backward slice
229
- * would follow an edge that no committed write ever had. Nothing is recorded.
230
- */
231
- discard(): void;
232
- }
@@ -1,46 +0,0 @@
1
- /**
2
- * SharedMemory — The shared state container for all flowchart execution
3
- *
4
- * Like a runtime heap with namespace isolation:
5
- * - A value is written at an ADDRESS — a path prefix the caller computed
6
- * (C2: the engine's frame decides it, `runAddress.ts · runAddress`) — and read
7
- * there first, then at the root
8
- * - Default values seed the root, and the container at an address when a
9
- * write creates it
10
- * - Accepts commit bundles from TransactionBuffer
11
- *
12
- * COPY-ON-WRITE (9.29.0 — docs/design/2026-10-copy-on-write-commit.md):
13
- * `context` is a GENERATION, and a generation is never edited. Every write —
14
- * `applyPatch` (a stage commit), `setValue`, `updateValue` — builds the next
15
- * generation by copying the root and the containers on each written path,
16
- * shares every other subtree with the generation before it, and swaps. So a
17
- * generation a stage captured (its first-touch view, its transaction
18
- * buffer's diff base) stays exactly what it was, and a write costs O(what it
19
- * wrote), not O(state).
20
- */
21
- import type { MemoryPatch, TraceEntry } from './types.js';
22
- export declare class SharedMemory {
23
- private context;
24
- private _defaultValues?;
25
- constructor(defaultValues?: unknown, initialContext?: unknown);
26
- /** Gets a clone of the default values. */
27
- getDefaultValues(): {} | undefined;
28
- /** Updates a value at `address` + `path` using merge semantics, as a new generation (path copy + swap). */
29
- updateValue(address: readonly string[], path: string[], key: string, value: unknown): void;
30
- /** Sets a value at `address` + `path` using overwrite semantics, as a new generation (path copy + swap). */
31
- setValue(address: readonly string[], path: string[], key: string, value: unknown): void;
32
- /**
33
- * A copy of the current generation's root whose containers on the way to
34
- * `key` are owned — the in-place helpers above then edit only copies.
35
- */
36
- private ownedPathTo;
37
- /**
38
- * Reads a value from the store.
39
- * Looks up at `address` first, falls back to the root.
40
- */
41
- getValue(address?: readonly string[], path?: string[], key?: string): any;
42
- /** Gets the entire state as a JSON object — the current generation, by reference. Never mutate it. */
43
- getState(): Record<string, unknown>;
44
- /** Applies a commit bundle from TransactionBuffer: builds the next generation and swaps it in. */
45
- applyPatch(overwrite: MemoryPatch, updates: MemoryPatch, trace: TraceEntry[]): void;
46
- }