@invinite-org/chartlang-runtime 1.1.0 → 1.2.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 (616) hide show
  1. package/CHANGELOG.md +245 -0
  2. package/README.md +1 -2
  3. package/dist/barPoint.d.ts +20 -0
  4. package/dist/barPoint.d.ts.map +1 -0
  5. package/dist/barPoint.js +72 -0
  6. package/dist/barPoint.js.map +1 -0
  7. package/dist/bufferSnapshot.d.ts +102 -0
  8. package/dist/bufferSnapshot.d.ts.map +1 -0
  9. package/dist/bufferSnapshot.js +119 -0
  10. package/dist/bufferSnapshot.js.map +1 -0
  11. package/dist/buildComputeContext.js.map +1 -1
  12. package/dist/createScriptRunner.d.ts +6 -3
  13. package/dist/createScriptRunner.d.ts.map +1 -1
  14. package/dist/createScriptRunner.js +29 -5
  15. package/dist/createScriptRunner.js.map +1 -1
  16. package/dist/dep/DepOutputStore.js.map +1 -1
  17. package/dist/dep/DepRunner.d.ts.map +1 -1
  18. package/dist/dep/DepRunner.js +1 -0
  19. package/dist/dep/DepRunner.js.map +1 -1
  20. package/dist/dep/depOutput.js.map +1 -1
  21. package/dist/dep/emissionFilter.js.map +1 -1
  22. package/dist/dep/index.js.map +1 -1
  23. package/dist/emit/alert.js.map +1 -1
  24. package/dist/emit/alertConditionEmission.js.map +1 -1
  25. package/dist/emit/applyPlotOverride.js.map +1 -1
  26. package/dist/emit/draw/annotations/arrow.js +1 -1
  27. package/dist/emit/draw/annotations/arrow.js.map +1 -1
  28. package/dist/emit/draw/annotations/arrowMarkDown.js +1 -1
  29. package/dist/emit/draw/annotations/arrowMarkDown.js.map +1 -1
  30. package/dist/emit/draw/annotations/arrowMarkUp.js +1 -1
  31. package/dist/emit/draw/annotations/arrowMarkUp.js.map +1 -1
  32. package/dist/emit/draw/annotations/arrowMarker.js +1 -1
  33. package/dist/emit/draw/annotations/arrowMarker.js.map +1 -1
  34. package/dist/emit/draw/annotations/text.js +1 -1
  35. package/dist/emit/draw/annotations/text.js.map +1 -1
  36. package/dist/emit/draw/boxes/circle.js +1 -1
  37. package/dist/emit/draw/boxes/circle.js.map +1 -1
  38. package/dist/emit/draw/boxes/ellipse.d.ts +1 -1
  39. package/dist/emit/draw/boxes/ellipse.js +1 -1
  40. package/dist/emit/draw/boxes/ellipse.js.map +1 -1
  41. package/dist/emit/draw/boxes/fillBetween.d.ts +45 -0
  42. package/dist/emit/draw/boxes/fillBetween.d.ts.map +1 -0
  43. package/dist/emit/draw/boxes/fillBetween.js +36 -0
  44. package/dist/emit/draw/boxes/fillBetween.js.map +1 -0
  45. package/dist/emit/draw/boxes/marker.js +1 -1
  46. package/dist/emit/draw/boxes/marker.js.map +1 -1
  47. package/dist/emit/draw/boxes/path.d.ts +1 -1
  48. package/dist/emit/draw/boxes/path.js +1 -1
  49. package/dist/emit/draw/boxes/path.js.map +1 -1
  50. package/dist/emit/draw/boxes/polyline.d.ts +1 -1
  51. package/dist/emit/draw/boxes/polyline.js +1 -1
  52. package/dist/emit/draw/boxes/polyline.js.map +1 -1
  53. package/dist/emit/draw/boxes/rectangle.js +1 -1
  54. package/dist/emit/draw/boxes/rectangle.js.map +1 -1
  55. package/dist/emit/draw/boxes/rotatedRectangle.js +1 -1
  56. package/dist/emit/draw/boxes/rotatedRectangle.js.map +1 -1
  57. package/dist/emit/draw/boxes/triangle.d.ts +1 -1
  58. package/dist/emit/draw/boxes/triangle.js +1 -1
  59. package/dist/emit/draw/boxes/triangle.js.map +1 -1
  60. package/dist/emit/draw/channels/disjointChannel.js +1 -1
  61. package/dist/emit/draw/channels/disjointChannel.js.map +1 -1
  62. package/dist/emit/draw/channels/flatTopBottom.d.ts +1 -2
  63. package/dist/emit/draw/channels/flatTopBottom.d.ts.map +1 -1
  64. package/dist/emit/draw/channels/flatTopBottom.js +1 -1
  65. package/dist/emit/draw/channels/flatTopBottom.js.map +1 -1
  66. package/dist/emit/draw/channels/regressionTrend.d.ts +3 -4
  67. package/dist/emit/draw/channels/regressionTrend.d.ts.map +1 -1
  68. package/dist/emit/draw/channels/regressionTrend.js +1 -1
  69. package/dist/emit/draw/channels/regressionTrend.js.map +1 -1
  70. package/dist/emit/draw/channels/trendChannel.js +1 -1
  71. package/dist/emit/draw/channels/trendChannel.js.map +1 -1
  72. package/dist/emit/draw/containers/frame.d.ts +1 -1
  73. package/dist/emit/draw/containers/frame.js +2 -2
  74. package/dist/emit/draw/containers/frame.js.map +1 -1
  75. package/dist/emit/draw/containers/group.d.ts +1 -2
  76. package/dist/emit/draw/containers/group.d.ts.map +1 -1
  77. package/dist/emit/draw/containers/group.js +2 -2
  78. package/dist/emit/draw/containers/group.js.map +1 -1
  79. package/dist/emit/draw/curves/arc.js +1 -1
  80. package/dist/emit/draw/curves/arc.js.map +1 -1
  81. package/dist/emit/draw/curves/brush.js +1 -1
  82. package/dist/emit/draw/curves/brush.js.map +1 -1
  83. package/dist/emit/draw/curves/curve.js +1 -1
  84. package/dist/emit/draw/curves/curve.js.map +1 -1
  85. package/dist/emit/draw/curves/doubleCurve.js +1 -1
  86. package/dist/emit/draw/curves/doubleCurve.js.map +1 -1
  87. package/dist/emit/draw/curves/highlighter.js +1 -1
  88. package/dist/emit/draw/curves/highlighter.js.map +1 -1
  89. package/dist/emit/draw/curves/pen.js +1 -1
  90. package/dist/emit/draw/curves/pen.js.map +1 -1
  91. package/dist/emit/draw/cycles/cyclicLines.js +1 -1
  92. package/dist/emit/draw/cycles/cyclicLines.js.map +1 -1
  93. package/dist/emit/draw/cycles/sineLine.js +1 -1
  94. package/dist/emit/draw/cycles/sineLine.js.map +1 -1
  95. package/dist/emit/draw/cycles/timeCycles.js +1 -1
  96. package/dist/emit/draw/cycles/timeCycles.js.map +1 -1
  97. package/dist/emit/draw/elliott/elliottCorrectionWave.js +1 -1
  98. package/dist/emit/draw/elliott/elliottCorrectionWave.js.map +1 -1
  99. package/dist/emit/draw/elliott/elliottDoubleCombo.js +1 -1
  100. package/dist/emit/draw/elliott/elliottDoubleCombo.js.map +1 -1
  101. package/dist/emit/draw/elliott/elliottImpulseWave.js +1 -1
  102. package/dist/emit/draw/elliott/elliottImpulseWave.js.map +1 -1
  103. package/dist/emit/draw/elliott/elliottTriangleWave.js +1 -1
  104. package/dist/emit/draw/elliott/elliottTriangleWave.js.map +1 -1
  105. package/dist/emit/draw/elliott/elliottTripleCombo.js +1 -1
  106. package/dist/emit/draw/elliott/elliottTripleCombo.js.map +1 -1
  107. package/dist/emit/draw/fibA/fibChannel.js +1 -1
  108. package/dist/emit/draw/fibA/fibChannel.js.map +1 -1
  109. package/dist/emit/draw/fibA/fibRetracement.js +1 -1
  110. package/dist/emit/draw/fibA/fibRetracement.js.map +1 -1
  111. package/dist/emit/draw/fibA/fibTimeZone.d.ts +1 -2
  112. package/dist/emit/draw/fibA/fibTimeZone.d.ts.map +1 -1
  113. package/dist/emit/draw/fibA/fibTimeZone.js +1 -1
  114. package/dist/emit/draw/fibA/fibTimeZone.js.map +1 -1
  115. package/dist/emit/draw/fibA/fibTrendExtension.js +1 -1
  116. package/dist/emit/draw/fibA/fibTrendExtension.js.map +1 -1
  117. package/dist/emit/draw/fibA/fibWedge.js +1 -1
  118. package/dist/emit/draw/fibA/fibWedge.js.map +1 -1
  119. package/dist/emit/draw/fibB/fibCircles.d.ts +1 -2
  120. package/dist/emit/draw/fibB/fibCircles.d.ts.map +1 -1
  121. package/dist/emit/draw/fibB/fibCircles.js +1 -1
  122. package/dist/emit/draw/fibB/fibCircles.js.map +1 -1
  123. package/dist/emit/draw/fibB/fibSpeedArcs.js +1 -1
  124. package/dist/emit/draw/fibB/fibSpeedArcs.js.map +1 -1
  125. package/dist/emit/draw/fibB/fibSpeedFan.js +1 -1
  126. package/dist/emit/draw/fibB/fibSpeedFan.js.map +1 -1
  127. package/dist/emit/draw/fibB/fibSpiral.d.ts +1 -2
  128. package/dist/emit/draw/fibB/fibSpiral.d.ts.map +1 -1
  129. package/dist/emit/draw/fibB/fibSpiral.js +1 -1
  130. package/dist/emit/draw/fibB/fibSpiral.js.map +1 -1
  131. package/dist/emit/draw/fibB/fibTrendTime.d.ts +1 -2
  132. package/dist/emit/draw/fibB/fibTrendTime.d.ts.map +1 -1
  133. package/dist/emit/draw/fibB/fibTrendTime.js +1 -1
  134. package/dist/emit/draw/fibB/fibTrendTime.js.map +1 -1
  135. package/dist/emit/draw/gann/gannBox.js +1 -1
  136. package/dist/emit/draw/gann/gannBox.js.map +1 -1
  137. package/dist/emit/draw/gann/gannFan.js +1 -1
  138. package/dist/emit/draw/gann/gannFan.js.map +1 -1
  139. package/dist/emit/draw/gann/gannSquare.js +1 -1
  140. package/dist/emit/draw/gann/gannSquare.js.map +1 -1
  141. package/dist/emit/draw/gann/gannSquareFixed.js +1 -1
  142. package/dist/emit/draw/gann/gannSquareFixed.js.map +1 -1
  143. package/dist/emit/draw/handle.d.ts +11 -2
  144. package/dist/emit/draw/handle.d.ts.map +1 -1
  145. package/dist/emit/draw/handle.js +67 -12
  146. package/dist/emit/draw/handle.js.map +1 -1
  147. package/dist/emit/draw/index.js.map +1 -1
  148. package/dist/emit/draw/lines/crossLine.js +1 -1
  149. package/dist/emit/draw/lines/crossLine.js.map +1 -1
  150. package/dist/emit/draw/lines/horizontalLine.d.ts +1 -1
  151. package/dist/emit/draw/lines/horizontalLine.js +1 -1
  152. package/dist/emit/draw/lines/horizontalLine.js.map +1 -1
  153. package/dist/emit/draw/lines/horizontalRay.js +1 -1
  154. package/dist/emit/draw/lines/horizontalRay.js.map +1 -1
  155. package/dist/emit/draw/lines/line.d.ts +1 -1
  156. package/dist/emit/draw/lines/line.d.ts.map +1 -1
  157. package/dist/emit/draw/lines/line.js +2 -3
  158. package/dist/emit/draw/lines/line.js.map +1 -1
  159. package/dist/emit/draw/lines/trendAngle.js +1 -1
  160. package/dist/emit/draw/lines/trendAngle.js.map +1 -1
  161. package/dist/emit/draw/lines/verticalLine.js +1 -1
  162. package/dist/emit/draw/lines/verticalLine.js.map +1 -1
  163. package/dist/emit/draw/namespace.d.ts +5 -4
  164. package/dist/emit/draw/namespace.d.ts.map +1 -1
  165. package/dist/emit/draw/namespace.js +7 -4
  166. package/dist/emit/draw/namespace.js.map +1 -1
  167. package/dist/emit/draw/patterns/abcdPattern.js +1 -1
  168. package/dist/emit/draw/patterns/abcdPattern.js.map +1 -1
  169. package/dist/emit/draw/patterns/cypherPattern.d.ts +1 -2
  170. package/dist/emit/draw/patterns/cypherPattern.d.ts.map +1 -1
  171. package/dist/emit/draw/patterns/cypherPattern.js +1 -1
  172. package/dist/emit/draw/patterns/cypherPattern.js.map +1 -1
  173. package/dist/emit/draw/patterns/headAndShoulders.js +1 -1
  174. package/dist/emit/draw/patterns/headAndShoulders.js.map +1 -1
  175. package/dist/emit/draw/patterns/threeDrivesPattern.js +1 -1
  176. package/dist/emit/draw/patterns/threeDrivesPattern.js.map +1 -1
  177. package/dist/emit/draw/patterns/trianglePattern.d.ts +1 -1
  178. package/dist/emit/draw/patterns/trianglePattern.js +1 -1
  179. package/dist/emit/draw/patterns/trianglePattern.js.map +1 -1
  180. package/dist/emit/draw/patterns/xabcdPattern.js +1 -1
  181. package/dist/emit/draw/patterns/xabcdPattern.js.map +1 -1
  182. package/dist/emit/draw/pitchforks/pitchfan.js +1 -1
  183. package/dist/emit/draw/pitchforks/pitchfan.js.map +1 -1
  184. package/dist/emit/draw/pitchforks/pitchfork.d.ts +1 -1
  185. package/dist/emit/draw/pitchforks/pitchfork.js +2 -2
  186. package/dist/emit/draw/pitchforks/pitchfork.js.map +1 -1
  187. package/dist/emit/draw/pushDrawing.js.map +1 -1
  188. package/dist/emit/draw/subIdAllocator.d.ts +1 -1
  189. package/dist/emit/draw/subIdAllocator.js +1 -1
  190. package/dist/emit/draw/subIdAllocator.js.map +1 -1
  191. package/dist/emit/draw/table/table.d.ts +1 -1
  192. package/dist/emit/draw/table/table.js.map +1 -1
  193. package/dist/emit/emissionsQueue.js.map +1 -1
  194. package/dist/emit/hash.js.map +1 -1
  195. package/dist/emit/hline.js.map +1 -1
  196. package/dist/emit/index.js.map +1 -1
  197. package/dist/emit/logEmission.js.map +1 -1
  198. package/dist/emit/paneResolver.js.map +1 -1
  199. package/dist/emit/plot.d.ts +7 -0
  200. package/dist/emit/plot.d.ts.map +1 -1
  201. package/dist/emit/plot.js +13 -0
  202. package/dist/emit/plot.js.map +1 -1
  203. package/dist/emit/runtimeError.js.map +1 -1
  204. package/dist/execution/dispose.d.ts.map +1 -1
  205. package/dist/execution/dispose.js +16 -0
  206. package/dist/execution/dispose.js.map +1 -1
  207. package/dist/execution/drain.js.map +1 -1
  208. package/dist/execution/index.js.map +1 -1
  209. package/dist/execution/onBarClose.js.map +1 -1
  210. package/dist/execution/onBarTick.js.map +1 -1
  211. package/dist/execution/onHistory.js.map +1 -1
  212. package/dist/execution/runComputeStep.d.ts.map +1 -1
  213. package/dist/execution/runComputeStep.js +10 -1
  214. package/dist/execution/runComputeStep.js.map +1 -1
  215. package/dist/execution/secondaryStream.js.map +1 -1
  216. package/dist/index.d.ts +1 -1
  217. package/dist/index.d.ts.map +1 -1
  218. package/dist/index.js +1 -1
  219. package/dist/index.js.map +1 -1
  220. package/dist/inputs/index.js.map +1 -1
  221. package/dist/inputs/resolveInputs.js.map +1 -1
  222. package/dist/internal.js.map +1 -1
  223. package/dist/persistentStateStore.js.map +1 -1
  224. package/dist/persistentStateStore.runtime.d.ts.map +1 -1
  225. package/dist/persistentStateStore.runtime.js +21 -7
  226. package/dist/persistentStateStore.runtime.js.map +1 -1
  227. package/dist/persistentStateStore.validate.js.map +1 -1
  228. package/dist/primitives.js.map +1 -1
  229. package/dist/request/alignHtfSeriesCache.js.map +1 -1
  230. package/dist/request/alignHtfSeriesToLtf.d.ts +2 -2
  231. package/dist/request/alignHtfSeriesToLtf.js +2 -2
  232. package/dist/request/alignHtfSeriesToLtf.js.map +1 -1
  233. package/dist/request/bucketLtfBarsByMainContainment.js.map +1 -1
  234. package/dist/request/bucketLtfBarsCache.js.map +1 -1
  235. package/dist/request/index.d.ts +2 -1
  236. package/dist/request/index.d.ts.map +1 -1
  237. package/dist/request/index.js +2 -1
  238. package/dist/request/index.js.map +1 -1
  239. package/dist/request/lowerTf.js.map +1 -1
  240. package/dist/request/pushOnce.js.map +1 -1
  241. package/dist/request/requestNamespace.d.ts.map +1 -1
  242. package/dist/request/requestNamespace.js +16 -3
  243. package/dist/request/requestNamespace.js.map +1 -1
  244. package/dist/request/security.d.ts +20 -1
  245. package/dist/request/security.d.ts.map +1 -1
  246. package/dist/request/security.js +62 -23
  247. package/dist/request/security.js.map +1 -1
  248. package/dist/request/securityExprRunner.d.ts +133 -0
  249. package/dist/request/securityExprRunner.d.ts.map +1 -0
  250. package/dist/request/securityExprRunner.js +235 -0
  251. package/dist/request/securityExprRunner.js.map +1 -0
  252. package/dist/request/streamBars.d.ts +14 -1
  253. package/dist/request/streamBars.d.ts.map +1 -1
  254. package/dist/request/streamBars.js +39 -1
  255. package/dist/request/streamBars.js.map +1 -1
  256. package/dist/ringBuffer.d.ts +2 -2
  257. package/dist/ringBuffer.js +1 -1
  258. package/dist/ringBuffer.js.map +1 -1
  259. package/dist/runtimeContext.d.ts +51 -3
  260. package/dist/runtimeContext.d.ts.map +1 -1
  261. package/dist/runtimeContext.js.map +1 -1
  262. package/dist/seriesView.d.ts +43 -18
  263. package/dist/seriesView.d.ts.map +1 -1
  264. package/dist/seriesView.js +66 -43
  265. package/dist/seriesView.js.map +1 -1
  266. package/dist/state/index.d.ts +2 -1
  267. package/dist/state/index.d.ts.map +1 -1
  268. package/dist/state/index.js +2 -1
  269. package/dist/state/index.js.map +1 -1
  270. package/dist/state/lifecycle.d.ts +40 -0
  271. package/dist/state/lifecycle.d.ts.map +1 -1
  272. package/dist/state/lifecycle.js +53 -0
  273. package/dist/state/lifecycle.js.map +1 -1
  274. package/dist/state/seriesPersistence.d.ts +48 -0
  275. package/dist/state/seriesPersistence.d.ts.map +1 -0
  276. package/dist/state/seriesPersistence.js +87 -0
  277. package/dist/state/seriesPersistence.js.map +1 -0
  278. package/dist/state/seriesSlot.d.ts +105 -0
  279. package/dist/state/seriesSlot.d.ts.map +1 -0
  280. package/dist/state/seriesSlot.js +123 -0
  281. package/dist/state/seriesSlot.js.map +1 -0
  282. package/dist/state/stateNamespace.d.ts.map +1 -1
  283. package/dist/state/stateNamespace.js +28 -0
  284. package/dist/state/stateNamespace.js.map +1 -1
  285. package/dist/state/stateSlot.js.map +1 -1
  286. package/dist/stateStore.d.ts +2 -2
  287. package/dist/stateStore.js.map +1 -1
  288. package/dist/streamState.d.ts +26 -20
  289. package/dist/streamState.d.ts.map +1 -1
  290. package/dist/streamState.js +41 -67
  291. package/dist/streamState.js.map +1 -1
  292. package/dist/ta/adl.js +2 -2
  293. package/dist/ta/adl.js.map +1 -1
  294. package/dist/ta/adr.d.ts +3 -3
  295. package/dist/ta/adr.js +5 -5
  296. package/dist/ta/adr.js.map +1 -1
  297. package/dist/ta/adx.d.ts +3 -2
  298. package/dist/ta/adx.d.ts.map +1 -1
  299. package/dist/ta/adx.js +5 -4
  300. package/dist/ta/adx.js.map +1 -1
  301. package/dist/ta/alma.d.ts +6 -4
  302. package/dist/ta/alma.d.ts.map +1 -1
  303. package/dist/ta/alma.js +21 -8
  304. package/dist/ta/alma.js.map +1 -1
  305. package/dist/ta/anchoredVolumeProfile.js.map +1 -1
  306. package/dist/ta/anchoredVwap.d.ts +1 -1
  307. package/dist/ta/anchoredVwap.js +3 -3
  308. package/dist/ta/anchoredVwap.js.map +1 -1
  309. package/dist/ta/ao.js +2 -2
  310. package/dist/ta/ao.js.map +1 -1
  311. package/dist/ta/aroon.js +2 -2
  312. package/dist/ta/aroon.js.map +1 -1
  313. package/dist/ta/aroonOsc.js +2 -2
  314. package/dist/ta/aroonOsc.js.map +1 -1
  315. package/dist/ta/atr.d.ts +3 -2
  316. package/dist/ta/atr.d.ts.map +1 -1
  317. package/dist/ta/atr.js +5 -4
  318. package/dist/ta/atr.js.map +1 -1
  319. package/dist/ta/barssince.js +1 -1
  320. package/dist/ta/barssince.js.map +1 -1
  321. package/dist/ta/bb.d.ts +3 -2
  322. package/dist/ta/bb.d.ts.map +1 -1
  323. package/dist/ta/bb.js +5 -4
  324. package/dist/ta/bb.js.map +1 -1
  325. package/dist/ta/bbPercentB.js +2 -2
  326. package/dist/ta/bbPercentB.js.map +1 -1
  327. package/dist/ta/bbw.js +2 -2
  328. package/dist/ta/bbw.js.map +1 -1
  329. package/dist/ta/bop.js +2 -2
  330. package/dist/ta/bop.js.map +1 -1
  331. package/dist/ta/cci.js +2 -2
  332. package/dist/ta/cci.js.map +1 -1
  333. package/dist/ta/chaikinOsc.d.ts +3 -2
  334. package/dist/ta/chaikinOsc.d.ts.map +1 -1
  335. package/dist/ta/chaikinOsc.js +5 -4
  336. package/dist/ta/chaikinOsc.js.map +1 -1
  337. package/dist/ta/chandeKrollStop.d.ts +1 -1
  338. package/dist/ta/chandeKrollStop.js +3 -3
  339. package/dist/ta/chandeKrollStop.js.map +1 -1
  340. package/dist/ta/chandelier.d.ts +1 -1
  341. package/dist/ta/chandelier.js +3 -3
  342. package/dist/ta/chandelier.js.map +1 -1
  343. package/dist/ta/change.js +1 -1
  344. package/dist/ta/change.js.map +1 -1
  345. package/dist/ta/chop.js +2 -2
  346. package/dist/ta/chop.js.map +1 -1
  347. package/dist/ta/cmf.js +2 -2
  348. package/dist/ta/cmf.js.map +1 -1
  349. package/dist/ta/cmo.js +2 -2
  350. package/dist/ta/cmo.js.map +1 -1
  351. package/dist/ta/connorsRsi.d.ts +1 -1
  352. package/dist/ta/connorsRsi.js +3 -3
  353. package/dist/ta/connorsRsi.js.map +1 -1
  354. package/dist/ta/coppock.js +2 -2
  355. package/dist/ta/coppock.js.map +1 -1
  356. package/dist/ta/crossover.d.ts +3 -2
  357. package/dist/ta/crossover.d.ts.map +1 -1
  358. package/dist/ta/crossover.js +4 -3
  359. package/dist/ta/crossover.js.map +1 -1
  360. package/dist/ta/crossunder.d.ts +3 -2
  361. package/dist/ta/crossunder.d.ts.map +1 -1
  362. package/dist/ta/crossunder.js +4 -3
  363. package/dist/ta/crossunder.js.map +1 -1
  364. package/dist/ta/dema.js +2 -2
  365. package/dist/ta/dema.js.map +1 -1
  366. package/dist/ta/dmi.d.ts +4 -3
  367. package/dist/ta/dmi.d.ts.map +1 -1
  368. package/dist/ta/dmi.js +6 -5
  369. package/dist/ta/dmi.js.map +1 -1
  370. package/dist/ta/donchian.js +2 -2
  371. package/dist/ta/donchian.js.map +1 -1
  372. package/dist/ta/dpo.js +2 -2
  373. package/dist/ta/dpo.js.map +1 -1
  374. package/dist/ta/ema.d.ts +3 -2
  375. package/dist/ta/ema.d.ts.map +1 -1
  376. package/dist/ta/ema.js +5 -4
  377. package/dist/ta/ema.js.map +1 -1
  378. package/dist/ta/envelope.js +2 -2
  379. package/dist/ta/envelope.js.map +1 -1
  380. package/dist/ta/eom.d.ts +3 -1
  381. package/dist/ta/eom.d.ts.map +1 -1
  382. package/dist/ta/eom.js +5 -3
  383. package/dist/ta/eom.js.map +1 -1
  384. package/dist/ta/fisher.js +2 -2
  385. package/dist/ta/fisher.js.map +1 -1
  386. package/dist/ta/fixedRangeVolumeProfile.js.map +1 -1
  387. package/dist/ta/highest.js +1 -1
  388. package/dist/ta/highest.js.map +1 -1
  389. package/dist/ta/highestbars.d.ts +25 -0
  390. package/dist/ta/highestbars.d.ts.map +1 -0
  391. package/dist/ta/highestbars.js +106 -0
  392. package/dist/ta/highestbars.js.map +1 -0
  393. package/dist/ta/historicalVolatility.d.ts +3 -2
  394. package/dist/ta/historicalVolatility.d.ts.map +1 -1
  395. package/dist/ta/historicalVolatility.js +5 -4
  396. package/dist/ta/historicalVolatility.js.map +1 -1
  397. package/dist/ta/hma.js +2 -2
  398. package/dist/ta/hma.js.map +1 -1
  399. package/dist/ta/ichimoku.d.ts +3 -1
  400. package/dist/ta/ichimoku.d.ts.map +1 -1
  401. package/dist/ta/ichimoku.js +5 -3
  402. package/dist/ta/ichimoku.js.map +1 -1
  403. package/dist/ta/index.js.map +1 -1
  404. package/dist/ta/kama.js +2 -2
  405. package/dist/ta/kama.js.map +1 -1
  406. package/dist/ta/keltner.js +2 -2
  407. package/dist/ta/keltner.js.map +1 -1
  408. package/dist/ta/klinger.js +2 -2
  409. package/dist/ta/klinger.js.map +1 -1
  410. package/dist/ta/kst.js +2 -2
  411. package/dist/ta/kst.js.map +1 -1
  412. package/dist/ta/lib/adxFromDi.js +2 -2
  413. package/dist/ta/lib/adxFromDi.js.map +1 -1
  414. package/dist/ta/lib/computeMa.js +2 -2
  415. package/dist/ta/lib/computeMa.js.map +1 -1
  416. package/dist/ta/lib/computeMaOfFloat64.js +2 -2
  417. package/dist/ta/lib/computeMaOfFloat64.js.map +1 -1
  418. package/dist/ta/lib/directionalState.js +2 -2
  419. package/dist/ta/lib/directionalState.js.map +1 -1
  420. package/dist/ta/lib/donchianMid.js +2 -2
  421. package/dist/ta/lib/donchianMid.js.map +1 -1
  422. package/dist/ta/lib/emaFloat64.js +2 -2
  423. package/dist/ta/lib/emaFloat64.js.map +1 -1
  424. package/dist/ta/lib/linearRegression.js +2 -2
  425. package/dist/ta/lib/linearRegression.js.map +1 -1
  426. package/dist/ta/lib/maTypes.js.map +1 -1
  427. package/dist/ta/lib/pearson.js +2 -2
  428. package/dist/ta/lib/pearson.js.map +1 -1
  429. package/dist/ta/lib/pickCandleSource.js +2 -2
  430. package/dist/ta/lib/pickCandleSource.js.map +1 -1
  431. package/dist/ta/lib/readSourceField.js +2 -2
  432. package/dist/ta/lib/readSourceField.js.map +1 -1
  433. package/dist/ta/lib/rollingStddev.js +2 -2
  434. package/dist/ta/lib/rollingStddev.js.map +1 -1
  435. package/dist/ta/lib/smaFloat64.js +2 -2
  436. package/dist/ta/lib/smaFloat64.js.map +1 -1
  437. package/dist/ta/lib/smmaFloat64.js +2 -2
  438. package/dist/ta/lib/smmaFloat64.js.map +1 -1
  439. package/dist/ta/lib/sourceValue.js.map +1 -1
  440. package/dist/ta/lib/trSeries.js +2 -2
  441. package/dist/ta/lib/trSeries.js.map +1 -1
  442. package/dist/ta/lib/volume-profile/bucketEdges.js.map +1 -1
  443. package/dist/ta/lib/volume-profile/bucketizeVolume.js.map +1 -1
  444. package/dist/ta/lib/volume-profile/developingSeries.js.map +1 -1
  445. package/dist/ta/lib/volume-profile/index.js.map +1 -1
  446. package/dist/ta/lib/volume-profile/intercept.js.map +1 -1
  447. package/dist/ta/lib/volume-profile/scaffold.js.map +1 -1
  448. package/dist/ta/lib/volume-profile/tooHeavy.js.map +1 -1
  449. package/dist/ta/lib/volume-profile/types.js.map +1 -1
  450. package/dist/ta/lib/volume-profile/valueArea.js.map +1 -1
  451. package/dist/ta/lib/volume-profile/volumeProfileShared.js.map +1 -1
  452. package/dist/ta/lib/vwmaFloat64.js +2 -2
  453. package/dist/ta/lib/vwmaFloat64.js.map +1 -1
  454. package/dist/ta/lib/wilderDirectional.js +2 -2
  455. package/dist/ta/lib/wilderDirectional.js.map +1 -1
  456. package/dist/ta/lib/wilderSmoothing.js +2 -2
  457. package/dist/ta/lib/wilderSmoothing.js.map +1 -1
  458. package/dist/ta/lib/wmaFloat64.js +2 -2
  459. package/dist/ta/lib/wmaFloat64.js.map +1 -1
  460. package/dist/ta/lowest.js +1 -1
  461. package/dist/ta/lowest.js.map +1 -1
  462. package/dist/ta/lowestbars.d.ts +25 -0
  463. package/dist/ta/lowestbars.d.ts.map +1 -0
  464. package/dist/ta/lowestbars.js +102 -0
  465. package/dist/ta/lowestbars.js.map +1 -0
  466. package/dist/ta/lsma.js +2 -2
  467. package/dist/ta/lsma.js.map +1 -1
  468. package/dist/ta/maRibbon.js +2 -2
  469. package/dist/ta/maRibbon.js.map +1 -1
  470. package/dist/ta/macd.d.ts +3 -2
  471. package/dist/ta/macd.d.ts.map +1 -1
  472. package/dist/ta/macd.js +6 -5
  473. package/dist/ta/macd.js.map +1 -1
  474. package/dist/ta/massIndex.d.ts +3 -2
  475. package/dist/ta/massIndex.d.ts.map +1 -1
  476. package/dist/ta/massIndex.js +5 -4
  477. package/dist/ta/massIndex.js.map +1 -1
  478. package/dist/ta/mcginley.js +2 -2
  479. package/dist/ta/mcginley.js.map +1 -1
  480. package/dist/ta/median.js +2 -2
  481. package/dist/ta/median.js.map +1 -1
  482. package/dist/ta/mfi.d.ts +3 -1
  483. package/dist/ta/mfi.d.ts.map +1 -1
  484. package/dist/ta/mfi.js +5 -3
  485. package/dist/ta/mfi.js.map +1 -1
  486. package/dist/ta/momentum.js +2 -2
  487. package/dist/ta/momentum.js.map +1 -1
  488. package/dist/ta/netVolume.d.ts +3 -1
  489. package/dist/ta/netVolume.d.ts.map +1 -1
  490. package/dist/ta/netVolume.js +5 -3
  491. package/dist/ta/netVolume.js.map +1 -1
  492. package/dist/ta/nvi.d.ts +3 -1
  493. package/dist/ta/nvi.d.ts.map +1 -1
  494. package/dist/ta/nvi.js +5 -3
  495. package/dist/ta/nvi.js.map +1 -1
  496. package/dist/ta/nz.js +1 -1
  497. package/dist/ta/nz.js.map +1 -1
  498. package/dist/ta/obv.js +2 -2
  499. package/dist/ta/obv.js.map +1 -1
  500. package/dist/ta/persistence.d.ts.map +1 -1
  501. package/dist/ta/persistence.js +1 -40
  502. package/dist/ta/persistence.js.map +1 -1
  503. package/dist/ta/pivotsHighLow.js +2 -2
  504. package/dist/ta/pivotsHighLow.js.map +1 -1
  505. package/dist/ta/pivotsStandard.d.ts +1 -1
  506. package/dist/ta/pivotsStandard.js +3 -3
  507. package/dist/ta/pivotsStandard.js.map +1 -1
  508. package/dist/ta/pmo.js +2 -2
  509. package/dist/ta/pmo.js.map +1 -1
  510. package/dist/ta/ppo.d.ts +3 -2
  511. package/dist/ta/ppo.d.ts.map +1 -1
  512. package/dist/ta/ppo.js +5 -4
  513. package/dist/ta/ppo.js.map +1 -1
  514. package/dist/ta/psar.js +2 -2
  515. package/dist/ta/psar.js.map +1 -1
  516. package/dist/ta/pvi.d.ts +3 -1
  517. package/dist/ta/pvi.d.ts.map +1 -1
  518. package/dist/ta/pvi.js +5 -3
  519. package/dist/ta/pvi.js.map +1 -1
  520. package/dist/ta/pvo.d.ts +3 -1
  521. package/dist/ta/pvo.d.ts.map +1 -1
  522. package/dist/ta/pvo.js +5 -3
  523. package/dist/ta/pvo.js.map +1 -1
  524. package/dist/ta/pvt.d.ts +3 -1
  525. package/dist/ta/pvt.d.ts.map +1 -1
  526. package/dist/ta/pvt.js +5 -3
  527. package/dist/ta/pvt.js.map +1 -1
  528. package/dist/ta/registry.d.ts +7 -1
  529. package/dist/ta/registry.d.ts.map +1 -1
  530. package/dist/ta/registry.js +4 -0
  531. package/dist/ta/registry.js.map +1 -1
  532. package/dist/ta/roc.js +2 -2
  533. package/dist/ta/roc.js.map +1 -1
  534. package/dist/ta/rsi.d.ts +3 -2
  535. package/dist/ta/rsi.d.ts.map +1 -1
  536. package/dist/ta/rsi.js +5 -4
  537. package/dist/ta/rsi.js.map +1 -1
  538. package/dist/ta/rvgi.js +2 -2
  539. package/dist/ta/rvgi.js.map +1 -1
  540. package/dist/ta/rvi.d.ts +3 -2
  541. package/dist/ta/rvi.d.ts.map +1 -1
  542. package/dist/ta/rvi.js +5 -4
  543. package/dist/ta/rvi.js.map +1 -1
  544. package/dist/ta/sessionVolumeProfile.js.map +1 -1
  545. package/dist/ta/sma.d.ts +6 -3
  546. package/dist/ta/sma.d.ts.map +1 -1
  547. package/dist/ta/sma.js +8 -5
  548. package/dist/ta/sma.js.map +1 -1
  549. package/dist/ta/smi.js +2 -2
  550. package/dist/ta/smi.js.map +1 -1
  551. package/dist/ta/smma.js +2 -2
  552. package/dist/ta/smma.js.map +1 -1
  553. package/dist/ta/stdev.d.ts +3 -2
  554. package/dist/ta/stdev.d.ts.map +1 -1
  555. package/dist/ta/stdev.js +5 -4
  556. package/dist/ta/stdev.js.map +1 -1
  557. package/dist/ta/stoch.js +2 -2
  558. package/dist/ta/stoch.js.map +1 -1
  559. package/dist/ta/stochRsi.js +2 -2
  560. package/dist/ta/stochRsi.js.map +1 -1
  561. package/dist/ta/supertrend.d.ts +1 -1
  562. package/dist/ta/supertrend.js +3 -3
  563. package/dist/ta/supertrend.js.map +1 -1
  564. package/dist/ta/tema.js +2 -2
  565. package/dist/ta/tema.js.map +1 -1
  566. package/dist/ta/trendStrengthIndex.d.ts +4 -3
  567. package/dist/ta/trendStrengthIndex.d.ts.map +1 -1
  568. package/dist/ta/trendStrengthIndex.js +6 -5
  569. package/dist/ta/trendStrengthIndex.js.map +1 -1
  570. package/dist/ta/trix.d.ts +4 -3
  571. package/dist/ta/trix.d.ts.map +1 -1
  572. package/dist/ta/trix.js +6 -5
  573. package/dist/ta/trix.js.map +1 -1
  574. package/dist/ta/tsi.js +2 -2
  575. package/dist/ta/tsi.js.map +1 -1
  576. package/dist/ta/ulcerIndex.js +2 -2
  577. package/dist/ta/ulcerIndex.js.map +1 -1
  578. package/dist/ta/ultimateOsc.js +2 -2
  579. package/dist/ta/ultimateOsc.js.map +1 -1
  580. package/dist/ta/valuewhen.js +1 -1
  581. package/dist/ta/valuewhen.js.map +1 -1
  582. package/dist/ta/visibleRangeVolumeProfile.d.ts +2 -2
  583. package/dist/ta/visibleRangeVolumeProfile.js +2 -2
  584. package/dist/ta/visibleRangeVolumeProfile.js.map +1 -1
  585. package/dist/ta/vol.js +2 -2
  586. package/dist/ta/vol.js.map +1 -1
  587. package/dist/ta/volatilityStop.d.ts +1 -1
  588. package/dist/ta/volatilityStop.js +3 -3
  589. package/dist/ta/volatilityStop.js.map +1 -1
  590. package/dist/ta/vortex.d.ts +3 -2
  591. package/dist/ta/vortex.d.ts.map +1 -1
  592. package/dist/ta/vortex.js +5 -4
  593. package/dist/ta/vortex.js.map +1 -1
  594. package/dist/ta/vwap.d.ts +3 -3
  595. package/dist/ta/vwap.js +5 -5
  596. package/dist/ta/vwap.js.map +1 -1
  597. package/dist/ta/vwma.js +2 -2
  598. package/dist/ta/vwma.js.map +1 -1
  599. package/dist/ta/williamsFractal.js +2 -2
  600. package/dist/ta/williamsFractal.js.map +1 -1
  601. package/dist/ta/williamsR.js +2 -2
  602. package/dist/ta/williamsR.js.map +1 -1
  603. package/dist/ta/wma.js +2 -2
  604. package/dist/ta/wma.js.map +1 -1
  605. package/dist/ta/zigZag.js +2 -2
  606. package/dist/ta/zigZag.js.map +1 -1
  607. package/dist/views/barstateView.js.map +1 -1
  608. package/dist/views/index.js.map +1 -1
  609. package/dist/views/refreshRuntimeViews.js.map +1 -1
  610. package/dist/views/symInfoView.js.map +1 -1
  611. package/dist/views/timeframeView.js.map +1 -1
  612. package/package.json +3 -3
  613. package/dist/ta/lib/applyOffset.d.ts +0 -19
  614. package/dist/ta/lib/applyOffset.d.ts.map +0 -1
  615. package/dist/ta/lib/applyOffset.js +0 -38
  616. package/dist/ta/lib/applyOffset.js.map +0 -1
@@ -0,0 +1,133 @@
1
+ import type { Bar, ScriptManifest, SecurityBar, SecurityExpr } from "@invinite-org/chartlang-core";
2
+ import { type RuntimeContext } from "../runtimeContext.js";
3
+ import { Float64RingBuffer } from "../ringBuffer.js";
4
+ import { type StreamState } from "../streamState.js";
5
+ /**
6
+ * One mounted higher-timeframe expression unit. The compiler records each
7
+ * `request.security({ interval }, (bar) => …)` callsite in
8
+ * `manifest.securityExpressions`; the runtime mounts one runner per entry.
9
+ *
10
+ * The runner owns a dedicated fold {@link StreamState} clocked on the HTF
11
+ * `interval`, a `Float64RingBuffer` output buffer (one sampled value per HTF
12
+ * bar), a fold {@link SecurityBar} view backed by the fold stream's head, and
13
+ * a private {@link RuntimeContext} (`stream = foldStream`,
14
+ * `slotIdPrefix = "security:<slotId>/"`) so `ta.*` inside the callback
15
+ * accumulate on the HTF clock without colliding with the main stream.
16
+ *
17
+ * `callback` is captured lazily the first time the main compute body calls
18
+ * `request.security(slotId, opts, expr)`. `processedHtfCount` tracks how many
19
+ * HTF bars have already been folded into `output` so replay catches up history
20
+ * exactly once.
21
+ *
22
+ * @since 0.7
23
+ * @stable
24
+ * @example
25
+ * // const runner = createSecurityExprRunner({ slotId: "s#0", interval: "1W",
26
+ * // capacity: 64, parent });
27
+ * const slotId = "s#0";
28
+ * void slotId;
29
+ */
30
+ export type SecurityExprRunner = {
31
+ readonly slotId: string;
32
+ readonly interval: string;
33
+ readonly foldStream: StreamState;
34
+ readonly foldBar: SecurityBar;
35
+ readonly ctx: RuntimeContext;
36
+ readonly output: Float64RingBuffer;
37
+ callback?: SecurityExpr;
38
+ processedHtfCount: number;
39
+ };
40
+ /**
41
+ * The pair of lookup maps the runtime threads onto its {@link RuntimeContext}:
42
+ * `bySlot` keyed by `slotId` (overload dispatch + capture) and `byInterval`
43
+ * keyed by `IntervalDescriptor.value` (the fan-out from a secondary close).
44
+ *
45
+ * @since 0.7
46
+ * @stable
47
+ * @example
48
+ * const registry: SecurityExprRegistry = {
49
+ * bySlot: new Map(),
50
+ * byInterval: new Map(),
51
+ * };
52
+ * void registry;
53
+ */
54
+ export type SecurityExprRegistry = {
55
+ readonly bySlot: Map<string, SecurityExprRunner>;
56
+ readonly byInterval: ReadonlyMap<string, ReadonlyArray<SecurityExprRunner>>;
57
+ };
58
+ /**
59
+ * Construct one {@link SecurityExprRunner}. The fold stream and output buffer
60
+ * share the secondary stream's `capacity` so a deep-lookback callback
61
+ * (`ta.sma(bar.close, 50)`) has enough HTF history to warm up.
62
+ *
63
+ * @since 0.7
64
+ * @stable
65
+ * @example
66
+ * // const runner = createSecurityExprRunner({ slotId: "s#0",
67
+ * // interval: "1W", capacity: 64, parent });
68
+ * const interval = "1W";
69
+ * void interval;
70
+ */
71
+ export declare function createSecurityExprRunner(args: {
72
+ readonly slotId: string;
73
+ readonly interval: string;
74
+ readonly capacity: number;
75
+ readonly parent: RuntimeContext;
76
+ }): SecurityExprRunner;
77
+ /**
78
+ * Mount one runner per `manifest.securityExpressions` entry and return the
79
+ * `bySlot` / `byInterval` lookup maps. Returns empty maps when the manifest
80
+ * declares no expression callsites (the common single-timeframe case), so the
81
+ * secondary-close drive pays a single empty-map check.
82
+ *
83
+ * @since 0.7
84
+ * @stable
85
+ * @example
86
+ * // const registry = buildSecurityExprRunners(manifest, ctx, 64);
87
+ * const built = "bySlot + byInterval";
88
+ * void built;
89
+ */
90
+ export declare function buildSecurityExprRunners(manifest: ScriptManifest, parent: RuntimeContext, capacity: number): SecurityExprRegistry;
91
+ /**
92
+ * Drive every runner registered on `interval` for one secondary event. A
93
+ * `"close"` folds the bar into the fold stream and appends one sampled output;
94
+ * a `"tick"` replaces the fold head and the output head without advancing
95
+ * length. Runners whose callback is not yet captured are skipped — the first
96
+ * main compute replays their backlog via {@link captureAndCatchUp}.
97
+ *
98
+ * @since 0.7
99
+ * @stable
100
+ * @example
101
+ * // driveSecurityExpressions(ctx, "1W", "close", weeklyBar);
102
+ * const mode = "close";
103
+ * void mode;
104
+ */
105
+ export declare function driveSecurityExpressions(parent: RuntimeContext, interval: string, mode: "close" | "tick", bar: Bar): void;
106
+ /**
107
+ * Store the callback the first time main compute provides it, then replay the
108
+ * real secondary stream oldest→newest through the runner's fold stream until
109
+ * `processedHtfCount === secondary.length`. Idempotent once the backlog is
110
+ * drained, so later calls in the same bar are no-ops.
111
+ *
112
+ * @since 0.7
113
+ * @stable
114
+ * @example
115
+ * // captureAndCatchUp(runner, expr, secondaryStream);
116
+ * const replayed = "oldest -> newest";
117
+ * void replayed;
118
+ */
119
+ export declare function captureAndCatchUp(runner: SecurityExprRunner, expr: SecurityExpr, secondary: StreamState): void;
120
+ /**
121
+ * Materialise a `Float64RingBuffer`'s values oldest→newest. Used as the
122
+ * `htfSeries` source when aligning a runner's output buffer to the main
123
+ * timeline.
124
+ *
125
+ * @since 0.7
126
+ * @stable
127
+ * @example
128
+ * // const values = ascendingValues(runner.output);
129
+ * const order = "oldest -> newest";
130
+ * void order;
131
+ */
132
+ export declare function ascendingValues(buffer: Float64RingBuffer): ReadonlyArray<number>;
133
+ //# sourceMappingURL=securityExprRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityExprRunner.d.ts","sourceRoot":"","sources":["../../src/request/securityExprRunner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,GAAG,EACH,cAAc,EACd,WAAW,EACX,YAAY,EAEf,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EACH,KAAK,WAAW,EAInB,MAAM,mBAAmB,CAAC;AAI3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAC/B,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACjD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC;CAC/E,CAAC;AAoEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;CACnC,GAAG,kBAAkB,CAYrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,GACjB,oBAAoB,CAmBtB;AAqCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,GAAG,MAAM,EACtB,GAAG,EAAE,GAAG,GACT,IAAI,CAUN;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,WAAW,GACvB,IAAI,CAON;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAMhF"}
@@ -0,0 +1,235 @@
1
+ // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
+ // See the LICENSE file in the repo root for full license text.
3
+ import { ACTIVE_RUNTIME_CONTEXT } from "../runtimeContext.js";
4
+ import { Float64RingBuffer } from "../ringBuffer.js";
5
+ import { advanceSeriesSlots, commitSeriesSlots, resetSeriesHeads } from "../state/index.js";
6
+ import { inMemoryStateStore } from "../stateStore.js";
7
+ import { appendBarToStream, createStreamState, replaceStreamHead, } from "../streamState.js";
8
+ import { createRuntimeViews } from "../views/index.js";
9
+ import { barFromStream, makeConstantStringSeries } from "./streamBars.js";
10
+ function makeFoldBar(foldStream, interval) {
11
+ const { seriesViews } = foldStream;
12
+ return Object.freeze({
13
+ time: seriesViews.time,
14
+ open: seriesViews.open,
15
+ high: seriesViews.high,
16
+ low: seriesViews.low,
17
+ close: seriesViews.close,
18
+ volume: seriesViews.volume,
19
+ hl2: seriesViews.hl2,
20
+ hlc3: seriesViews.hlc3,
21
+ ohlc4: seriesViews.ohlc4,
22
+ hlcc4: seriesViews.hlcc4,
23
+ symbol: makeConstantStringSeries(""),
24
+ interval: makeConstantStringSeries(interval),
25
+ });
26
+ }
27
+ function buildExprContext(parent, slotId, foldStream) {
28
+ return {
29
+ stream: foldStream,
30
+ stateStore: inMemoryStateStore(),
31
+ lastPersistTime: 0,
32
+ capabilities: parent.capabilities,
33
+ // A throwaway bag — the callback may not emit (Task 2 forbids
34
+ // non-`ta` refs), but an isolated queue guards if it somehow does.
35
+ emissions: {
36
+ plots: [],
37
+ drawings: [],
38
+ alerts: [],
39
+ alertConditions: [],
40
+ logs: [],
41
+ diagnostics: [],
42
+ fromBar: 0,
43
+ toBar: 0,
44
+ },
45
+ barIndex: () => foldStream.ohlcv.close.length - 1,
46
+ isTick: false,
47
+ drawingSlots: new Map(),
48
+ drawingSubIdCounters: new Map(),
49
+ drawingBucketCounters: { lines: 0, labels: 0, boxes: 0, polylines: 0, other: 0 },
50
+ scriptMaxDrawings: null,
51
+ stateSlots: new Map(),
52
+ seriesSlots: new Map(),
53
+ secondaryStreams: parent.secondaryStreams,
54
+ requestSecurityBars: new Map(),
55
+ requestSecurityAlignments: new Map(),
56
+ requestSecurityAscendingBars: new Map(),
57
+ requestLowerTfViews: new Map(),
58
+ diagnosedRequestKeys: new Set(),
59
+ logBudget: 0,
60
+ logBudgetExceededDiagnosed: false,
61
+ resolvedInputs: parent.resolvedInputs,
62
+ defaultPane: parent.defaultPane,
63
+ scriptPane: parent.scriptPane,
64
+ plotOverrides: Object.freeze({}),
65
+ diagnosedInputKeys: new Set(),
66
+ views: createRuntimeViews(),
67
+ slotIdPrefix: `security:${slotId}/`,
68
+ };
69
+ }
70
+ /**
71
+ * Construct one {@link SecurityExprRunner}. The fold stream and output buffer
72
+ * share the secondary stream's `capacity` so a deep-lookback callback
73
+ * (`ta.sma(bar.close, 50)`) has enough HTF history to warm up.
74
+ *
75
+ * @since 0.7
76
+ * @stable
77
+ * @example
78
+ * // const runner = createSecurityExprRunner({ slotId: "s#0",
79
+ * // interval: "1W", capacity: 64, parent });
80
+ * const interval = "1W";
81
+ * void interval;
82
+ */
83
+ export function createSecurityExprRunner(args) {
84
+ const { slotId, interval, capacity, parent } = args;
85
+ const foldStream = createStreamState({ interval, capacity, symbol: "" });
86
+ return {
87
+ slotId,
88
+ interval,
89
+ foldStream,
90
+ foldBar: makeFoldBar(foldStream, interval),
91
+ ctx: buildExprContext(parent, slotId, foldStream),
92
+ output: new Float64RingBuffer(capacity),
93
+ processedHtfCount: 0,
94
+ };
95
+ }
96
+ /**
97
+ * Mount one runner per `manifest.securityExpressions` entry and return the
98
+ * `bySlot` / `byInterval` lookup maps. Returns empty maps when the manifest
99
+ * declares no expression callsites (the common single-timeframe case), so the
100
+ * secondary-close drive pays a single empty-map check.
101
+ *
102
+ * @since 0.7
103
+ * @stable
104
+ * @example
105
+ * // const registry = buildSecurityExprRunners(manifest, ctx, 64);
106
+ * const built = "bySlot + byInterval";
107
+ * void built;
108
+ */
109
+ export function buildSecurityExprRunners(manifest, parent, capacity) {
110
+ const bySlot = new Map();
111
+ const byInterval = new Map();
112
+ for (const descriptor of manifest.securityExpressions ?? []) {
113
+ const runner = createSecurityExprRunner({
114
+ slotId: descriptor.slotId,
115
+ interval: descriptor.interval,
116
+ capacity,
117
+ parent,
118
+ });
119
+ bySlot.set(descriptor.slotId, runner);
120
+ const list = byInterval.get(descriptor.interval);
121
+ if (list === undefined) {
122
+ byInterval.set(descriptor.interval, [runner]);
123
+ }
124
+ else {
125
+ list.push(runner);
126
+ }
127
+ }
128
+ return { bySlot, byInterval };
129
+ }
130
+ function sampleOutput(result) {
131
+ return typeof result === "number" ? result : result.current;
132
+ }
133
+ function evaluate(runner, callback, isTick) {
134
+ const previous = ACTIVE_RUNTIME_CONTEXT.current;
135
+ ACTIVE_RUNTIME_CONTEXT.current = runner.ctx;
136
+ runner.ctx.isTick = isTick;
137
+ // `state.series` inside the callback accumulates on the HTF clock, so it
138
+ // advances/commits in lockstep with the fold stream — the same close/tick
139
+ // discipline `runComputeBody` applies to the main compute.
140
+ if (isTick)
141
+ resetSeriesHeads(runner.ctx);
142
+ else
143
+ advanceSeriesSlots(runner.ctx);
144
+ try {
145
+ return sampleOutput(callback(runner.foldBar));
146
+ }
147
+ finally {
148
+ if (!isTick)
149
+ commitSeriesSlots(runner.ctx);
150
+ runner.ctx.isTick = false;
151
+ ACTIVE_RUNTIME_CONTEXT.current = previous;
152
+ }
153
+ }
154
+ function foldClose(runner, bar) {
155
+ if (runner.callback === undefined)
156
+ return;
157
+ appendBarToStream(runner.foldStream, bar);
158
+ runner.output.append(evaluate(runner, runner.callback, false));
159
+ runner.processedHtfCount += 1;
160
+ }
161
+ function foldTick(runner, bar) {
162
+ if (runner.callback === undefined)
163
+ return;
164
+ replaceStreamHead(runner.foldStream, bar);
165
+ runner.output.replaceHead(evaluate(runner, runner.callback, true));
166
+ }
167
+ /**
168
+ * Drive every runner registered on `interval` for one secondary event. A
169
+ * `"close"` folds the bar into the fold stream and appends one sampled output;
170
+ * a `"tick"` replaces the fold head and the output head without advancing
171
+ * length. Runners whose callback is not yet captured are skipped — the first
172
+ * main compute replays their backlog via {@link captureAndCatchUp}.
173
+ *
174
+ * @since 0.7
175
+ * @stable
176
+ * @example
177
+ * // driveSecurityExpressions(ctx, "1W", "close", weeklyBar);
178
+ * const mode = "close";
179
+ * void mode;
180
+ */
181
+ export function driveSecurityExpressions(parent, interval, mode, bar) {
182
+ const runners = parent.securityExprRunnersByInterval?.get(interval);
183
+ if (runners === undefined)
184
+ return;
185
+ for (const runner of runners) {
186
+ if (mode === "close") {
187
+ foldClose(runner, bar);
188
+ }
189
+ else {
190
+ foldTick(runner, bar);
191
+ }
192
+ }
193
+ }
194
+ /**
195
+ * Store the callback the first time main compute provides it, then replay the
196
+ * real secondary stream oldest→newest through the runner's fold stream until
197
+ * `processedHtfCount === secondary.length`. Idempotent once the backlog is
198
+ * drained, so later calls in the same bar are no-ops.
199
+ *
200
+ * @since 0.7
201
+ * @stable
202
+ * @example
203
+ * // captureAndCatchUp(runner, expr, secondaryStream);
204
+ * const replayed = "oldest -> newest";
205
+ * void replayed;
206
+ */
207
+ export function captureAndCatchUp(runner, expr, secondary) {
208
+ if (runner.callback === undefined)
209
+ runner.callback = expr;
210
+ const length = secondary.ohlcv.close.length;
211
+ while (runner.processedHtfCount < length) {
212
+ const age = length - 1 - runner.processedHtfCount;
213
+ foldClose(runner, barFromStream(secondary, age));
214
+ }
215
+ }
216
+ /**
217
+ * Materialise a `Float64RingBuffer`'s values oldest→newest. Used as the
218
+ * `htfSeries` source when aligning a runner's output buffer to the main
219
+ * timeline.
220
+ *
221
+ * @since 0.7
222
+ * @stable
223
+ * @example
224
+ * // const values = ascendingValues(runner.output);
225
+ * const order = "oldest -> newest";
226
+ * void order;
227
+ */
228
+ export function ascendingValues(buffer) {
229
+ const values = [];
230
+ for (let age = buffer.length - 1; age >= 0; age -= 1) {
231
+ values.push(buffer.at(age));
232
+ }
233
+ return values;
234
+ }
235
+ //# sourceMappingURL=securityExprRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityExprRunner.js","sourceRoot":"","sources":["../../src/request/securityExprRunner.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type {\n Bar,\n ScriptManifest,\n SecurityBar,\n SecurityExpr,\n Series,\n} from \"@invinite-org/chartlang-core\";\n\nimport { ACTIVE_RUNTIME_CONTEXT, type RuntimeContext } from \"../runtimeContext.js\";\nimport { Float64RingBuffer } from \"../ringBuffer.js\";\nimport { advanceSeriesSlots, commitSeriesSlots, resetSeriesHeads } from \"../state/index.js\";\nimport { inMemoryStateStore } from \"../stateStore.js\";\nimport {\n type StreamState,\n appendBarToStream,\n createStreamState,\n replaceStreamHead,\n} from \"../streamState.js\";\nimport { createRuntimeViews } from \"../views/index.js\";\nimport { barFromStream, makeConstantStringSeries } from \"./streamBars.js\";\n\n/**\n * One mounted higher-timeframe expression unit. The compiler records each\n * `request.security({ interval }, (bar) => …)` callsite in\n * `manifest.securityExpressions`; the runtime mounts one runner per entry.\n *\n * The runner owns a dedicated fold {@link StreamState} clocked on the HTF\n * `interval`, a `Float64RingBuffer` output buffer (one sampled value per HTF\n * bar), a fold {@link SecurityBar} view backed by the fold stream's head, and\n * a private {@link RuntimeContext} (`stream = foldStream`,\n * `slotIdPrefix = \"security:<slotId>/\"`) so `ta.*` inside the callback\n * accumulate on the HTF clock without colliding with the main stream.\n *\n * `callback` is captured lazily the first time the main compute body calls\n * `request.security(slotId, opts, expr)`. `processedHtfCount` tracks how many\n * HTF bars have already been folded into `output` so replay catches up history\n * exactly once.\n *\n * @since 0.7\n * @stable\n * @example\n * // const runner = createSecurityExprRunner({ slotId: \"s#0\", interval: \"1W\",\n * // capacity: 64, parent });\n * const slotId = \"s#0\";\n * void slotId;\n */\nexport type SecurityExprRunner = {\n readonly slotId: string;\n readonly interval: string;\n readonly foldStream: StreamState;\n readonly foldBar: SecurityBar;\n readonly ctx: RuntimeContext;\n readonly output: Float64RingBuffer;\n callback?: SecurityExpr;\n processedHtfCount: number;\n};\n\n/**\n * The pair of lookup maps the runtime threads onto its {@link RuntimeContext}:\n * `bySlot` keyed by `slotId` (overload dispatch + capture) and `byInterval`\n * keyed by `IntervalDescriptor.value` (the fan-out from a secondary close).\n *\n * @since 0.7\n * @stable\n * @example\n * const registry: SecurityExprRegistry = {\n * bySlot: new Map(),\n * byInterval: new Map(),\n * };\n * void registry;\n */\nexport type SecurityExprRegistry = {\n readonly bySlot: Map<string, SecurityExprRunner>;\n readonly byInterval: ReadonlyMap<string, ReadonlyArray<SecurityExprRunner>>;\n};\n\nfunction makeFoldBar(foldStream: StreamState, interval: string): SecurityBar {\n const { seriesViews } = foldStream;\n return Object.freeze({\n time: seriesViews.time,\n open: seriesViews.open,\n high: seriesViews.high,\n low: seriesViews.low,\n close: seriesViews.close,\n volume: seriesViews.volume,\n hl2: seriesViews.hl2,\n hlc3: seriesViews.hlc3,\n ohlc4: seriesViews.ohlc4,\n hlcc4: seriesViews.hlcc4,\n symbol: makeConstantStringSeries(\"\"),\n interval: makeConstantStringSeries(interval),\n });\n}\n\nfunction buildExprContext(\n parent: RuntimeContext,\n slotId: string,\n foldStream: StreamState,\n): RuntimeContext {\n return {\n stream: foldStream,\n stateStore: inMemoryStateStore(),\n lastPersistTime: 0,\n capabilities: parent.capabilities,\n // A throwaway bag — the callback may not emit (Task 2 forbids\n // non-`ta` refs), but an isolated queue guards if it somehow does.\n emissions: {\n plots: [],\n drawings: [],\n alerts: [],\n alertConditions: [],\n logs: [],\n diagnostics: [],\n fromBar: 0,\n toBar: 0,\n },\n barIndex: () => foldStream.ohlcv.close.length - 1,\n isTick: false,\n drawingSlots: new Map(),\n drawingSubIdCounters: new Map(),\n drawingBucketCounters: { lines: 0, labels: 0, boxes: 0, polylines: 0, other: 0 },\n scriptMaxDrawings: null,\n stateSlots: new Map(),\n seriesSlots: new Map(),\n secondaryStreams: parent.secondaryStreams,\n requestSecurityBars: new Map(),\n requestSecurityAlignments: new Map(),\n requestSecurityAscendingBars: new Map(),\n requestLowerTfViews: new Map(),\n diagnosedRequestKeys: new Set(),\n logBudget: 0,\n logBudgetExceededDiagnosed: false,\n resolvedInputs: parent.resolvedInputs,\n defaultPane: parent.defaultPane,\n scriptPane: parent.scriptPane,\n plotOverrides: Object.freeze({}),\n diagnosedInputKeys: new Set(),\n views: createRuntimeViews(),\n slotIdPrefix: `security:${slotId}/`,\n };\n}\n\n/**\n * Construct one {@link SecurityExprRunner}. The fold stream and output buffer\n * share the secondary stream's `capacity` so a deep-lookback callback\n * (`ta.sma(bar.close, 50)`) has enough HTF history to warm up.\n *\n * @since 0.7\n * @stable\n * @example\n * // const runner = createSecurityExprRunner({ slotId: \"s#0\",\n * // interval: \"1W\", capacity: 64, parent });\n * const interval = \"1W\";\n * void interval;\n */\nexport function createSecurityExprRunner(args: {\n readonly slotId: string;\n readonly interval: string;\n readonly capacity: number;\n readonly parent: RuntimeContext;\n}): SecurityExprRunner {\n const { slotId, interval, capacity, parent } = args;\n const foldStream = createStreamState({ interval, capacity, symbol: \"\" });\n return {\n slotId,\n interval,\n foldStream,\n foldBar: makeFoldBar(foldStream, interval),\n ctx: buildExprContext(parent, slotId, foldStream),\n output: new Float64RingBuffer(capacity),\n processedHtfCount: 0,\n };\n}\n\n/**\n * Mount one runner per `manifest.securityExpressions` entry and return the\n * `bySlot` / `byInterval` lookup maps. Returns empty maps when the manifest\n * declares no expression callsites (the common single-timeframe case), so the\n * secondary-close drive pays a single empty-map check.\n *\n * @since 0.7\n * @stable\n * @example\n * // const registry = buildSecurityExprRunners(manifest, ctx, 64);\n * const built = \"bySlot + byInterval\";\n * void built;\n */\nexport function buildSecurityExprRunners(\n manifest: ScriptManifest,\n parent: RuntimeContext,\n capacity: number,\n): SecurityExprRegistry {\n const bySlot = new Map<string, SecurityExprRunner>();\n const byInterval = new Map<string, SecurityExprRunner[]>();\n for (const descriptor of manifest.securityExpressions ?? []) {\n const runner = createSecurityExprRunner({\n slotId: descriptor.slotId,\n interval: descriptor.interval,\n capacity,\n parent,\n });\n bySlot.set(descriptor.slotId, runner);\n const list = byInterval.get(descriptor.interval);\n if (list === undefined) {\n byInterval.set(descriptor.interval, [runner]);\n } else {\n list.push(runner);\n }\n }\n return { bySlot, byInterval };\n}\n\nfunction sampleOutput(result: Series<number> | number): number {\n return typeof result === \"number\" ? result : result.current;\n}\n\nfunction evaluate(runner: SecurityExprRunner, callback: SecurityExpr, isTick: boolean): number {\n const previous = ACTIVE_RUNTIME_CONTEXT.current;\n ACTIVE_RUNTIME_CONTEXT.current = runner.ctx;\n runner.ctx.isTick = isTick;\n // `state.series` inside the callback accumulates on the HTF clock, so it\n // advances/commits in lockstep with the fold stream — the same close/tick\n // discipline `runComputeBody` applies to the main compute.\n if (isTick) resetSeriesHeads(runner.ctx);\n else advanceSeriesSlots(runner.ctx);\n try {\n return sampleOutput(callback(runner.foldBar));\n } finally {\n if (!isTick) commitSeriesSlots(runner.ctx);\n runner.ctx.isTick = false;\n ACTIVE_RUNTIME_CONTEXT.current = previous;\n }\n}\n\nfunction foldClose(runner: SecurityExprRunner, bar: Bar): void {\n if (runner.callback === undefined) return;\n appendBarToStream(runner.foldStream, bar);\n runner.output.append(evaluate(runner, runner.callback, false));\n runner.processedHtfCount += 1;\n}\n\nfunction foldTick(runner: SecurityExprRunner, bar: Bar): void {\n if (runner.callback === undefined) return;\n replaceStreamHead(runner.foldStream, bar);\n runner.output.replaceHead(evaluate(runner, runner.callback, true));\n}\n\n/**\n * Drive every runner registered on `interval` for one secondary event. A\n * `\"close\"` folds the bar into the fold stream and appends one sampled output;\n * a `\"tick\"` replaces the fold head and the output head without advancing\n * length. Runners whose callback is not yet captured are skipped — the first\n * main compute replays their backlog via {@link captureAndCatchUp}.\n *\n * @since 0.7\n * @stable\n * @example\n * // driveSecurityExpressions(ctx, \"1W\", \"close\", weeklyBar);\n * const mode = \"close\";\n * void mode;\n */\nexport function driveSecurityExpressions(\n parent: RuntimeContext,\n interval: string,\n mode: \"close\" | \"tick\",\n bar: Bar,\n): void {\n const runners = parent.securityExprRunnersByInterval?.get(interval);\n if (runners === undefined) return;\n for (const runner of runners) {\n if (mode === \"close\") {\n foldClose(runner, bar);\n } else {\n foldTick(runner, bar);\n }\n }\n}\n\n/**\n * Store the callback the first time main compute provides it, then replay the\n * real secondary stream oldest→newest through the runner's fold stream until\n * `processedHtfCount === secondary.length`. Idempotent once the backlog is\n * drained, so later calls in the same bar are no-ops.\n *\n * @since 0.7\n * @stable\n * @example\n * // captureAndCatchUp(runner, expr, secondaryStream);\n * const replayed = \"oldest -> newest\";\n * void replayed;\n */\nexport function captureAndCatchUp(\n runner: SecurityExprRunner,\n expr: SecurityExpr,\n secondary: StreamState,\n): void {\n if (runner.callback === undefined) runner.callback = expr;\n const length = secondary.ohlcv.close.length;\n while (runner.processedHtfCount < length) {\n const age = length - 1 - runner.processedHtfCount;\n foldClose(runner, barFromStream(secondary, age));\n }\n}\n\n/**\n * Materialise a `Float64RingBuffer`'s values oldest→newest. Used as the\n * `htfSeries` source when aligning a runner's output buffer to the main\n * timeline.\n *\n * @since 0.7\n * @stable\n * @example\n * // const values = ascendingValues(runner.output);\n * const order = \"oldest -> newest\";\n * void order;\n */\nexport function ascendingValues(buffer: Float64RingBuffer): ReadonlyArray<number> {\n const values: number[] = [];\n for (let age = buffer.length - 1; age >= 0; age -= 1) {\n values.push(buffer.at(age));\n }\n return values;\n}\n"]}
@@ -1,6 +1,19 @@
1
- import type { Bar } from "@invinite-org/chartlang-core";
1
+ import type { Bar, Series } from "@invinite-org/chartlang-core";
2
2
  import type { RuntimeContext } from "../runtimeContext.js";
3
3
  import type { StreamState } from "../streamState.js";
4
+ /**
5
+ * A `Series<string>` whose every head-relative read returns a fixed `value`.
6
+ * Backs the `symbol` / `interval` fields of a materialised {@link SecurityBar}
7
+ * (both the data form's live bar and the expression form's fold bar), where the
8
+ * scalar is constant across history.
9
+ *
10
+ * @since 0.7
11
+ * @stable
12
+ * @example
13
+ * const s = makeConstantStringSeries("1W");
14
+ * void s.current; // "1W"
15
+ */
16
+ export declare function makeConstantStringSeries(value: string): Series<string>;
4
17
  /**
5
18
  * Materialise the bar at ring-buffer `age` from a stream state.
6
19
  *
@@ -1 +1 @@
1
- {"version":3,"file":"streamBars.d.ts","sourceRoot":"","sources":["../../src/request/streamBars.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAmBnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,CAS7F"}
1
+ {"version":3,"file":"streamBars.d.ts","sourceRoot":"","sources":["../../src/request/streamBars.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAS,MAAM,EAAc,MAAM,8BAA8B,CAAC;AAGnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAkBtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAyBnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,CAS7F"}
@@ -1,5 +1,38 @@
1
1
  // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
2
  // See the LICENSE file in the repo root for full license text.
3
+ import { resolveBarPoint } from "../barPoint.js";
4
+ /**
5
+ * A `Series<string>` whose every head-relative read returns a fixed `value`.
6
+ * Backs the `symbol` / `interval` fields of a materialised {@link SecurityBar}
7
+ * (both the data form's live bar and the expression form's fold bar), where the
8
+ * scalar is constant across history.
9
+ *
10
+ * @since 0.7
11
+ * @stable
12
+ * @example
13
+ * const s = makeConstantStringSeries("1W");
14
+ * void s.current; // "1W"
15
+ */
16
+ export function makeConstantStringSeries(value) {
17
+ const target = {
18
+ get current() {
19
+ return value;
20
+ },
21
+ get length() {
22
+ return 0;
23
+ },
24
+ };
25
+ return new Proxy(Object.freeze(target), {
26
+ get(obj, prop, receiver) {
27
+ if (typeof prop === "string") {
28
+ const n = Number(prop);
29
+ if (Number.isInteger(n) && n >= 0)
30
+ return value;
31
+ }
32
+ return Reflect.get(obj, prop, receiver);
33
+ },
34
+ });
35
+ }
3
36
  /**
4
37
  * Materialise the bar at ring-buffer `age` from a stream state.
5
38
  *
@@ -15,8 +48,9 @@ export function barFromStream(stream, age) {
15
48
  const high = stream.ohlcv.high.at(age);
16
49
  const low = stream.ohlcv.low.at(age);
17
50
  const close = stream.ohlcv.close.at(age);
51
+ const barTime = stream.ohlcv.time.at(age);
18
52
  return {
19
- time: stream.ohlcv.time.at(age),
53
+ time: barTime,
20
54
  open,
21
55
  high,
22
56
  low,
@@ -28,6 +62,10 @@ export function barFromStream(stream, age) {
28
62
  hlc3: (high + low + close) / 3,
29
63
  ohlc4: (open + high + low + close) / 4,
30
64
  hlcc4: (high + low + close + close) / 4,
65
+ // Anchored at this materialised bar's own `age`: a negative offset
66
+ // reads `time.at(age - offset)` (further back in this stream's
67
+ // history) so a snapshot bar's offsets stay relative to itself.
68
+ point: (offset, price) => resolveBarPoint(stream.ohlcv.time, stream.bar.interval, barTime, offset - age, price),
31
69
  };
32
70
  }
33
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"streamBars.js","sourceRoot":"","sources":["../../src/request/streamBars.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAO/D;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,MAAmB,EAAE,GAAW;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO;QACH,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;QAC/B,IAAI;QACJ,IAAI;QACJ,GAAG;QACH,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM;QACzB,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ;QAC7B,GAAG,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;QACrB,IAAI,EAAE,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QAC9B,KAAK,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QACtC,KAAK,EAAE,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC;KAC1C,CAAC;AACN,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAmB,EAAE,MAAmB;IACrE,MAAM,MAAM,GAAG,GAAG,CAAC,4BAA4B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,IAAI,GAAU,EAAE,CAAC;IACvB,KAAK,IAAI,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAC/D,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,GAAG,CAAC,4BAA4B,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"streamBars.js","sourceRoot":"","sources":["../../src/request/streamBars.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { Bar, Price, Series, WorldPoint } from \"@invinite-org/chartlang-core\";\n\nimport { resolveBarPoint } from \"../barPoint.js\";\nimport type { RuntimeContext } from \"../runtimeContext.js\";\nimport type { StreamState } from \"../streamState.js\";\n\n/**\n * A `Series<string>` whose every head-relative read returns a fixed `value`.\n * Backs the `symbol` / `interval` fields of a materialised {@link SecurityBar}\n * (both the data form's live bar and the expression form's fold bar), where the\n * scalar is constant across history.\n *\n * @since 0.7\n * @stable\n * @example\n * const s = makeConstantStringSeries(\"1W\");\n * void s.current; // \"1W\"\n */\nexport function makeConstantStringSeries(value: string): Series<string> {\n const target = {\n get current() {\n return value;\n },\n get length() {\n return 0;\n },\n };\n return new Proxy(Object.freeze(target), {\n get(obj, prop, receiver) {\n if (typeof prop === \"string\") {\n const n = Number(prop);\n if (Number.isInteger(n) && n >= 0) return value;\n }\n return Reflect.get(obj, prop, receiver);\n },\n }) as Series<string>;\n}\n\n/**\n * Materialise the bar at ring-buffer `age` from a stream state.\n *\n * @since 0.6\n * @stable\n * @example\n * // const bar = barFromStream(stream, 0);\n * const age = 0;\n * void age;\n */\nexport function barFromStream(stream: StreamState, age: number): Bar {\n const open = stream.ohlcv.open.at(age);\n const high = stream.ohlcv.high.at(age);\n const low = stream.ohlcv.low.at(age);\n const close = stream.ohlcv.close.at(age);\n const barTime = stream.ohlcv.time.at(age);\n return {\n time: barTime,\n open,\n high,\n low,\n close,\n volume: stream.ohlcv.volume.at(age),\n symbol: stream.bar.symbol,\n interval: stream.bar.interval,\n hl2: (high + low) / 2,\n hlc3: (high + low + close) / 3,\n ohlc4: (open + high + low + close) / 4,\n hlcc4: (high + low + close + close) / 4,\n // Anchored at this materialised bar's own `age`: a negative offset\n // reads `time.at(age - offset)` (further back in this stream's\n // history) so a snapshot bar's offsets stay relative to itself.\n point: (offset: number, price: Price): WorldPoint =>\n resolveBarPoint(stream.ohlcv.time, stream.bar.interval, barTime, offset - age, price),\n };\n}\n\n/**\n * Return a stream's bars in ascending time order, memoised per step on\n * `ctx.requestSecurityAscendingBars` (cleared each bar close).\n *\n * @since 0.6\n * @stable\n * @example\n * // const bars = ascendingBarsFor(ctx, ctx.stream);\n * const memo = \"requestSecurityAscendingBars\";\n * void memo;\n */\nexport function ascendingBarsFor(ctx: RuntimeContext, stream: StreamState): ReadonlyArray<Bar> {\n const cached = ctx.requestSecurityAscendingBars.get(stream);\n if (cached !== undefined) return cached;\n const bars: Bar[] = [];\n for (let age = stream.ohlcv.close.length - 1; age >= 0; age -= 1) {\n bars.push(barFromStream(stream, age));\n }\n ctx.requestSecurityAscendingBars.set(stream, bars);\n return bars;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Shared contract for the two ring-buffer flavours the runtime ships
3
3
  * (`RingBuffer<T>` for object payloads, `Float64RingBuffer` for numeric
4
- * payloads). Mirrors PLAN.md §6.6 — `at(n)` returns `undefined` on
4
+ * payloads). Both share one read contract — `at(n)` returns `undefined` on
5
5
  * out-of-range reads in the generic shape; `Float64RingBuffer` narrows
6
6
  * the return to `number` with `NaN` as the OOR sentinel.
7
7
  *
@@ -54,7 +54,7 @@ export declare class RingBuffer<T> implements RingBufferLike<T> {
54
54
  /**
55
55
  * Numeric ring buffer backed by a `Float64Array`. Reads are direct
56
56
  * memory hits — no boxing, no map lookup. Out-of-range reads return
57
- * `NaN` (the language-wide warmup sentinel per PLAN.md §6.3), which
57
+ * `NaN` (the language-wide warmup sentinel), which
58
58
  * is the correct value for unwarmed indicator slots.
59
59
  *
60
60
  * `at(n)` narrows the shared `RingBufferLike<T>`'s `T | undefined`
@@ -59,7 +59,7 @@ export class RingBuffer {
59
59
  /**
60
60
  * Numeric ring buffer backed by a `Float64Array`. Reads are direct
61
61
  * memory hits — no boxing, no map lookup. Out-of-range reads return
62
- * `NaN` (the language-wide warmup sentinel per PLAN.md §6.3), which
62
+ * `NaN` (the language-wide warmup sentinel), which
63
63
  * is the correct value for unwarmed indicator slots.
64
64
  *
65
65
  * `at(n)` narrows the shared `RingBufferLike<T>`'s `T | undefined`
@@ -1 +1 @@
1
- {"version":3,"file":"ringBuffer.js","sourceRoot":"","sources":["../src/ringBuffer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ringBuffer.js","sourceRoot":"","sources":["../src/ringBuffer.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAwB/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,UAAU;IAKS;IAJpB,GAAG,CAAuB;IAC1B,IAAI,GAAG,CAAC,CAAC,CAAC;IACV,MAAM,GAAG,CAAC,CAAC;IAEnB,YAA4B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,KAAK,CAAgB,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,CAAI;QACP,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,WAAW,CAAC,CAAI;QACZ,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACf,OAAO;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,EAAE,CAAC,CAAS;QACR,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAChD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,KAAK;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,KAAK,CAAgB,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,iBAAiB;IAKE;IAJpB,GAAG,CAAe;IAClB,IAAI,GAAG,CAAC,CAAC,CAAC;IACV,MAAM,GAAG,CAAC,CAAC;IAEnB,YAA4B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,CAAC,CAAS;QACZ,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,WAAW,CAAC,CAAS;QACjB,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACf,OAAO;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,EAAE,CAAC,CAAS;QACR,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC;QACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,uBAAuB;QAKnB,MAAM,MAAM,GAAyB,EAAE,CAAC;QACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;YACjB,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;SAChC,CAAC,CAAC;IACP,CAAC;IAED,yBAAyB,CACrB,IAIE;QAEF,IACI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ;YACpC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YACjC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ;YAC/B,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,CAAC;YACf,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ;YAC3B,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;YAC5C,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,EACzC,CAAC;YACC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,CAAC;CACJ","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\n/**\n * Shared contract for the two ring-buffer flavours the runtime ships\n * (`RingBuffer<T>` for object payloads, `Float64RingBuffer` for numeric\n * payloads). Both share one read contract — `at(n)` returns `undefined` on\n * out-of-range reads in the generic shape; `Float64RingBuffer` narrows\n * the return to `number` with `NaN` as the OOR sentinel.\n *\n * @since 0.1\n * @example\n * const buf: RingBufferLike<number> = new Float64RingBuffer(8);\n * buf.append(42);\n * buf.at(0); // 42\n */\nexport interface RingBufferLike<T> {\n readonly capacity: number;\n readonly length: number;\n append(v: T): void;\n replaceHead(v: T): void;\n at(n: number): T | undefined;\n reset(): void;\n}\n\n/**\n * Generic ring buffer over an `Array<T>`. Backs object-valued\n * `Series<T>` (e.g. Phase-3 drawing handles). For numeric series use\n * `Float64RingBuffer` — it avoids the array-pointer indirection on\n * every read.\n *\n * Out-of-range `at(n)` returns `undefined`. `replaceHead` on an empty\n * buffer behaves like `append` so the first call after construction\n * does not need a special-case branch in callers.\n *\n * @since 0.1\n * @example\n * const buf = new RingBuffer<string>(3);\n * buf.append(\"a\");\n * buf.append(\"b\");\n * buf.append(\"c\");\n * buf.append(\"d\"); // overwrites \"a\"\n * buf.at(0); // \"d\"\n * buf.at(2); // \"b\"\n */\nexport class RingBuffer<T> implements RingBufferLike<T> {\n private buf: Array<T | undefined>;\n private head = -1;\n private filled = 0;\n\n constructor(public readonly capacity: number) {\n this.buf = new Array<T | undefined>(capacity);\n }\n\n append(v: T): void {\n this.head = (this.head + 1) % this.capacity;\n this.buf[this.head] = v;\n if (this.filled < this.capacity) this.filled += 1;\n }\n\n replaceHead(v: T): void {\n if (this.head === -1) {\n this.append(v);\n return;\n }\n this.buf[this.head] = v;\n }\n\n at(n: number): T | undefined {\n if (n < 0 || n >= this.filled) return undefined;\n return this.buf[(this.head - n + this.capacity) % this.capacity];\n }\n\n get length(): number {\n return this.filled;\n }\n\n reset(): void {\n this.buf = new Array<T | undefined>(this.capacity);\n this.head = -1;\n this.filled = 0;\n }\n}\n\n/**\n * Numeric ring buffer backed by a `Float64Array`. Reads are direct\n * memory hits — no boxing, no map lookup. Out-of-range reads return\n * `NaN` (the language-wide warmup sentinel), which\n * is the correct value for unwarmed indicator slots.\n *\n * `at(n)` narrows the shared `RingBufferLike<T>`'s `T | undefined`\n * return to plain `number` in a covariant return position; callers\n * that hold this concrete class see `number`, callers that hold\n * the wider interface see `number | undefined`.\n *\n * @since 0.1\n * @example\n * const buf = new Float64RingBuffer(4);\n * buf.append(1.0);\n * buf.append(2.0);\n * buf.at(0); // 2\n * buf.at(5); // NaN\n */\nexport class Float64RingBuffer implements RingBufferLike<number> {\n private buf: Float64Array;\n private head = -1;\n private filled = 0;\n\n constructor(public readonly capacity: number) {\n this.buf = new Float64Array(capacity);\n }\n\n append(v: number): void {\n this.head = (this.head + 1) % this.capacity;\n this.buf[this.head] = v;\n if (this.filled < this.capacity) this.filled += 1;\n }\n\n replaceHead(v: number): void {\n if (this.head === -1) {\n this.append(v);\n return;\n }\n this.buf[this.head] = v;\n }\n\n at(n: number): number {\n if (n < 0 || n >= this.filled) return Number.NaN;\n return this.buf[(this.head - n + this.capacity) % this.capacity];\n }\n\n get length(): number {\n return this.filled;\n }\n\n serialiseSnapshotBuffer(): Readonly<{\n headIndex: number;\n filled: number;\n values: ReadonlyArray<number | null>;\n }> {\n const values: Array<number | null> = [];\n for (const value of this.buf) {\n values.push(Number.isNaN(value) ? null : value);\n }\n return Object.freeze({\n headIndex: this.head,\n filled: this.filled,\n values: Object.freeze(values),\n });\n }\n\n restoreFromSnapshotBuffer(\n args: Readonly<{\n headIndex: number;\n filled: number;\n values: ReadonlyArray<number | null>;\n }>,\n ): void {\n if (\n args.values.length !== this.capacity ||\n !Number.isInteger(args.headIndex) ||\n args.headIndex < -1 ||\n args.headIndex >= this.capacity ||\n !Number.isInteger(args.filled) ||\n args.filled < 0 ||\n args.filled > this.capacity ||\n (args.filled === 0 && args.headIndex !== -1) ||\n (args.filled > 0 && args.headIndex < 0)\n ) {\n throw new Error(\"invalid ring buffer snapshot\");\n }\n const next = new Float64Array(this.capacity);\n for (let i = 0; i < args.values.length; i += 1) {\n const value = args.values[i];\n next[i] = value === null ? Number.NaN : value;\n }\n this.buf = next;\n this.head = args.headIndex;\n this.filled = args.filled;\n }\n\n reset(): void {\n this.buf = new Float64Array(this.capacity);\n this.head = -1;\n this.filled = 0;\n }\n}\n"]}