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,136 +0,0 @@
1
- /**
2
- * bundles.ts — reading a log whose rows are not typed yet.
3
- *
4
- * WHY THIS FILE EXISTS. A LIVE snapshot hands time travel real
5
- * {@link CommitBundle}s. A STORED recording hands it parsed JSON, and a
6
- * careful consumer will not claim that what came back off disk is a
7
- * `CommitBundle` — so it either casts (a lie with a comment on it) or cannot
8
- * call the library at all. Since 9.18.0 the source takes `readonly unknown[]`
9
- * and the narrowing happens here, per row, at the one place that actually
10
- * reads one.
11
- *
12
- * A row that is not a bundle becomes a GAP rather than an exception: it KEEPS
13
- * ITS INDEX — so every `commitIdx` in the axis still addresses the same
14
- * position — contributes no state, gets no stop, and is reported with its
15
- * index and a reason. One corrupt row in a stored recording loses that row,
16
- * not the recording.
17
- */
18
- import { isVerb, VERBS } from '../memory/verbs.js';
19
- /**
20
- * The stand-in a gap leaves at its index: a commit that belongs to no stage
21
- * and carries nothing.
22
- *
23
- * It is NOT invented evidence — every field is the empty value, and an id-less
24
- * bundle is a shape the log already has (a root-context commit made before any
25
- * stage ran). `commitStops` gives it no stop for exactly that reason, the fold
26
- * folds nothing from it, and `changedSince` reads no keys off it. What it does
27
- * is hold the index, so the arithmetic downstream never has to know.
28
- */
29
- const GAP_BUNDLE = Object.freeze({
30
- stage: '',
31
- stageId: '',
32
- runtimeStageId: '',
33
- trace: Object.freeze([]),
34
- redactedPaths: Object.freeze([]),
35
- overwrite: Object.freeze({}),
36
- updates: Object.freeze({}),
37
- });
38
- /** A plain object — not null, not an array, not a primitive. */
39
- export function isPlainish(value) {
40
- return typeof value === 'object' && value !== null && !Array.isArray(value);
41
- }
42
- /**
43
- * Read a source's `executionTree` as an {@link ExecutionTree}, or as absent.
44
- *
45
- * The tree is only ever WALKED for mount ids (`subflowId` + `runtimeStageId`
46
- * on each node), so the honest narrowing a reader can do is "a plain object";
47
- * anything else — a stored field that came back as a string, a number, an
48
- * array — is read as no tree at all, which sends `commitStops` down the same
49
- * shape-heuristic path a log handed over without its tree already takes.
50
- */
51
- export function readTree(value) {
52
- return isPlainish(value) ? value : undefined;
53
- }
54
- /**
55
- * Why `row` cannot be read as a commit bundle, or `undefined` when it can.
56
- *
57
- * DELIBERATELY LENIENT — but exactly as lenient as the readers are. It checks
58
- * what the fold, the axis and `changedSince` actually touch:
59
- *
60
- * - `runtimeStageId` must be a string — the axis keys on it.
61
- * - `trace` must be an ARRAY, and it must be PRESENT. It is the one field
62
- * every reader WALKS (`applySmartMerge` iterates it verb by verb;
63
- * `changedSince` reads its paths), so a row without one is not a bundle the
64
- * fold can survive — it is the crash a gap exists to prevent. `CommitBundle`
65
- * declares it required, so no live log is affected.
66
- * - `updates` / `overwrite`, when present, must be plain objects. They are
67
- * read only AT THE PATHS THE TRACE NAMES, so an absent one is harmless and
68
- * is tolerated, exactly as the fold tolerates an absent `redactedPaths`.
69
- *
70
- * Being stricter than that — demanding `stage`, `stageId`, `idx` — would
71
- * reject hand-built logs that have folded correctly since 9.17.0, which is a
72
- * compatibility break dressed up as validation.
73
- */
74
- export function bundleRefusal(row) {
75
- if (!isPlainish(row)) {
76
- return `not an object (${row === null ? 'null' : Array.isArray(row) ? 'array' : typeof row})`;
77
- }
78
- if (typeof row.runtimeStageId !== 'string') {
79
- return `runtimeStageId is ${row.runtimeStageId === undefined ? 'missing' : `a ${typeof row.runtimeStageId}`}, not a string`;
80
- }
81
- if (!Array.isArray(row.trace)) {
82
- return `trace is ${row.trace === undefined ? 'missing' : `a ${typeof row.trace}`}, not an array`;
83
- }
84
- if (row.updates !== undefined && !isPlainish(row.updates))
85
- return 'updates is not a plain object';
86
- if (row.overwrite !== undefined && !isPlainish(row.overwrite))
87
- return 'overwrite is not a plain object';
88
- // The four verbs are the contract (9.27.0). The replay's switch used to
89
- // treat anything else as `merge` — a silent coercion of a row a foreign
90
- // producer got wrong; the readers now refuse it (`UnknownVerbError`), and
91
- // this reader turns the same refusal into a gap that says which row.
92
- for (let i = 0; i < row.trace.length; i++) {
93
- const entry = row.trace[i];
94
- const verb = isPlainish(entry) ? entry.verb : undefined;
95
- if (!isVerb(verb)) {
96
- return `trace[${i}].verb is ${verb === undefined ? 'missing' : JSON.stringify(verb)}, not ${VERBS.join(' | ')}`;
97
- }
98
- }
99
- return undefined;
100
- }
101
- /** `true` when `row` can be read as a {@link CommitBundle}. */
102
- export function isCommitBundle(row) {
103
- return bundleRefusal(row) === undefined;
104
- }
105
- /** Nothing to read — shared, so the clean path allocates nothing extra. */
106
- const NO_GAPS = Object.freeze([]);
107
- /**
108
- * Read an unvalidated array as a commit log.
109
- *
110
- * The clean case (a live snapshot, or a stored recording that round-tripped
111
- * intact) returns the SAME array reference and no gaps: nothing is copied,
112
- * nothing is allocated, and the fold behaves byte for byte as it did in
113
- * 9.17.0. Only a log with a refused row is rebuilt, and only to keep the
114
- * indices aligned.
115
- *
116
- * @example
117
- * ```typescript
118
- * const { log, gaps } = readLog(JSON.parse(stored).commitLog);
119
- * gaps; // [{ index: 3, reason: 'not an object (null)' }]
120
- * ```
121
- */
122
- export function readLog(raw) {
123
- if (!raw || raw.length === 0)
124
- return { log: [], gaps: NO_GAPS };
125
- let gaps;
126
- for (let i = 0; i < raw.length; i++) {
127
- const reason = bundleRefusal(raw[i]);
128
- if (reason !== undefined)
129
- (gaps ??= []).push({ index: i, reason });
130
- }
131
- if (!gaps)
132
- return { log: raw, gaps: NO_GAPS };
133
- const log = raw.map((row) => (isCommitBundle(row) ? row : GAP_BUNDLE));
134
- return { log, gaps: Object.freeze(gaps) };
135
- }
136
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdGltZS10cmF2ZWwvYnVuZGxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUdILE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHbkQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLEdBQWlCLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDN0MsS0FBSyxFQUFFLEVBQUU7SUFDVCxPQUFPLEVBQUUsRUFBRTtJQUNYLGNBQWMsRUFBRSxFQUFFO0lBQ2xCLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBcUM7SUFDNUQsYUFBYSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUF3QjtJQUN2RCxTQUFTLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDNUIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0NBQzNCLENBQUMsQ0FBQztBQUVILGdFQUFnRTtBQUNoRSxNQUFNLFVBQVUsVUFBVSxDQUFDLEtBQWM7SUFDdkMsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxLQUFjO0lBQ3JDLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBRSxLQUFrQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDN0UsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxHQUFZO0lBQ3hDLElBQUksQ0FBQyxVQUFVLENBQUMs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QyxDQUFDO1FBQ3JDLElBQUksTUFBTSxLQUFLLFNBQVM7WUFBRSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUNELElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUE4QixFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUV6RSxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBidW5kbGVzLnRzIOKAlCByZWFkaW5nIGEgbG9nIHdob3NlIHJvd3MgYXJlIG5vdCB0eXBlZCB5ZXQuXG4gKlxuICogV0hZIFRISVMgRklMRSBFWElTVFMuIEEgTElWRSBzbmFwc2hvdCBoYW5kcyB0aW1lIHRyYXZlbCByZWFsXG4gKiB7QGxpbmsgQ29tbWl0QnVuZGxlfXMuIEEgU1RPUkVEIHJlY29yZGluZyBoYW5kcyBpdCBwYXJzZWQgSlNPTiwgYW5kIGFcbiAqIGNhcmVmdWwgY29uc3VtZXIgd2lsbCBub3QgY2xhaW0gdGhhdCB3aGF0IGNhbWUgYmFjayBvZmYgZGlzayBpcyBhXG4gKiBgQ29tbWl0QnVuZGxlYCDigJQgc28gaXQgZWl0aGVyIGNhc3RzIChhIGxpZSB3aXRoIGEgY29tbWVudCBvbiBpdCkgb3IgY2Fubm90XG4gKiBjYWxsIHRoZSBsaWJyYXJ5IGF0IGFsbC4gU2luY2UgOS4xOC4wIHRoZSBzb3VyY2UgdGFrZXMgYHJlYWRvbmx5IHVua25vd25bXWBcbiAqIGFuZCB0aGUgbmFycm93aW5nIGhhcHBlbnMgaGVyZSwgcGVyIHJvdywgYXQgdGhlIG9uZSBwbGFjZSB0aGF0IGFjdHVhbGx5XG4gKiByZWFkcyBvbmUuXG4gKlxuICogQSByb3cgdGhhdCBpcyBub3QgYSBidW5kbGUgYmVjb21lcyBhIEdBUCByYXRoZXIgdGhhbiBhbiBleGNlcHRpb246IGl0IEtFRVBTXG4gKiBJVFMgSU5ERVgg4oCUIHNvIGV2ZXJ5IGBjb21taXRJZHhgIGluIHRoZSBheGlzIHN0aWxsIGFkZHJlc3NlcyB0aGUgc2FtZVxuICogcG9zaXRpb24g4oCUIGNvbnRyaWJ1dGVzIG5vIHN0YXRlLCBnZXRzIG5vIHN0b3AsIGFuZCBpcyByZXBvcnRlZCB3aXRoIGl0c1xuICogaW5kZXggYW5kIGEgcmVhc29uLiBPbmUgY29ycnVwdCByb3cgaW4gYSBzdG9yZWQgcmVjb3JkaW5nIGxvc2VzIHRoYXQgcm93LFxuICogbm90IHRoZSByZWNvcmRpbmcuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBDb21taXRCdW5kbGUsIEV4ZWN1dGlvblRyZWUgfSBmcm9tICcuLi9tZW1vcnkvdHlwZXMuanMnO1xuaW1wb3J0IHsgaXNWZXJiLCBWRVJCUyB9IGZyb20gJy4uL21lbW9yeS92ZXJicy5qcyc7XG5pbXBvcnQgdHlwZSB7IExvZ0dhcCB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKipcbiAqIFRoZSBzdGFuZC1pbiBhIGdhcCBsZWF2ZXMgYXQgaXRzIGluZGV4OiBhIGNvbW1pdCB0aGF0IGJlbG9uZ3MgdG8gbm8gc3RhZ2VcbiAqIGFuZCBjYXJyaWVzIG5vdGhpbmcuXG4gKlxuICogSXQgaXMgTk9UIGludmVudGVkIGV2aWRlbmNlIOKAlCBldmVyeSBmaWVsZCBpcyB0aGUgZW1wdHkgdmFsdWUsIGFuZCBhbiBpZC1sZXNzXG4gKiBidW5kbGUgaXMgYSBzaGFwZSB0aGUgbG9nIGFscmVhZHkgaGFzIChhIHJvb3QtY29udGV4dCBjb21taXQgbWFkZSBiZWZvcmUgYW55XG4gKiBzdGFnZSByYW4pLiBgY29tbWl0U3RvcHNgIGdpdmVzIGl0IG5vIHN0b3AgZm9yIGV4YWN0bHkgdGhhdCByZWFzb24sIHRoZSBmb2xkXG4gKiBmb2xkcyBub3RoaW5nIGZyb20gaXQsIGFuZCBgY2hhbmdlZFNpbmNlYCByZWFkcyBubyBrZXlzIG9mZiBpdC4gV2hhdCBpdCBkb2VzXG4gKiBpcyBob2xkIHRoZSBpbmRleCwgc28gdGhlIGFyaXRobWV0aWMgZG93bnN0cmVhbSBuZXZlciBoYXMgdG8ga25vdy5cbiAqL1xuY29uc3QgR0FQX0JVTkRMRTogQ29tbWl0QnVuZGxlID0gT2JqZWN0LmZyZWV6ZSh7XG4gIHN0YWdlOiAnJyxcbiAgc3RhZ2VJZDogJycsXG4gIHJ1bnRpbWVTdGFnZUlkOiAnJyxcbiAgdHJhY2U6IE9iamVjdC5mcmVlemUoW10pIGFzIHVua25vd24gYXMgQ29tbWl0QnVuZGxlWyd0cmFjZSddLFxuICByZWRhY3RlZFBhdGhzOiBPYmplY3QuZnJlZXplKFtdKSBhcyB1bmtub3duIGFzIHN0cmluZ1tdLFxuICBvdmVyd3JpdGU6IE9iamVjdC5mcmVlemUoe30pLFxuICB1cGRhdGVzOiBPYmplY3QuZnJlZXplKHt9KSxcbn0pO1xuXG4vKiogQSBwbGFpbiBvYmplY3Qg4oCUIG5vdCBudWxsLCBub3QgYW4gYXJyYXksIG5vdCBhIHByaW1pdGl2ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1BsYWluaXNoKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbi8qKlxuICogUmVhZCBhIHNvdXJjZSdzIGBleGVjdXRpb25UcmVlYCBhcyBhbiB7QGxpbmsgRXhlY3V0aW9uVHJlZX0sIG9yIGFzIGFic2VudC5cbiAqXG4gKiBUaGUgdHJlZSBpcyBvbmx5IGV2ZXIgV0FMS0VEIGZvciBtb3VudCBpZHMgKGBzdWJmbG93SWRgICsgYHJ1bnRpbWVTdGFnZUlkYFxuICogb24gZWFjaCBub2RlKSwgc28gdGhlIGhvbmVzdCBuYXJyb3dpbmcgYSByZWFkZXIgY2FuIGRvIGlzIFwiYSBwbGFpbiBvYmplY3RcIjtcbiAqIGFueXRoaW5nIGVsc2Ug4oCUIGEgc3RvcmVkIGZpZWxkIHRoYXQgY2FtZSBiYWNrIGFzIGEgc3RyaW5nLCBhIG51bWJlciwgYW5cbiAqIGFycmF5IOKAlCBpcyByZWFkIGFzIG5vIHRyZWUgYXQgYWxsLCB3aGljaCBzZW5kcyBgY29tbWl0U3RvcHNgIGRvd24gdGhlIHNhbWVcbiAqIHNoYXBlLWhldXJpc3RpYyBwYXRoIGEgbG9nIGhhbmRlZCBvdmVyIHdpdGhvdXQgaXRzIHRyZWUgYWxyZWFkeSB0YWtlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRUcmVlKHZhbHVlOiB1bmtub3duKTogRXhlY3V0aW9uVHJlZSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBpc1BsYWluaXNoKHZhbHVlKSA/ICh2YWx1ZSBhcyB1bmtub3duIGFzIEV4ZWN1dGlvblRyZWUpIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFdoeSBgcm93YCBjYW5ub3QgYmUgcmVhZCBhcyBhIGNvbW1pdCBidW5kbGUsIG9yIGB1bmRlZmluZWRgIHdoZW4gaXQgY2FuLlxuICpcbiAqIERFTElCRVJBVEVMWSBMRU5JRU5UIOKAlCBidXQgZXhhY3RseSBhcyBsZW5pZW50IGFzIHRoZSByZWFkZXJzIGFyZS4gSXQgY2hlY2tzXG4gKiB3aGF0IHRoZSBmb2xkLCB0aGUgYXhpcyBhbmQgYGNoYW5nZWRTaW5jZWAgYWN0dWFsbHkgdG91Y2g6XG4gKlxuICogLSBgcnVudGltZVN0YWdlSWRgIG11c3QgYmUgYSBzdHJpbmcg4oCUIHRoZSBheGlzIGtleXMgb24gaXQuXG4gKiAtIGB0cmFjZWAgbXVzdCBiZSBhbiBBUlJBWSwgYW5kIGl0IG11c3QgYmUgUFJFU0VOVC4gSXQgaXMgdGhlIG9uZSBmaWVsZFxuICogICBldmVyeSByZWFkZXIgV0FMS1MgKGBhcHBseVNtYXJ0TWVyZ2VgIGl0ZXJhdGVzIGl0IHZlcmIgYnkgdmVyYjtcbiAqICAgYGNoYW5nZWRTaW5jZWAgcmVhZHMgaXRzIHBhdGhzKSwgc28gYSByb3cgd2l0aG91dCBvbmUgaXMgbm90IGEgYnVuZGxlIHRoZVxuICogICBmb2xkIGNhbiBzdXJ2aXZlIOKAlCBpdCBpcyB0aGUgY3Jhc2ggYSBnYXAgZXhpc3RzIHRvIHByZXZlbnQuIGBDb21taXRCdW5kbGVgXG4gKiAgIGRlY2xhcmVzIGl0IHJlcXVpcmVkLCBzbyBubyBsaXZlIGxvZyBpcyBhZmZlY3RlZC5cbiAqIC0gYHVwZGF0ZXNgIC8gYG92ZXJ3cml0ZWAsIHdoZW4gcHJlc2VudCwgbXVzdCBiZSBwbGFpbiBvYmplY3RzLiBUaGV5IGFyZVxuICogICByZWFkIG9ubHkgQVQgVEhFIFBBVEhTIFRIRSBUUkFDRSBOQU1FUywgc28gYW4gYWJzZW50IG9uZSBpcyBoYXJtbGVzcyBhbmRcbiAqICAgaXMgdG9sZXJhdGVkLCBleGFjdGx5IGFzIHRoZSBmb2xkIHRvbGVyYXRlcyBhbiBhYnNlbnQgYHJlZGFjdGVkUGF0aHNgLlxuICpcbiAqIEJlaW5nIHN0cmljdGVyIHRoYW4gdGhhdCDigJQgZGVtYW5kaW5nIGBzdGFnZWAsIGBzdGFnZUlkYCwgYGlkeGAg4oCUIHdvdWxkXG4gKiByZWplY3QgaGFuZC1idWlsdCBsb2dzIHRoYXQgaGF2ZSBmb2xkZWQgY29ycmVjdGx5IHNpbmNlIDkuMTcuMCwgd2hpY2ggaXMgYVxuICogY29tcGF0aWJpbGl0eSBicmVhayBkcmVzc2VkIHVwIGFzIHZhbGlkYXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidW5kbGVSZWZ1c2FsKHJvdzogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaXNQbGFpbmlzaChyb3cpKSB7XG4gICAgcmV0dXJuIGBub3QgYW4gb2JqZWN0ICgke3JvdyA9PT0gbnVsbCA/ICdudWxsJyA6IEFycmF5LmlzQXJyYXkocm93KSA/ICdhcnJheScgOiB0eXBlb2Ygcm93fSlgO1xuICB9XG4gIGlmICh0eXBlb2Ygcm93LnJ1bnRpbWVTdGFnZUlkICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBgcnVudGltZVN0YWdlSWQgaXMgJHtcbiAgICAgIHJvdy5ydW50aW1lU3RhZ2VJZCA9PT0gdW5kZWZpbmVkID8gJ21pc3NpbmcnIDogYGEgJHt0eXBlb2Ygcm93LnJ1bnRpbWVTdGFnZUlkfWBcbiAgICB9LCBub3QgYSBzdHJpbmdgO1xuICB9XG4gIGlmICghQXJyYXkuaXNBcnJheShyb3cudHJhY2UpKSB7XG4gICAgcmV0dXJuIGB0cmFjZSBpcyAke3Jvdy50cmFjZSA9PT0gdW5kZWZpbmVkID8gJ21pc3NpbmcnIDogYGEgJHt0eXBlb2Ygcm93LnRyYWNlfWB9LCBub3QgYW4gYXJyYXlgO1xuICB9XG4gIGlmIChyb3cudXBkYXRlcyAhPT0gdW5kZWZpbmVkICYmICFpc1BsYWluaXNoKHJvdy51cGRhdGVzKSkgcmV0dXJuICd1cGRhdGVzIGlzIG5vdCBhIHBsYWluIG9iamVjdCc7XG4gIGlmIChyb3cub3ZlcndyaXRlICE9PSB1bmRlZmluZWQgJiYgIWlzUGxhaW5pc2gocm93Lm92ZXJ3cml0ZSkpIHJldHVybiAnb3ZlcndyaXRlIGlzIG5vdCBhIHBsYWluIG9iamVjdCc7XG4gIC8vIFRoZSBmb3VyIHZlcmJzIGFyZSB0aGUgY29udHJhY3QgKDkuMjcuMCkuIFRoZSByZXBsYXkncyBzd2l0Y2ggdXNlZCB0b1xuICAvLyB0cmVhdCBhbnl0aGluZyBlbHNlIGFzIGBtZXJnZWAg4oCUIGEgc2lsZW50IGNvZXJjaW9uIG9mIGEgcm93IGEgZm9yZWlnblxuICAvLyBwcm9kdWNlciBnb3Qgd3Jvbmc7IHRoZSByZWFkZXJzIG5vdyByZWZ1c2UgaXQgKGBVbmtub3duVmVyYkVycm9yYCksIGFuZFxuICAvLyB0aGlzIHJlYWRlciB0dXJucyB0aGUgc2FtZSByZWZ1c2FsIGludG8gYSBnYXAgdGhhdCBzYXlzIHdoaWNoIHJvdy5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3cudHJhY2UubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBlbnRyeTogdW5rbm93biA9IHJvdy50cmFjZVtpXTtcbiAgICBjb25zdCB2ZXJiID0gaXNQbGFpbmlzaChlbnRyeSkgPyBlbnRyeS52ZXJiIDogdW5kZWZpbmVkO1xuICAgIGlmICghaXNWZXJiKHZlcmIpKSB7XG4gICAgICByZXR1cm4gYHRyYWNlWyR7aX1dLnZlcmIgaXMgJHt2ZXJiID09PSB1bmRlZmluZWQgPyAnbWlzc2luZycgOiBKU09OLnN0cmluZ2lmeSh2ZXJiKX0sIG5vdCAke1ZFUkJTLmpvaW4oJyB8ICcpfWA7XG4gICAgfVxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBgdHJ1ZWAgd2hlbiBgcm93YCBjYW4gYmUgcmVhZCBhcyBhIHtAbGluayBDb21taXRCdW5kbGV9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29tbWl0QnVuZGxlKHJvdzogdW5rbm93bik6IHJvdyBpcyBDb21taXRCdW5kbGUge1xuICByZXR1cm4gYnVuZGxlUmVmdXNhbChyb3cpID09PSB1bmRlZmluZWQ7XG59XG5cbi8qKiBBIGxvZyByZWFkIHJvdyBieSByb3c6IHRoZSBidW5kbGVzLCBpbmRleC1hbGlnbmVkLCBwbHVzIHdoYXQgd2FzIHJlZnVzZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlYWRMb2cge1xuICAvKiogU2FtZSBsZW5ndGggYW5kIG9yZGVyIGFzIHRoZSBpbnB1dDsgYSByZWZ1c2VkIHJvdyBob2xkcyBhIEdBUCBzdGFuZC1pbi4gKi9cbiAgcmVhZG9ubHkgbG9nOiByZWFkb25seSBDb21taXRCdW5kbGVbXTtcbiAgLyoqIFRoZSByZWZ1c2VkIHJvd3MsIGluIGluZGV4IG9yZGVyLiBFbXB0eSB3aGVuIHRoZSBsb2cgd2FzIGNsZWFuLiAqL1xuICByZWFkb25seSBnYXBzOiByZWFkb25seSBMb2dHYXBbXTtcbn1cblxuLyoqIE5vdGhpbmcgdG8gcmVhZCDigJQgc2hhcmVkLCBzbyB0aGUgY2xlYW4gcGF0aCBhbGxvY2F0ZXMgbm90aGluZyBleHRyYS4gKi9cbmNvbnN0IE5PX0dBUFM6IHJlYWRvbmx5IExvZ0dhcFtdID0gT2JqZWN0LmZyZWV6ZShbXSk7XG5cbi8qKlxuICogUmVhZCBhbiB1bnZhbGlkYXRlZCBhcnJheSBhcyBhIGNvbW1pdCBsb2cuXG4gKlxuICogVGhlIGNsZWFuIGNhc2UgKGEgbGl2ZSBzbmFwc2hvdCwgb3IgYSBzdG9yZWQgcmVjb3JkaW5nIHRoYXQgcm91bmQtdHJpcHBlZFxuICogaW50YWN0KSByZXR1cm5zIHRoZSBTQU1FIGFycmF5IHJlZmVyZW5jZSBhbmQgbm8gZ2Fwczogbm90aGluZyBpcyBjb3BpZWQsXG4gKiBub3RoaW5nIGlzIGFsbG9jYXRlZCwgYW5kIHRoZSBmb2xkIGJlaGF2ZXMgYnl0ZSBmb3IgYnl0ZSBhcyBpdCBkaWQgaW5cbiAqIDkuMTcuMC4gT25seSBhIGxvZyB3aXRoIGEgcmVmdXNlZCByb3cgaXMgcmVidWlsdCwgYW5kIG9ubHkgdG8ga2VlcCB0aGVcbiAqIGluZGljZXMgYWxpZ25lZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgeyBsb2csIGdhcHMgfSA9IHJlYWRMb2coSlNPTi5wYXJzZShzdG9yZWQpLmNvbW1pdExvZyk7XG4gKiBnYXBzOyAvLyBbeyBpbmRleDogMywgcmVhc29uOiAnbm90IGFuIG9iamVjdCAobnVsbCknIH1dXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRMb2cocmF3OiByZWFkb25seSB1bmtub3duW10gfCB1bmRlZmluZWQpOiBSZWFkTG9nIHtcbiAgaWYgKCFyYXcgfHwgcmF3Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgbG9nOiBbXSwgZ2FwczogTk9fR0FQUyB9O1xuXG4gIGxldCBnYXBzOiBMb2dHYXBbXSB8IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXcubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCByZWFzb24gPSBidW5kbGVSZWZ1c2FsKHJhd1tpXSk7XG4gICAgaWYgKHJlYXNvbiAhPT0gdW5kZWZpbmVkKSAoZ2FwcyA/Pz0gW10pLnB1c2goeyBpbmRleDogaSwgcmVhc29uIH0pO1xuICB9XG4gIGlmICghZ2FwcykgcmV0dXJuIHsgbG9nOiByYXcgYXMgcmVhZG9ubHkgQ29tbWl0QnVuZGxlW10sIGdhcHM6IE5PX0dBUFMgfTtcblxuICBjb25zdCBsb2cgPSByYXcubWFwKChyb3cpID0+IChpc0NvbW1pdEJ1bmRsZShyb3cpID8gcm93IDogR0FQX0JVTkRMRSkpO1xuICByZXR1cm4geyBsb2csIGdhcHM6IE9iamVjdC5mcmVlemUoZ2FwcykgfTtcbn1cbiJdfQ==
@@ -1,93 +0,0 @@
1
- /**
2
- * chain.ts — reading a pause/resume as ONE axis.
3
- *
4
- * WHY THIS FILE EXISTS. A pause and its resume produce TWO snapshots. On a
5
- * cross-executor resume (the checkpoint was persisted and a fresh executor
6
- * picked it up) the second run gets a fresh runtime: its `commitLog` starts at
7
- * index 0 and holds only the post-resume commits, and its `initialState` is
8
- * the state at the pause. Two logs, two disjoint axes — so a reader scrubbing
9
- * a resumed run saw only the second half unless the application had kept the
10
- * paused snapshot and stitched the halves itself. Every application that
11
- * pauses would write that stitching, and none of them own the arithmetic.
12
- *
13
- * THE HONEST BIT, up front: COMMIT INDICES ARE RUN-LOCAL. There is no global
14
- * index across a chain and this file does not invent one — `commitIdx` and
15
- * `lastCommitIdx` keep indexing their own source, and every stop carries the
16
- * {@link Stop.sourceIdx} they belong to. The cursor's STEPS are what run
17
- * across the whole chain.
18
- *
19
- * AND THE REFUSAL: a chain that is not ordered, or whose legs are not from one
20
- * lineage, is REFUSED rather than guessed at. The record carries TWO signals
21
- * and this file reads both:
22
- *
23
- * - The execution index the engine stamps into every `runtimeStageId` —
24
- * globally monotonic per run and, deliberately, NOT reset on resume. So a
25
- * later leg's first execution index must be past the earlier leg's last, and
26
- * no stage may appear in two legs. This catches a backwards chain, a fresh
27
- * run (which restarts at 0) and a same-executor resume (whose one snapshot
28
- * already holds both halves).
29
- * - The later leg's `initialState`. On a resume the fresh runtime is seeded
30
- * from the checkpoint, so that base IS the state at the pause — and the
31
- * state the earlier legs FOLD TO must deep-equal it. This is what catches a
32
- * leg from some OTHER lineage whose indices merely happen to be higher: the
33
- * counters line up by accident, the state never does.
34
- *
35
- * A chart identity or a lineage id is NOT on the record, so nothing here
36
- * pretends to check one. And where the state signal is not on the record
37
- * either — a leg recorded before 9.17 carries no `initialState`; an earlier
38
- * leg with no base folds `'log-only'`; a leg with unreadable rows folds an
39
- * incomplete state — that check is SKIPPED, not faked: the chain then rests on
40
- * the index checks alone, and every fold's `basis` still says what it stood
41
- * on. That degradation is documented on `refuseChain`, on `timeTravel`'s
42
- * `@throws`, and in the README.
43
- */
44
- import type { CommitBundle } from '../memory/types.js';
45
- import { type ReadSource } from './stateAt.js';
46
- import type { TimeTravelSource } from './types.js';
47
- /** One leg of a chain: a source, its read log, and where it sits in the run. */
48
- export interface ChainLeg {
49
- readonly source: TimeTravelSource;
50
- readonly log: readonly CommitBundle[];
51
- /** Lowest execution index stamped in this leg; `undefined` for an id-less log. */
52
- readonly firstExecutionIndex: number | undefined;
53
- /** Highest execution index stamped in this leg. */
54
- readonly lastExecutionIndex: number | undefined;
55
- }
56
- /** The execution-index span of one leg, read off its `runtimeStageId`s. */
57
- export declare function spanOf(log: readonly CommitBundle[]): {
58
- first: number | undefined;
59
- last: number | undefined;
60
- ids: Set<string>;
61
- };
62
- /**
63
- * Check that `legs` really are one run read in order, and say why not.
64
- *
65
- * Returns the refusal message, or `undefined` when the chain is sound. Three
66
- * distinct failures, because they are three different mistakes, checked in
67
- * this order:
68
- *
69
- * - REPEATED STAGE — one `runtimeStageId` appears in two legs. Ids are unique
70
- * within a run, so a repeat means the same execution was recorded twice: a
71
- * same-executor resume, whose snapshot ALREADY holds the whole log and needs
72
- * no chaining, is the usual cause.
73
- * - OUT OF ORDER — a later leg's first execution index is not past the earlier
74
- * leg's last. Either the sources were handed over backwards, or the second
75
- * is not a continuation at all (a fresh run restarts the counter at 0, so an
76
- * unrelated snapshot fails here rather than silently interleaving).
77
- * - WRONG LINEAGE — leg k's `initialState` is not the state legs 0..k-1 fold
78
- * to. On a resume the later leg is seeded from the checkpoint, so its base
79
- * IS the state at the pause; a leg that begins anywhere else is from some
80
- * other run, however its indices happen to line up.
81
- *
82
- * THE LINEAGE CHECK RUNS ONLY WHERE THE RECORD ALLOWS IT, and is skipped —
83
- * never faked — otherwise: leg k must carry an `initialState` (a recording
84
- * made before 9.17 has none), and the fold of the legs before it must stand on
85
- * a real base (`basis: 'initial+log'`) with no unreadable rows (`skipped`
86
- * absent) — a log-only or gapped fold is not a state a real base may be held
87
- * against. On such a chain the two index checks are the whole defence, and
88
- * `foldLegs`' leg rule then CONTINUES the fold across the seam, which is the
89
- * right state for a real resume and is what `basis` reports. Paths the log
90
- * was redacted at are excluded from the comparison: the fold holds
91
- * `'REDACTED'` there and the checkpoint holds the value.
92
- */
93
- export declare function refuseChain(legs: readonly ReadSource[]): string | undefined;
@@ -1,188 +0,0 @@
1
- /**
2
- * chain.ts — reading a pause/resume as ONE axis.
3
- *
4
- * WHY THIS FILE EXISTS. A pause and its resume produce TWO snapshots. On a
5
- * cross-executor resume (the checkpoint was persisted and a fresh executor
6
- * picked it up) the second run gets a fresh runtime: its `commitLog` starts at
7
- * index 0 and holds only the post-resume commits, and its `initialState` is
8
- * the state at the pause. Two logs, two disjoint axes — so a reader scrubbing
9
- * a resumed run saw only the second half unless the application had kept the
10
- * paused snapshot and stitched the halves itself. Every application that
11
- * pauses would write that stitching, and none of them own the arithmetic.
12
- *
13
- * THE HONEST BIT, up front: COMMIT INDICES ARE RUN-LOCAL. There is no global
14
- * index across a chain and this file does not invent one — `commitIdx` and
15
- * `lastCommitIdx` keep indexing their own source, and every stop carries the
16
- * {@link Stop.sourceIdx} they belong to. The cursor's STEPS are what run
17
- * across the whole chain.
18
- *
19
- * AND THE REFUSAL: a chain that is not ordered, or whose legs are not from one
20
- * lineage, is REFUSED rather than guessed at. The record carries TWO signals
21
- * and this file reads both:
22
- *
23
- * - The execution index the engine stamps into every `runtimeStageId` —
24
- * globally monotonic per run and, deliberately, NOT reset on resume. So a
25
- * later leg's first execution index must be past the earlier leg's last, and
26
- * no stage may appear in two legs. This catches a backwards chain, a fresh
27
- * run (which restarts at 0) and a same-executor resume (whose one snapshot
28
- * already holds both halves).
29
- * - The later leg's `initialState`. On a resume the fresh runtime is seeded
30
- * from the checkpoint, so that base IS the state at the pause — and the
31
- * state the earlier legs FOLD TO must deep-equal it. This is what catches a
32
- * leg from some OTHER lineage whose indices merely happen to be higher: the
33
- * counters line up by accident, the state never does.
34
- *
35
- * A chart identity or a lineage id is NOT on the record, so nothing here
36
- * pretends to check one. And where the state signal is not on the record
37
- * either — a leg recorded before 9.17 carries no `initialState`; an earlier
38
- * leg with no base folds `'log-only'`; a leg with unreadable rows folds an
39
- * incomplete state — that check is SKIPPED, not faked: the chain then rests on
40
- * the index checks alone, and every fold's `basis` still says what it stood
41
- * on. That degradation is documented on `refuseChain`, on `timeTravel`'s
42
- * `@throws`, and in the README.
43
- */
44
- import { kindOf } from '../capture/valueKinds.js';
45
- import { parseRuntimeStageId } from '../ids/runtimeStageId.js';
46
- import { deepEqual, DELIM } from '../memory/utils.js';
47
- import { foldLegs } from './stateAt.js';
48
- /** The execution-index span of one leg, read off its `runtimeStageId`s. */
49
- export function spanOf(log) {
50
- let first;
51
- let last;
52
- const ids = new Set();
53
- for (const bundle of log) {
54
- const id = bundle.runtimeStageId;
55
- if (!id)
56
- continue;
57
- ids.add(id);
58
- const { executionIndex } = parseRuntimeStageId(id);
59
- if (Number.isNaN(executionIndex))
60
- continue;
61
- if (first === undefined || executionIndex < first)
62
- first = executionIndex;
63
- if (last === undefined || executionIndex > last)
64
- last = executionIndex;
65
- }
66
- return { first, last, ids };
67
- }
68
- /**
69
- * Structural equality of two folded states, ignoring the paths the log was
70
- * redacted at.
71
- *
72
- * The fold reproduces `'REDACTED'` wherever the engine scrubbed a write, while
73
- * the checkpoint that seeded the resumed leg holds the real value — so those
74
- * paths CANNOT agree, and are not asked to. Everything else is decided by the
75
- * ONE equality law (`memory/equality.ts · deepEqual`, every value kind compared
76
- * as the record holds it; 9.44.2 — this walk had a law of its own, which held
77
- * any two RegExps, Errors or buffers equal). Both sides are copies of one
78
- * record, so an opaque value compares as `'copies'`. Only the containers above
79
- * a redacted path are walked here.
80
- */
81
- function sameState(a, b, redacted, path) {
82
- if (!redactedBelow(path, redacted))
83
- return deepEqual(a, b, 'copies');
84
- if (Array.isArray(a) && Array.isArray(b)) {
85
- if (a.length !== b.length)
86
- return false;
87
- return a.every((item, i) => sameState(item, b[i], redacted, path === '' ? String(i) : `${path}${DELIM}${i}`));
88
- }
89
- const plain = (v) => v !== null && typeof v === 'object' && !Array.isArray(v) && kindOf(v) === 'plain';
90
- if (!plain(a) || !plain(b))
91
- return deepEqual(a, b, 'copies');
92
- const present = (o) => Object.keys(o).filter((k) => o[k] !== undefined);
93
- const leftKeys = present(a);
94
- const rightKeys = new Set(present(b));
95
- if (leftKeys.length !== rightKeys.size || !leftKeys.every((k) => rightKeys.has(k)))
96
- return false;
97
- return leftKeys.every((k) => {
98
- const childPath = path === '' ? k : `${path}${DELIM}${k}`;
99
- return redacted.has(childPath) || sameState(a[k], b[k], redacted, childPath);
100
- });
101
- }
102
- /** Is `path`, or a path below it, one the log was redacted at? */
103
- function redactedBelow(path, redacted) {
104
- if (redacted.size === 0)
105
- return false;
106
- if (path === '')
107
- return true;
108
- for (const r of redacted)
109
- if (r === path || r.startsWith(`${path}${DELIM}`))
110
- return true;
111
- return false;
112
- }
113
- /**
114
- * Check that `legs` really are one run read in order, and say why not.
115
- *
116
- * Returns the refusal message, or `undefined` when the chain is sound. Three
117
- * distinct failures, because they are three different mistakes, checked in
118
- * this order:
119
- *
120
- * - REPEATED STAGE — one `runtimeStageId` appears in two legs. Ids are unique
121
- * within a run, so a repeat means the same execution was recorded twice: a
122
- * same-executor resume, whose snapshot ALREADY holds the whole log and needs
123
- * no chaining, is the usual cause.
124
- * - OUT OF ORDER — a later leg's first execution index is not past the earlier
125
- * leg's last. Either the sources were handed over backwards, or the second
126
- * is not a continuation at all (a fresh run restarts the counter at 0, so an
127
- * unrelated snapshot fails here rather than silently interleaving).
128
- * - WRONG LINEAGE — leg k's `initialState` is not the state legs 0..k-1 fold
129
- * to. On a resume the later leg is seeded from the checkpoint, so its base
130
- * IS the state at the pause; a leg that begins anywhere else is from some
131
- * other run, however its indices happen to line up.
132
- *
133
- * THE LINEAGE CHECK RUNS ONLY WHERE THE RECORD ALLOWS IT, and is skipped —
134
- * never faked — otherwise: leg k must carry an `initialState` (a recording
135
- * made before 9.17 has none), and the fold of the legs before it must stand on
136
- * a real base (`basis: 'initial+log'`) with no unreadable rows (`skipped`
137
- * absent) — a log-only or gapped fold is not a state a real base may be held
138
- * against. On such a chain the two index checks are the whole defence, and
139
- * `foldLegs`' leg rule then CONTINUES the fold across the seam, which is the
140
- * right state for a real resume and is what `basis` reports. Paths the log
141
- * was redacted at are excluded from the comparison: the fold holds
142
- * `'REDACTED'` there and the checkpoint holds the value.
143
- */
144
- export function refuseChain(legs) {
145
- if (legs.length === 0)
146
- return 'timeTravel: a chain needs at least one source, got an empty array.';
147
- const spans = legs.map((leg) => spanOf(leg.log));
148
- const seen = new Map();
149
- for (const [i, span] of spans.entries()) {
150
- for (const id of span.ids) {
151
- const earlier = seen.get(id);
152
- if (earlier !== undefined) {
153
- return (`timeTravel: sources ${earlier} and ${i} both record '${id}'. A runtimeStageId is unique ` +
154
- 'within a run, so these are not two legs of one run — a same-executor resume already ' +
155
- 'carries the whole log in ONE snapshot and must not be chained with the paused one.');
156
- }
157
- seen.set(id, i);
158
- }
159
- }
160
- let previous;
161
- for (const [i, span] of spans.entries()) {
162
- if (span.first === undefined || span.last === undefined)
163
- continue;
164
- if (previous && span.first <= previous.last) {
165
- return (`timeTravel: source ${i} starts at execution index ${span.first}, which is not past ` +
166
- `source ${previous.idx}'s last (${previous.last}). Chain the sources in run order, and ` +
167
- 'only sources from ONE lineage — the engine never resets the execution counter across a ' +
168
- 'resume, so a fresh run restarting at 0 is a different run, not a continuation.');
169
- }
170
- previous = { idx: i, last: span.last };
171
- }
172
- for (let k = 1; k < legs.length; k++) {
173
- const base = legs[k].base;
174
- if (!base || typeof base !== 'object')
175
- continue; // no signal on the record — documented degradation
176
- const before = foldLegs(legs, k - 1, Number.POSITIVE_INFINITY);
177
- if (before.basis !== 'initial+log' || before.skipped)
178
- continue; // not a state a real base can be held to
179
- if (!sameState(before.state, base, new Set(before.redactedPaths), '')) {
180
- return (`timeTravel: source ${k}'s initialState is not the state source ${k - 1} folds to. On a resume ` +
181
- "the later leg's initialState IS the state at the pause, so a leg that begins anywhere else is " +
182
- 'not from one lineage — a different chart, or another run of this one — even when its execution ' +
183
- 'indices happen to be higher.');
184
- }
185
- }
186
- return undefined;
187
- }
188
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3RpbWUtdHJhdmVsL2NoYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQ0c7QUFFSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFL0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN0RCxPQUFPLEVBQW1CLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQWF6RCwyRUFBMkU7QUFDM0UsTUFBTSxVQUFVLE1BQU0sQ0FBQyxHQUE0QjtJQUtqRCxJQUFJLEtBQXlCLENBQUM7SUFDOUIsSUFBSSxJQUF3QixDQUFDO0lBQzdCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDOUIsS0FBSyxNQUFNLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN6QixNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxFQUFFO1lBQUUsU0FBUztRQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ1osTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLG1CQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7WUFBRSxTQUFTO1FBQzNDLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxjQUFjLEdBQUcsS0FBSztZQUFFLEtBQUssR0FBRyxjQUFjLENBQUM7UUFDMUUsSUFBSSxJQUFJLEtBQUssU0FBUyxJQUFJLGNBQWMsR0FBRyxJQUFJO1lBQUUsSUFBSSxHQUFHLGNBQWMsQ0FBQztJQUN6RSxD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TSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDdEUsT0FBTyxDQUNMLHNCQUFzQixDQUFDLDJDQUEyQyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUI7Z0JBQ2hHLGdHQUFnRztnQkFDaEcsaUdBQWlHO2dCQUNqRyw4QkFBOEIsQ0FDL0IsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogY2hhaW4udHMg4oCUIHJlYWRpbmcgYSBwYXVzZS9yZXN1bWUgYXMgT05FIGF4aXMuXG4gKlxuICogV0hZIFRISVMgRklMRSBFWElTVFMuIEEgcGF1c2UgYW5kIGl0cyByZXN1bWUgcHJvZHVjZSBUV08gc25hcHNob3RzLiBPbiBhXG4gKiBjcm9zcy1leGVjdXRvciByZXN1bWUgKHRoZSBjaGVja3BvaW50IHdhcyBwZXJzaXN0ZWQgYW5kIGEgZnJlc2ggZXhlY3V0b3JcbiAqIHBpY2tlZCBpdCB1cCkgdGhlIHNlY29uZCBydW4gZ2V0cyBhIGZyZXNoIHJ1bnRpbWU6IGl0cyBgY29tbWl0TG9nYCBzdGFydHMgYXRcbiAqIGluZGV4IDAgYW5kIGhvbGRzIG9ubHkgdGhlIHBvc3QtcmVzdW1lIGNvbW1pdHMsIGFuZCBpdHMgYGluaXRpYWxTdGF0ZWAgaXNcbiAqIHRoZSBzdGF0ZSBhdCB0aGUgcGF1c2UuIFR3byBsb2dzLCB0d28gZGlzam9pbnQgYXhlcyDigJQgc28gYSByZWFkZXIgc2NydWJiaW5nXG4gKiBhIHJlc3VtZWQgcnVuIHNhdyBvbmx5IHRoZSBzZWNvbmQgaGFsZiB1bmxlc3MgdGhlIGFwcGxpY2F0aW9uIGhhZCBrZXB0IHRoZVxuICogcGF1c2VkIHNuYXBzaG90IGFuZCBzdGl0Y2hlZCB0aGUgaGFsdmVzIGl0c2VsZi4gRXZlcnkgYXBwbGljYXRpb24gdGhhdFxuICogcGF1c2VzIHdvdWxkIHdyaXRlIHRoYXQgc3RpdGNoaW5nLCBhbmQgbm9uZSBvZiB0aGVtIG93biB0aGUgYXJpdGhtZXRpYy5cbiAqXG4gKiBUSEUgSE9ORVNUIEJJVCwgdXAgZnJvbnQ6IENPTU1JVCBJTkRJQ0VTIEFSRSBSVU4tTE9DQUwuIFRoZXJlIGlzIG5vIGdsb2JhbFxuICogaW5kZXggYWNyb3NzIGEgY2hhaW4gYW5kIHRoaXMgZmlsZSBkb2VzIG5vdCBpbnZlbnQgb25lIOKAlCBgY29tbWl0SWR4YCBhbmRcbiAqIGBsYXN0Q29tbWl0SWR4YCBrZWVwIGluZGV4aW5nIHRoZWlyIG93biBzb3VyY2UsIGFuZCBldmVyeSBzdG9wIGNhcnJpZXMgdGhlXG4gKiB7QGxpbmsgU3RvcC5zb3VyY2VJZHh9IHRoZXkgYmVsb25nIHRvLiBUaGUgY3Vyc29yJ3MgU1RFUFMgYXJlIHdoYXQgcnVuXG4gKiBhY3Jvc3MgdGhlIHdob2xlIGNoYWluLlxuICpcbiAqIEFORCBUSEUgUkVGVVNBTDogYSBjaGFpbiB0aGF0IGlzIG5vdCBvcmRlcmVkLCBvciB3aG9zZSBsZWdzIGFyZSBub3QgZnJvbSBvbmVcbiAqIGxpbmVhZ2UsIGlzIFJFRlVTRUQgcmF0aGVyIHRoYW4gZ3Vlc3NlZCBhdC4gVGhlIHJlY29yZCBjYXJyaWVzIFRXTyBzaWduYWxzXG4gKiBhbmQgdGhpcyBmaWxlIHJlYWRzIGJvdGg6XG4gKlxuICogLSBUaGUgZXhlY3V0aW9uIGluZGV4IHRoZSBlbmdpbmUgc3RhbXBzIGludG8gZXZlcnkgYHJ1bnRpbWVTdGFnZUlkYCDigJRcbiAqICAgZ2xvYmFsbHkgbW9ub3RvbmljIHBlciBydW4gYW5kLCBkZWxpYmVyYXRlbHksIE5PVCByZXNldCBvbiByZXN1bWUuIFNvIGFcbiAqICAgbGF0ZXIgbGVnJ3MgZmlyc3QgZXhlY3V0aW9uIGluZGV4IG11c3QgYmUgcGFzdCB0aGUgZWFybGllciBsZWcncyBsYXN0LCBhbmRcbiAqICAgbm8gc3RhZ2UgbWF5IGFwcGVhciBpbiB0d28gbGVncy4gVGhpcyBjYXRjaGVzIGEgYmFja3dhcmRzIGNoYWluLCBhIGZyZXNoXG4gKiAgIHJ1biAod2hpY2ggcmVzdGFydHMgYXQgMCkgYW5kIGEgc2FtZS1leGVjdXRvciByZXN1bWUgKHdob3NlIG9uZSBzbmFwc2hvdFxuICogICBhbHJlYWR5IGhvbGRzIGJvdGggaGFsdmVzKS5cbiAqIC0gVGhlIGxhdGVyIGxlZydzIGBpbml0aWFsU3RhdGVgLiBPbiBhIHJlc3VtZSB0aGUgZnJlc2ggcnVudGltZSBpcyBzZWVkZWRcbiAqICAgZnJvbSB0aGUgY2hlY2twb2ludCwgc28gdGhhdCBiYXNlIElTIHRoZSBzdGF0ZSBhdCB0aGUgcGF1c2Ug4oCUIGFuZCB0aGVcbiAqICAgc3RhdGUgdGhlIGVhcmxpZXIgbGVncyBGT0xEIFRPIG11c3QgZGVlcC1lcXVhbCBpdC4gVGhpcyBpcyB3aGF0IGNhdGNoZXMgYVxuICogICBsZWcgZnJvbSBzb21lIE9USEVSIGxpbmVhZ2Ugd2hvc2UgaW5kaWNlcyBtZXJlbHkgaGFwcGVuIHRvIGJlIGhpZ2hlcjogdGhlXG4gKiAgIGNvdW50ZXJzIGxpbmUgdXAgYnkgYWNjaWRlbnQsIHRoZSBzdGF0ZSBuZXZlciBkb2VzLlxuICpcbiAqIEEgY2hhcnQgaWRlbnRpdHkgb3IgYSBsaW5lYWdlIGlkIGlzIE5PVCBvbiB0aGUgcmVjb3JkLCBzbyBub3RoaW5nIGhlcmVcbiAqIHByZXRlbmRzIHRvIGNoZWNrIG9uZS4gQW5kIHdoZXJlIHRoZSBzdGF0ZSBzaWduYWwgaXMgbm90IG9uIHRoZSByZWNvcmRcbiAqIGVpdGhlciDigJQgYSBsZWcgcmVjb3JkZWQgYmVmb3JlIDkuMTcgY2FycmllcyBubyBgaW5pdGlhbFN0YXRlYDsgYW4gZWFybGllclxuICogbGVnIHdpdGggbm8gYmFzZSBmb2xkcyBgJ2xvZy1vbmx5J2A7IGEgbGVnIHdpdGggdW5yZWFkYWJsZSByb3dzIGZvbGRzIGFuXG4gKiBpbmNvbXBsZXRlIHN0YXRlIOKAlCB0aGF0IGNoZWNrIGlzIFNLSVBQRUQsIG5vdCBmYWtlZDogdGhlIGNoYWluIHRoZW4gcmVzdHMgb25cbiAqIHRoZSBpbmRleCBjaGVja3MgYWxvbmUsIGFuZCBldmVyeSBmb2xkJ3MgYGJhc2lzYCBzdGlsbCBzYXlzIHdoYXQgaXQgc3Rvb2RcbiAqIG9uLiBUaGF0IGRlZ3JhZGF0aW9uIGlzIGRvY3VtZW50ZWQgb24gYHJlZnVzZUNoYWluYCwgb24gYHRpbWVUcmF2ZWxgJ3NcbiAqIGBAdGhyb3dzYCwgYW5kIGluIHRoZSBSRUFETUUuXG4gKi9cblxuaW1wb3J0IHsga2luZE9mIH0gZnJvbSAnLi4vY2FwdHVyZS92YWx1ZUtpbmRzLmpzJztcbmltcG9ydCB7IHBhcnNlUnVudGltZVN0YWdlSWQgfSBmcm9tICcuLi9pZHMvcnVudGltZVN0YWdlSWQuanMnO1xuaW1wb3J0IHR5cGUgeyBDb21taXRCdW5kbGUgfSBmcm9tICcuLi9tZW1vcnkvdHlwZXMuanMnO1xuaW1wb3J0IHsgZGVlcEVxdWFsLCBERUxJTSB9IGZyb20gJy4uL21lbW9yeS91dGlscy5qcyc7XG5pbXBvcnQgeyB0eXBlIFJlYWRTb3VyY2UsIGZvbGRMZWdzIH0gZnJvbSAnLi9zdGF0ZUF0LmpzJztcbmltcG9ydCB0eXBlIHsgVGltZVRyYXZlbFNvdXJjZSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKiogT25lIGxlZyBvZiBhIGNoYWluOiBhIHNvdXJjZSwgaXRzIHJlYWQgbG9nLCBhbmQgd2hlcmUgaXQgc2l0cyBpbiB0aGUgcnVuLiAqL1xuZXhwb3J0IGludGVyZmFjZSBDaGFpbkxlZyB7XG4gIHJlYWRvbmx5IHNvdXJjZTogVGltZVRyYXZlbFNvdXJjZTtcbiAgcmVhZG9ubHkgbG9nOiByZWFkb25seSBDb21taXRCdW5kbGVbXTtcbiAgLyoqIExvd2VzdCBleGVjdXRpb24gaW5kZXggc3RhbXBlZCBpbiB0aGlzIGxlZzsgYHVuZGVmaW5lZGAgZm9yIGFuIGlkLWxlc3MgbG9nLiAqL1xuICByZWFkb25seSBmaXJzdEV4ZWN1dGlvbkluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIC8qKiBIaWdoZXN0IGV4ZWN1dGlvbiBpbmRleCBzdGFtcGVkIGluIHRoaXMgbGVnLiAqL1xuICByZWFkb25seSBsYXN0RXhlY3V0aW9uSW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZDtcbn1cblxuLyoqIFRoZSBleGVjdXRpb24taW5kZXggc3BhbiBvZiBvbmUgbGVnLCByZWFkIG9mZiBpdHMgYHJ1bnRpbWVTdGFnZUlkYHMuICovXG5leHBvcnQgZnVuY3Rpb24gc3Bhbk9mKGxvZzogcmVhZG9ubHkgQ29tbWl0QnVuZGxlW10pOiB7XG4gIGZpcnN0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGxhc3Q6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgaWRzOiBTZXQ8c3RyaW5nPjtcbn0ge1xuICBsZXQgZmlyc3Q6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgbGV0IGxhc3Q6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgY29uc3QgaWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgYnVuZGxlIG9mIGxvZykge1xuICAgIGNvbnN0IGlkID0gYnVuZGxlLnJ1bnRpbWVTdGFnZUlkO1xuICAgIGlmICghaWQpIGNvbnRpbnVlO1xuICAgIGlkcy5hZGQoaWQpO1xuICAgIGNvbnN0IHsgZXhlY3V0aW9uSW5kZXggfSA9IHBhcnNlUnVudGltZVN0YWdlSWQoaWQpO1xuICAgIGlmIChOdW1iZXIuaXNOYU4oZXhlY3V0aW9uSW5kZXgpKSBjb250aW51ZTtcbiAgICBpZiAoZmlyc3QgPT09IHVuZGVmaW5lZCB8fCBleGVjdXRpb25JbmRleCA8IGZpcnN0KSBmaXJzdCA9IGV4ZWN1dGlvbkluZGV4O1xuICAgIGlmIChsYXN0ID09PSB1bmRlZmluZWQgfHwgZXhlY3V0aW9uSW5kZXggPiBsYXN0KSBsYXN0ID0gZXhlY3V0aW9uSW5kZXg7XG4gIH1cbiAgcmV0dXJuIHsgZmlyc3QsIGxhc3QsIGlkcyB9O1xufVxuXG4vKipcbiAqIFN0cnVjdHVyYWwgZXF1YWxpdHkgb2YgdHdvIGZvbGRlZCBzdGF0ZXMsIGlnbm9yaW5nIHRoZSBwYXRocyB0aGUgbG9nIHdhc1xuICogcmVkYWN0ZWQgYXQuXG4gKlxuICogVGhlIGZvbGQgcmVwcm9kdWNlcyBgJ1JFREFDVEVEJ2Agd2hlcmV2ZXIgdGhlIGVuZ2luZSBzY3J1YmJlZCBhIHdyaXRlLCB3aGlsZVxuICogdGhlIGNoZWNrcG9pbnQgdGhhdCBzZWVkZWQgdGhlIHJlc3VtZWQgbGVnIGhvbGRzIHRoZSByZWFsIHZhbHVlIOKAlCBzbyB0aG9zZVxuICogcGF0aHMgQ0FOTk9UIGFncmVlLCBhbmQgYXJlIG5vdCBhc2tlZCB0by4gRXZlcnl0aGluZyBlbHNlIGlzIGRlY2lkZWQgYnkgdGhlXG4gKiBPTkUgZXF1YWxpdHkgbGF3IChgbWVtb3J5L2VxdWFsaXR5LnRzIMK3IGRlZXBFcXVhbGAsIGV2ZXJ5IHZhbHVlIGtpbmQgY29tcGFyZWRcbiAqIGFzIHRoZSByZWNvcmQgaG9sZHMgaXQ7IDkuNDQuMiDigJQgdGhpcyB3YWxrIGhhZCBhIGxhdyBvZiBpdHMgb3duLCB3aGljaCBoZWxkXG4gKiBhbnkgdHdvIFJlZ0V4cHMsIEVycm9ycyBvciBidWZmZXJzIGVxdWFsKS4gQm90aCBzaWRlcyBhcmUgY29waWVzIG9mIG9uZVxuICogcmVjb3JkLCBzbyBhbiBvcGFxdWUgdmFsdWUgY29tcGFyZXMgYXMgYCdjb3BpZXMnYC4gT25seSB0aGUgY29udGFpbmVycyBhYm92ZVxuICogYSByZWRhY3RlZCBwYXRoIGFyZSB3YWxrZWQgaGVyZS5cbiAqL1xuZnVuY3Rpb24gc2FtZVN0YXRlKGE6IHVua25vd24sIGI6IHVua25vd24sIHJlZGFjdGVkOiBSZWFkb25seVNldDxzdHJpbmc+LCBwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFyZWRhY3RlZEJlbG93KHBhdGgsIHJlZGFjdGVkKSkgcmV0dXJuIGRlZXBFcXVhbChhLCBiLCAnY29waWVzJyk7XG4gIGlmIChBcnJheS5pc0FycmF5KGEpICYmIEFycmF5LmlzQXJyYXkoYikpIHtcbiAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGEuZXZlcnkoKGl0ZW0sIGkpID0+IHNhbWVTdGF0ZShpdGVtLCBiW2ldLCByZWRhY3RlZCwgcGF0aCA9PT0gJycgPyBTdHJpbmcoaSkgOiBgJHtwYXRofSR7REVMSU19JHtpfWApKTtcbiAgfVxuICBjb25zdCBwbGFpbiA9ICh2OiB1bmtub3duKTogdiBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICAgIHYgIT09IG51bGwgJiYgdHlwZW9mIHYgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHYpICYmIGtpbmRPZih2KSA9PT0gJ3BsYWluJztcbiAgaWYgKCFwbGFpbihhKSB8fCAhcGxhaW4oYikpIHJldHVybiBkZWVwRXF1YWwoYSwgYiwgJ2NvcGllcycpO1xuICBjb25zdCBwcmVzZW50ID0gKG86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBPYmplY3Qua2V5cyhvKS5maWx0ZXIoKGspID0+IG9ba10gIT09IHVuZGVmaW5lZCk7XG4gIGNvbnN0IGxlZnRLZXlzID0gcHJlc2VudChhKTtcbiAgY29uc3QgcmlnaHRLZXlzID0gbmV3IFNldChwcmVzZW50KGIpKTtcbiAgaWYgKGxlZnRLZXlzLmxlbmd0aCAhPT0gcmlnaHRLZXlzLnNpemUgfHwgIWxlZnRLZXlzLmV2ZXJ5KChrKSA9PiByaWdodEtleXMuaGFzKGspKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gbGVmdEtleXMuZXZlcnkoKGspID0+IHtcbiAgICBjb25zdCBjaGlsZFBhdGggPSBwYXRoID09PSAnJyA/IGsgOiBgJHtwYXRofSR7REVMSU19JHtrfWA7XG4gICAgcmV0dXJuIHJlZGFjdGVkLmhhcyhjaGlsZFBhdGgpIHx8IHNhbWVTdGF0ZShhW2tdLCBiW2tdLCByZWRhY3RlZCwgY2hpbGRQYXRoKTtcbiAgfSk7XG59XG5cbi8qKiBJcyBgcGF0aGAsIG9yIGEgcGF0aCBiZWxvdyBpdCwgb25lIHRoZSBsb2cgd2FzIHJlZGFjdGVkIGF0PyAqL1xuZnVuY3Rpb24gcmVkYWN0ZWRCZWxvdyhwYXRoOiBzdHJpbmcsIHJlZGFjdGVkOiBSZWFkb25seVNldDxzdHJpbmc+KTogYm9vbGVhbiB7XG4gIGlmIChyZWRhY3RlZC5zaXplID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXRoID09PSAnJykgcmV0dXJuIHRydWU7XG4gIGZvciAoY29uc3QgciBvZiByZWRhY3RlZCkgaWYgKHIgPT09IHBhdGggfHwgci5zdGFydHNXaXRoKGAke3BhdGh9JHtERUxJTX1gKSkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVjayB0aGF0IGBsZWdzYCByZWFsbHkgYXJlIG9uZSBydW4gcmVhZCBpbiBvcmRlciwgYW5kIHNheSB3aHkgbm90LlxuICpcbiAqIFJldHVybnMgdGhlIHJlZnVzYWwgbWVzc2FnZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGUgY2hhaW4gaXMgc291bmQuIFRocmVlXG4gKiBkaXN0aW5jdCBmYWlsdXJlcywgYmVjYXVzZSB0aGV5IGFyZSB0aHJlZSBkaWZmZXJlbnQgbWlzdGFrZXMsIGNoZWNrZWQgaW5cbiAqIHRoaXMgb3JkZXI6XG4gKlxuICogLSBSRVBFQVRFRCBTVEFHRSDigJQgb25lIGBydW50aW1lU3RhZ2VJZGAgYXBwZWFycyBpbiB0d28gbGVncy4gSWRzIGFyZSB1bmlxdWVcbiAqICAgd2l0aGluIGEgcnVuLCBzbyBhIHJlcGVhdCBtZWFucyB0aGUgc2FtZSBleGVjdXRpb24gd2FzIHJlY29yZGVkIHR3aWNlOiBhXG4gKiAgIHNhbWUtZXhlY3V0b3IgcmVzdW1lLCB3aG9zZSBzbmFwc2hvdCBBTFJFQURZIGhvbGRzIHRoZSB3aG9sZSBsb2cgYW5kIG5lZWRzXG4gKiAgIG5vIGNoYWluaW5nLCBpcyB0aGUgdXN1YWwgY2F1c2UuXG4gKiAtIE9VVCBPRiBPUkRFUiDigJQgYSBsYXRlciBsZWcncyBmaXJzdCBleGVjdXRpb24gaW5kZXggaXMgbm90IHBhc3QgdGhlIGVhcmxpZXJcbiAqICAgbGVnJ3MgbGFzdC4gRWl0aGVyIHRoZSBzb3VyY2VzIHdlcmUgaGFuZGVkIG92ZXIgYmFja3dhcmRzLCBvciB0aGUgc2Vjb25kXG4gKiAgIGlzIG5vdCBhIGNvbnRpbnVhdGlvbiBhdCBhbGwgKGEgZnJlc2ggcnVuIHJlc3RhcnRzIHRoZSBjb3VudGVyIGF0IDAsIHNvIGFuXG4gKiAgIHVucmVsYXRlZCBzbmFwc2hvdCBmYWlscyBoZXJlIHJhdGhlciB0aGFuIHNpbGVudGx5IGludGVybGVhdmluZykuXG4gKiAtIFdST05HIExJTkVBR0Ug4oCUIGxlZyBrJ3MgYGluaXRpYWxTdGF0ZWAgaXMgbm90IHRoZSBzdGF0ZSBsZWdzIDAuLmstMSBmb2xkXG4gKiAgIHRvLiBPbiBhIHJlc3VtZSB0aGUgbGF0ZXIgbGVnIGlzIHNlZWRlZCBmcm9tIHRoZSBjaGVja3BvaW50LCBzbyBpdHMgYmFzZVxuICogICBJUyB0aGUgc3RhdGUgYXQgdGhlIHBhdXNlOyBhIGxlZyB0aGF0IGJlZ2lucyBhbnl3aGVyZSBlbHNlIGlzIGZyb20gc29tZVxuICogICBvdGhlciBydW4sIGhvd2V2ZXIgaXRzIGluZGljZXMgaGFwcGVuIHRvIGxpbmUgdXAuXG4gKlxuICogVEhFIExJTkVBR0UgQ0hFQ0sgUlVOUyBPTkxZIFdIRVJFIFRIRSBSRUNPUkQgQUxMT1dTIElULCBhbmQgaXMgc2tpcHBlZCDigJRcbiAqIG5ldmVyIGZha2VkIOKAlCBvdGhlcndpc2U6IGxlZyBrIG11c3QgY2FycnkgYW4gYGluaXRpYWxTdGF0ZWAgKGEgcmVjb3JkaW5nXG4gKiBtYWRlIGJlZm9yZSA5LjE3IGhhcyBub25lKSwgYW5kIHRoZSBmb2xkIG9mIHRoZSBsZWdzIGJlZm9yZSBpdCBtdXN0IHN0YW5kIG9uXG4gKiBhIHJlYWwgYmFzZSAoYGJhc2lzOiAnaW5pdGlhbCtsb2cnYCkgd2l0aCBubyB1bnJlYWRhYmxlIHJvd3MgKGBza2lwcGVkYFxuICogYWJzZW50KSDigJQgYSBsb2ctb25seSBvciBnYXBwZWQgZm9sZCBpcyBub3QgYSBzdGF0ZSBhIHJlYWwgYmFzZSBtYXkgYmUgaGVsZFxuICogYWdhaW5zdC4gT24gc3VjaCBhIGNoYWluIHRoZSB0d28gaW5kZXggY2hlY2tzIGFyZSB0aGUgd2hvbGUgZGVmZW5jZSwgYW5kXG4gKiBgZm9sZExlZ3NgJyBsZWcgcnVsZSB0aGVuIENPTlRJTlVFUyB0aGUgZm9sZCBhY3Jvc3MgdGhlIHNlYW0sIHdoaWNoIGlzIHRoZVxuICogcmlnaHQgc3RhdGUgZm9yIGEgcmVhbCByZXN1bWUgYW5kIGlzIHdoYXQgYGJhc2lzYCByZXBvcnRzLiBQYXRocyB0aGUgbG9nXG4gKiB3YXMgcmVkYWN0ZWQgYXQgYXJlIGV4Y2x1ZGVkIGZyb20gdGhlIGNvbXBhcmlzb246IHRoZSBmb2xkIGhvbGRzXG4gKiBgJ1JFREFDVEVEJ2AgdGhlcmUgYW5kIHRoZSBjaGVja3BvaW50IGhvbGRzIHRoZSB2YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZnVzZUNoYWluKGxlZ3M6IHJlYWRvbmx5IFJlYWRTb3VyY2VbXSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChsZWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICd0aW1lVHJhdmVsOiBhIGNoYWluIG5lZWRzIGF0IGxlYXN0IG9uZSBzb3VyY2UsIGdvdCBhbiBlbXB0eSBhcnJheS4nO1xuXG4gIGNvbnN0IHNwYW5zID0gbGVncy5tYXAoKGxlZykgPT4gc3Bhbk9mKGxlZy5sb2cpKTtcbiAgY29uc3Qgc2VlbiA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIGZvciAoY29uc3QgW2ksIHNwYW5dIG9mIHNwYW5zLmVudHJpZXMoKSkge1xuICAgIGZvciAoY29uc3QgaWQgb2Ygc3Bhbi5pZHMpIHtcbiAgICAgIGNvbnN0IGVhcmxpZXIgPSBzZWVuLmdldChpZCk7XG4gICAgICBpZiAoZWFybGllciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgYHRpbWVUcmF2ZWw6IHNvdXJjZXMgJHtlYXJsaWVyfSBhbmQgJHtpfSBib3RoIHJlY29yZCAnJHtpZH0nLiBBIHJ1bnRpbWVTdGFnZUlkIGlzIHVuaXF1ZSBgICtcbiAgICAgICAgICAnd2l0aGluIGEgcnVuLCBzbyB0aGVzZSBhcmUgbm90IHR3byBsZWdzIG9mIG9uZSBydW4g4oCUIGEgc2FtZS1leGVjdXRvciByZXN1bWUgYWxyZWFkeSAnICtcbiAgICAgICAgICAnY2FycmllcyB0aGUgd2hvbGUgbG9nIGluIE9ORSBzbmFwc2hvdCBhbmQgbXVzdCBub3QgYmUgY2hhaW5lZCB3aXRoIHRoZSBwYXVzZWQgb25lLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHNlZW4uc2V0KGlkLCBpKTtcbiAgICB9XG4gIH1cblxuICBsZXQgcHJldmlvdXM6IHsgaWR4OiBudW1iZXI7IGxhc3Q6IG51bWJlciB9IHwgdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IFtpLCBzcGFuXSBvZiBzcGFucy5lbnRyaWVzKCkpIHtcbiAgICBpZiAoc3Bhbi5maXJzdCA9PT0gdW5kZWZpbmVkIHx8IHNwYW4ubGFzdCA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICBpZiAocHJldmlvdXMgJiYgc3Bhbi5maXJzdCA8PSBwcmV2aW91cy5sYXN0KSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBgdGltZVRyYXZlbDogc291cmNlICR7aX0gc3RhcnRzIGF0IGV4ZWN1dGlvbiBpbmRleCAke3NwYW4uZmlyc3R9LCB3aGljaCBpcyBub3QgcGFzdCBgICtcbiAgICAgICAgYHNvdXJjZSAke3ByZXZpb3VzLmlkeH0ncyBsYXN0ICgke3ByZXZpb3VzLmxhc3R9KS4gQ2hhaW4gdGhlIHNvdXJjZXMgaW4gcnVuIG9yZGVyLCBhbmQgYCArXG4gICAgICAgICdvbmx5IHNvdXJjZXMgZnJvbSBPTkUgbGluZWFnZSDigJQgdGhlIGVuZ2luZSBuZXZlciByZXNldHMgdGhlIGV4ZWN1dGlvbiBjb3VudGVyIGFjcm9zcyBhICcgK1xuICAgICAgICAncmVzdW1lLCBzbyBhIGZyZXNoIHJ1biByZXN0YXJ0aW5nIGF0IDAgaXMgYSBkaWZmZXJlbnQgcnVuLCBub3QgYSBjb250aW51YXRpb24uJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcHJldmlvdXMgPSB7IGlkeDogaSwgbGFzdDogc3Bhbi5sYXN0IH07XG4gIH1cblxuICBmb3IgKGxldCBrID0gMTsgayA8IGxlZ3MubGVuZ3RoOyBrKyspIHtcbiAgICBjb25zdCBiYXNlID0gbGVnc1trXS5iYXNlO1xuICAgIGlmICghYmFzZSB8fCB0eXBlb2YgYmFzZSAhPT0gJ29iamVjdCcpIGNvbnRpbnVlOyAvLyBubyBzaWduYWwgb24gdGhlIHJlY29yZCDigJQgZG9jdW1lbnRlZCBkZWdyYWRhdGlvblxuICAgIGNvbnN0IGJlZm9yZSA9IGZvbGRMZWdzKGxlZ3MsIGsgLSAxLCBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpO1xuICAgIGlmIChiZWZvcmUuYmFzaXMgIT09ICdpbml0aWFsK2xvZycgfHwgYmVmb3JlLnNraXBwZWQpIGNvbnRpbnVlOyAvLyBub3QgYSBzdGF0ZSBhIHJlYWwgYmFzZSBjYW4gYmUgaGVsZCB0b1xuICAgIGlmICghc2FtZVN0YXRlKGJlZm9yZS5zdGF0ZSwgYmFzZSwgbmV3IFNldChiZWZvcmUucmVkYWN0ZWRQYXRocyksICcnKSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgYHRpbWVUcmF2ZWw6IHNvdXJjZSAke2t9J3MgaW5pdGlhbFN0YXRlIGlzIG5vdCB0aGUgc3RhdGUgc291cmNlICR7ayAtIDF9IGZvbGRzIHRvLiBPbiBhIHJlc3VtZSBgICtcbiAgICAgICAgXCJ0aGUgbGF0ZXIgbGVnJ3MgaW5pdGlhbFN0YXRlIElTIHRoZSBzdGF0ZSBhdCB0aGUgcGF1c2UsIHNvIGEgbGVnIHRoYXQgYmVnaW5zIGFueXdoZXJlIGVsc2UgaXMgXCIgK1xuICAgICAgICAnbm90IGZyb20gb25lIGxpbmVhZ2Ug4oCUIGEgZGlmZmVyZW50IGNoYXJ0LCBvciBhbm90aGVyIHJ1biBvZiB0aGlzIG9uZSDigJQgZXZlbiB3aGVuIGl0cyBleGVjdXRpb24gJyArXG4gICAgICAgICdpbmRpY2VzIGhhcHBlbiB0byBiZSBoaWdoZXIuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiJdfQ==
@@ -1,55 +0,0 @@
1
- /**
2
- * commitStops — the one strategy footprintjs ships.
3
- *
4
- * One stop per executed stage, in execution order, plus `'start'` / `'end'`
5
- * bookends. It is the only stop grammar the substrate itself knows: the engine
6
- * stamps one `runtimeStageId` per executed stage, and an empty commit is a
7
- * deliberate cursor stop, not noise. Richer vocabularies (milestones, turns,
8
- * tool calls) belong to the consumer that owns them — they plug in through
9
- * `TimeTravelStrategy`, they do not go here.
10
- */
11
- import type { CommitBundle, ExecutionTree } from '../memory/types.js';
12
- import type { Stop, TimeTravelStrategy } from './types.js';
13
- /**
14
- * Derive one stop per executed stage from a recorded commit log.
15
- *
16
- * **One stop per `runtimeStageId`.** A stage can commit MORE than one bundle:
17
- * a subflow mount commits its output-mapping bundle and then its EXIT; a
18
- * parallel fork child is committed by the stage funnel and again by the
19
- * fan-out (its REPEAT), and siblings interleave. The writer names each
20
- * continuation on its bundle (`phase: 'exit' | 'repeat'`, 9.39.0), so the
21
- * grouping is read, never inferred: the axis shows the stage ONCE, at its
22
- * first commit ({@link buildCommitIndex}), which keeps `runtimeStageId → stop`
23
- * one-to-one — the property `jumpTo` and marks depend on. The FIRST bundle per
24
- * `runtimeStageId` is the stage's own and never carries a `phase`; a stage
25
- * whose bundles include an `'exit'` is a `'mount'`. A continuation is normally empty
26
- * (the first commit released the staging buffer); one that carries a write is
27
- * folded where it sits in the log, which is when it happened.
28
- *
29
- * **Stops PARTITION the log.** A stop's range runs from its own first commit
30
- * up to (and including) the last commit before the NEXT stop begins —
31
- * `lastCommitIdx`. Every bundle therefore belongs to exactly one stop, nothing
32
- * is orphaned, and `stateAt(stop)` is precisely the state that existed just
33
- * before the next stop's stage started. Folding through `commitIdx` instead
34
- * would silently drop a mount's output mapping.
35
- *
36
- * **Bookends.** `'start'` is the position before the first commit — the fold
37
- * base, which no commit index can otherwise address. `'end'` is "the run is
38
- * over"; it folds the whole log, the same as the last stage's stop, because
39
- * "after the last stage" and "the run finished" are the same state asked as
40
- * two different questions.
41
- *
42
- * An EMPTY log yields NO stops at all — not two bookends around nothing. A
43
- * cursor with nowhere to stand says so (`Move.reason === 'empty'`).
44
- *
45
- * **THE SHAPE IS A CONTRACT (9.18.0).** For a non-empty log the result is
46
- * `[start, …stages, end]` — `'start'` first, `'end'` last, one stop per
47
- * executed stage between them, in execution order — and for an empty log it
48
- * is `[]`. A strategy that COMPOSES this one (keep some stages, drop the rest)
49
- * rests on that shape; it is pinned by `test/lib/time-travel/`, and
50
- * {@link splitAxis} is the one guard that reads it — a composer calls that, or
51
- * {@link filterStops} which calls it, instead of writing its own.
52
- */
53
- export declare function commitStops(commitLog: readonly CommitBundle[], executionTree?: ExecutionTree, subflowResults?: unknown): Stop[];
54
- /** `commitStops` as a {@link TimeTravelStrategy} — the default for `timeTravel`. */
55
- export declare const commitStopsStrategy: TimeTravelStrategy;