@363045841yyt/klinechart-core 0.8.11-alpha.0 → 0.8.12

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 (578) hide show
  1. package/dist/alerts/createAlertController.d.ts +30 -0
  2. package/dist/alerts/createAlertController.d.ts.map +1 -0
  3. package/dist/alerts/createAlertController.js +261 -0
  4. package/dist/alerts/createAlertController.js.map +1 -0
  5. package/dist/alerts/index.d.ts +5 -0
  6. package/dist/alerts/index.d.ts.map +1 -0
  7. package/dist/alerts/index.js +4 -0
  8. package/dist/alerts/index.js.map +1 -0
  9. package/dist/alerts/predicates.d.ts +28 -0
  10. package/dist/alerts/predicates.d.ts.map +1 -0
  11. package/dist/alerts/predicates.js +211 -0
  12. package/dist/alerts/predicates.js.map +1 -0
  13. package/dist/alerts/rollingVolume.d.ts +15 -0
  14. package/dist/alerts/rollingVolume.d.ts.map +1 -0
  15. package/dist/alerts/rollingVolume.js +42 -0
  16. package/dist/alerts/rollingVolume.js.map +1 -0
  17. package/dist/alerts/ruleSchema.d.ts +42 -0
  18. package/dist/alerts/ruleSchema.d.ts.map +1 -0
  19. package/dist/alerts/ruleSchema.js +240 -0
  20. package/dist/alerts/ruleSchema.js.map +1 -0
  21. package/dist/alerts/types.d.ts +169 -0
  22. package/dist/alerts/types.d.ts.map +1 -0
  23. package/dist/alerts/types.js +24 -0
  24. package/dist/alerts/types.js.map +1 -0
  25. package/dist/chartTypes/heikinAshi.d.ts +49 -0
  26. package/dist/chartTypes/heikinAshi.d.ts.map +1 -0
  27. package/dist/chartTypes/heikinAshi.js +94 -0
  28. package/dist/chartTypes/heikinAshi.js.map +1 -0
  29. package/dist/chartTypes/index.d.ts +6 -0
  30. package/dist/chartTypes/index.d.ts.map +1 -0
  31. package/dist/chartTypes/index.js +5 -0
  32. package/dist/chartTypes/index.js.map +1 -0
  33. package/dist/chartTypes/pointAndFigure.d.ts +83 -0
  34. package/dist/chartTypes/pointAndFigure.d.ts.map +1 -0
  35. package/dist/chartTypes/pointAndFigure.js +159 -0
  36. package/dist/chartTypes/pointAndFigure.js.map +1 -0
  37. package/dist/chartTypes/rangeBars.d.ts +61 -0
  38. package/dist/chartTypes/rangeBars.d.ts.map +1 -0
  39. package/dist/chartTypes/rangeBars.js +181 -0
  40. package/dist/chartTypes/rangeBars.js.map +1 -0
  41. package/dist/chartTypes/renko.d.ts +94 -0
  42. package/dist/chartTypes/renko.d.ts.map +1 -0
  43. package/dist/chartTypes/renko.js +207 -0
  44. package/dist/chartTypes/renko.js.map +1 -0
  45. package/dist/chartTypes/types.d.ts +97 -0
  46. package/dist/chartTypes/types.d.ts.map +1 -0
  47. package/dist/chartTypes/types.js +39 -0
  48. package/dist/chartTypes/types.js.map +1 -0
  49. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts +76 -0
  50. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts.map +1 -0
  51. package/dist/components/anchoredVwap/computeAnchoredVwap.js +155 -0
  52. package/dist/components/anchoredVwap/computeAnchoredVwap.js.map +1 -0
  53. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts +28 -0
  54. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts.map +1 -0
  55. package/dist/components/anchoredVwap/createAnchoredVwapController.js +282 -0
  56. package/dist/components/anchoredVwap/createAnchoredVwapController.js.map +1 -0
  57. package/dist/components/anchoredVwap/index.d.ts +11 -0
  58. package/dist/components/anchoredVwap/index.d.ts.map +1 -0
  59. package/dist/components/anchoredVwap/index.js +10 -0
  60. package/dist/components/anchoredVwap/index.js.map +1 -0
  61. package/dist/components/anchoredVwap/types.d.ts +171 -0
  62. package/dist/components/anchoredVwap/types.d.ts.map +1 -0
  63. package/dist/components/anchoredVwap/types.js +25 -0
  64. package/dist/components/anchoredVwap/types.js.map +1 -0
  65. package/dist/components/crosshairSync/createCrosshairSync.d.ts +94 -0
  66. package/dist/components/crosshairSync/createCrosshairSync.d.ts.map +1 -0
  67. package/dist/components/crosshairSync/createCrosshairSync.js +118 -0
  68. package/dist/components/crosshairSync/createCrosshairSync.js.map +1 -0
  69. package/dist/components/crosshairSync/index.d.ts +2 -0
  70. package/dist/components/crosshairSync/index.d.ts.map +1 -0
  71. package/dist/components/crosshairSync/index.js +2 -0
  72. package/dist/components/crosshairSync/index.js.map +1 -0
  73. package/dist/components/footprint/aggressor.d.ts +89 -0
  74. package/dist/components/footprint/aggressor.d.ts.map +1 -0
  75. package/dist/components/footprint/aggressor.js +106 -0
  76. package/dist/components/footprint/aggressor.js.map +1 -0
  77. package/dist/components/footprint/createFootprintController.d.ts +29 -0
  78. package/dist/components/footprint/createFootprintController.d.ts.map +1 -0
  79. package/dist/components/footprint/createFootprintController.js +264 -0
  80. package/dist/components/footprint/createFootprintController.js.map +1 -0
  81. package/dist/components/footprint/index.d.ts +7 -0
  82. package/dist/components/footprint/index.d.ts.map +1 -0
  83. package/dist/components/footprint/index.js +4 -0
  84. package/dist/components/footprint/index.js.map +1 -0
  85. package/dist/components/footprint/perBarStats.d.ts +63 -0
  86. package/dist/components/footprint/perBarStats.d.ts.map +1 -0
  87. package/dist/components/footprint/perBarStats.js +123 -0
  88. package/dist/components/footprint/perBarStats.js.map +1 -0
  89. package/dist/components/footprint/types.d.ts +197 -0
  90. package/dist/components/footprint/types.d.ts.map +1 -0
  91. package/dist/components/footprint/types.js +23 -0
  92. package/dist/components/footprint/types.js.map +1 -0
  93. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts +45 -0
  94. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts.map +1 -0
  95. package/dist/components/mtfOverlay/alignToBaseIndex.js +92 -0
  96. package/dist/components/mtfOverlay/alignToBaseIndex.js.map +1 -0
  97. package/dist/components/mtfOverlay/createMtfController.d.ts +7 -0
  98. package/dist/components/mtfOverlay/createMtfController.d.ts.map +1 -0
  99. package/dist/components/mtfOverlay/createMtfController.js +134 -0
  100. package/dist/components/mtfOverlay/createMtfController.js.map +1 -0
  101. package/dist/components/mtfOverlay/index.d.ts +19 -0
  102. package/dist/components/mtfOverlay/index.d.ts.map +1 -0
  103. package/dist/components/mtfOverlay/index.js +18 -0
  104. package/dist/components/mtfOverlay/index.js.map +1 -0
  105. package/dist/components/mtfOverlay/resampleBars.d.ts +37 -0
  106. package/dist/components/mtfOverlay/resampleBars.d.ts.map +1 -0
  107. package/dist/components/mtfOverlay/resampleBars.js +93 -0
  108. package/dist/components/mtfOverlay/resampleBars.js.map +1 -0
  109. package/dist/components/mtfOverlay/types.d.ts +132 -0
  110. package/dist/components/mtfOverlay/types.d.ts.map +1 -0
  111. package/dist/components/mtfOverlay/types.js +22 -0
  112. package/dist/components/mtfOverlay/types.js.map +1 -0
  113. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts +21 -0
  114. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts.map +1 -0
  115. package/dist/components/orderBookHeatmap/createHeatmapController.js +234 -0
  116. package/dist/components/orderBookHeatmap/createHeatmapController.js.map +1 -0
  117. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts +18 -0
  118. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts.map +1 -0
  119. package/dist/components/orderBookHeatmap/createOrderBookState.js +102 -0
  120. package/dist/components/orderBookHeatmap/createOrderBookState.js.map +1 -0
  121. package/dist/components/orderBookHeatmap/deltaArchive.d.ts +25 -0
  122. package/dist/components/orderBookHeatmap/deltaArchive.d.ts.map +1 -0
  123. package/dist/components/orderBookHeatmap/deltaArchive.js +106 -0
  124. package/dist/components/orderBookHeatmap/deltaArchive.js.map +1 -0
  125. package/dist/components/orderBookHeatmap/index.d.ts +13 -0
  126. package/dist/components/orderBookHeatmap/index.d.ts.map +1 -0
  127. package/dist/components/orderBookHeatmap/index.js +12 -0
  128. package/dist/components/orderBookHeatmap/index.js.map +1 -0
  129. package/dist/components/orderBookHeatmap/logColorScale.d.ts +20 -0
  130. package/dist/components/orderBookHeatmap/logColorScale.d.ts.map +1 -0
  131. package/dist/components/orderBookHeatmap/logColorScale.js +71 -0
  132. package/dist/components/orderBookHeatmap/logColorScale.js.map +1 -0
  133. package/dist/components/orderBookHeatmap/snapshotRing.d.ts +16 -0
  134. package/dist/components/orderBookHeatmap/snapshotRing.d.ts.map +1 -0
  135. package/dist/components/orderBookHeatmap/snapshotRing.js +61 -0
  136. package/dist/components/orderBookHeatmap/snapshotRing.js.map +1 -0
  137. package/dist/components/orderBookHeatmap/types.d.ts +128 -0
  138. package/dist/components/orderBookHeatmap/types.d.ts.map +1 -0
  139. package/dist/components/orderBookHeatmap/types.js +16 -0
  140. package/dist/components/orderBookHeatmap/types.js.map +1 -0
  141. package/dist/components/volumeProfile/binning.d.ts +54 -0
  142. package/dist/components/volumeProfile/binning.d.ts.map +1 -0
  143. package/dist/components/volumeProfile/binning.js +123 -0
  144. package/dist/components/volumeProfile/binning.js.map +1 -0
  145. package/dist/components/volumeProfile/createVolumeProfileController.d.ts +31 -0
  146. package/dist/components/volumeProfile/createVolumeProfileController.d.ts.map +1 -0
  147. package/dist/components/volumeProfile/createVolumeProfileController.js +179 -0
  148. package/dist/components/volumeProfile/createVolumeProfileController.js.map +1 -0
  149. package/dist/components/volumeProfile/index.d.ts +6 -0
  150. package/dist/components/volumeProfile/index.d.ts.map +1 -0
  151. package/dist/components/volumeProfile/index.js +5 -0
  152. package/dist/components/volumeProfile/index.js.map +1 -0
  153. package/dist/components/volumeProfile/poc.d.ts +35 -0
  154. package/dist/components/volumeProfile/poc.d.ts.map +1 -0
  155. package/dist/components/volumeProfile/poc.js +51 -0
  156. package/dist/components/volumeProfile/poc.js.map +1 -0
  157. package/dist/components/volumeProfile/types.d.ts +138 -0
  158. package/dist/components/volumeProfile/types.d.ts.map +1 -0
  159. package/dist/components/volumeProfile/types.js +19 -0
  160. package/dist/components/volumeProfile/types.js.map +1 -0
  161. package/dist/components/volumeProfile/valueArea.d.ts +58 -0
  162. package/dist/components/volumeProfile/valueArea.d.ts.map +1 -0
  163. package/dist/components/volumeProfile/valueArea.js +172 -0
  164. package/dist/components/volumeProfile/valueArea.js.map +1 -0
  165. package/dist/controllers/createChartController.d.ts.map +1 -1
  166. package/dist/controllers/createChartController.js +22 -11
  167. package/dist/controllers/createChartController.js.map +1 -1
  168. package/dist/controllers/types.d.ts +3 -1
  169. package/dist/controllers/types.d.ts.map +1 -1
  170. package/dist/data-fetchers/baostock.d.ts.map +1 -1
  171. package/dist/data-fetchers/baostock.js +2 -1
  172. package/dist/data-fetchers/baostock.js.map +1 -1
  173. package/dist/data-fetchers/dataBuffer.effects.d.ts.map +1 -1
  174. package/dist/data-fetchers/dataBuffer.effects.js +2 -1
  175. package/dist/data-fetchers/dataBuffer.effects.js.map +1 -1
  176. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
  177. package/dist/data-fetchers/fetcherDefinitionRegistry.js +2 -1
  178. package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
  179. package/dist/data-fetchers/gotdx.js +4 -3
  180. package/dist/data-fetchers/gotdx.js.map +1 -1
  181. package/dist/data-fetchers/router.d.ts.map +1 -1
  182. package/dist/data-fetchers/router.js +4 -3
  183. package/dist/data-fetchers/router.js.map +1 -1
  184. package/dist/data-fetchers/tradingview.js +3 -2
  185. package/dist/data-fetchers/tradingview.js.map +1 -1
  186. package/dist/engine/chart.d.ts +13 -0
  187. package/dist/engine/chart.d.ts.map +1 -1
  188. package/dist/engine/chart.js +109 -0
  189. package/dist/engine/chart.js.map +1 -1
  190. package/dist/engine/data/chartDataManager.d.ts +1 -0
  191. package/dist/engine/data/chartDataManager.d.ts.map +1 -1
  192. package/dist/engine/data/chartDataManager.js +27 -4
  193. package/dist/engine/data/chartDataManager.js.map +1 -1
  194. package/dist/engine/drawing/toolConfig.d.ts.map +1 -1
  195. package/dist/engine/drawing/toolConfig.js +2 -1
  196. package/dist/engine/drawing/toolConfig.js.map +1 -1
  197. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  198. package/dist/engine/indicators/chartIndicatorManager.js +2 -1
  199. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  200. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  201. package/dist/engine/indicators/indicatorDefinitionRegistry.js +2 -1
  202. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  203. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  204. package/dist/engine/indicators/indicatorMetadata.js +2 -1
  205. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  206. package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
  207. package/dist/engine/indicators/indicatorRegistry.js +6 -5
  208. package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
  209. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
  210. package/dist/engine/indicators/registerBuiltins.js +2 -1
  211. package/dist/engine/indicators/registerBuiltins.js.map +1 -1
  212. package/dist/engine/indicators/scheduler.d.ts +6 -0
  213. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  214. package/dist/engine/indicators/scheduler.js +12 -0
  215. package/dist/engine/indicators/scheduler.js.map +1 -1
  216. package/dist/engine/indicators/soa.d.ts.map +1 -1
  217. package/dist/engine/indicators/soa.js +2 -1
  218. package/dist/engine/indicators/soa.js.map +1 -1
  219. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  220. package/dist/engine/indicators/stateComposer.js +2 -1
  221. package/dist/engine/indicators/stateComposer.js.map +1 -1
  222. package/dist/engine/subPaneManager.d.ts.map +1 -1
  223. package/dist/engine/subPaneManager.js +2 -1
  224. package/dist/engine/subPaneManager.js.map +1 -1
  225. package/dist/engine/utils/chartZoomController.d.ts +2 -0
  226. package/dist/engine/utils/chartZoomController.d.ts.map +1 -1
  227. package/dist/engine/utils/chartZoomController.js +5 -1
  228. package/dist/engine/utils/chartZoomController.js.map +1 -1
  229. package/dist/errors-help.d.ts +72 -0
  230. package/dist/errors-help.d.ts.map +1 -0
  231. package/dist/errors-help.js +149 -0
  232. package/dist/errors-help.js.map +1 -0
  233. package/dist/errors.d.ts +64 -0
  234. package/dist/errors.d.ts.map +1 -0
  235. package/dist/errors.js +61 -0
  236. package/dist/errors.js.map +1 -0
  237. package/dist/index.d.ts +18 -0
  238. package/dist/index.d.ts.map +1 -1
  239. package/dist/index.js +22 -0
  240. package/dist/index.js.map +1 -1
  241. package/dist/indicators/alma.d.ts +27 -0
  242. package/dist/indicators/alma.d.ts.map +1 -0
  243. package/dist/indicators/alma.js +36 -0
  244. package/dist/indicators/alma.js.map +1 -0
  245. package/dist/indicators/awesomeOscillator.d.ts +19 -0
  246. package/dist/indicators/awesomeOscillator.d.ts.map +1 -0
  247. package/dist/indicators/awesomeOscillator.js +36 -0
  248. package/dist/indicators/awesomeOscillator.js.map +1 -0
  249. package/dist/indicators/dpo.d.ts +17 -0
  250. package/dist/indicators/dpo.d.ts.map +1 -0
  251. package/dist/indicators/dpo.js +24 -0
  252. package/dist/indicators/dpo.js.map +1 -0
  253. package/dist/indicators/fisherTransform.d.ts +26 -0
  254. package/dist/indicators/fisherTransform.d.ts.map +1 -0
  255. package/dist/indicators/fisherTransform.js +44 -0
  256. package/dist/indicators/fisherTransform.js.map +1 -0
  257. package/dist/indicators/frama.d.ts +25 -0
  258. package/dist/indicators/frama.d.ts.map +1 -0
  259. package/dist/indicators/frama.js +61 -0
  260. package/dist/indicators/frama.js.map +1 -0
  261. package/dist/indicators/index.d.ts +24 -0
  262. package/dist/indicators/index.d.ts.map +1 -0
  263. package/dist/indicators/index.js +26 -0
  264. package/dist/indicators/index.js.map +1 -0
  265. package/dist/indicators/lsma.d.ts +21 -0
  266. package/dist/indicators/lsma.d.ts.map +1 -0
  267. package/dist/indicators/lsma.js +37 -0
  268. package/dist/indicators/lsma.js.map +1 -0
  269. package/dist/indicators/schaffTrendCycle.d.ts +24 -0
  270. package/dist/indicators/schaffTrendCycle.d.ts.map +1 -0
  271. package/dist/indicators/schaffTrendCycle.js +70 -0
  272. package/dist/indicators/schaffTrendCycle.js.map +1 -0
  273. package/dist/indicators/stochRSI.d.ts +24 -0
  274. package/dist/indicators/stochRSI.d.ts.map +1 -0
  275. package/dist/indicators/stochRSI.js +86 -0
  276. package/dist/indicators/stochRSI.js.map +1 -0
  277. package/dist/indicators/t3.d.ts +31 -0
  278. package/dist/indicators/t3.d.ts.map +1 -0
  279. package/dist/indicators/t3.js +63 -0
  280. package/dist/indicators/t3.js.map +1 -0
  281. package/dist/indicators/ultimateOscillator.d.ts +26 -0
  282. package/dist/indicators/ultimateOscillator.d.ts.map +1 -0
  283. package/dist/indicators/ultimateOscillator.js +59 -0
  284. package/dist/indicators/ultimateOscillator.js.map +1 -0
  285. package/dist/indicators/vidya.d.ts +24 -0
  286. package/dist/indicators/vidya.d.ts.map +1 -0
  287. package/dist/indicators/vidya.js +54 -0
  288. package/dist/indicators/vidya.js.map +1 -0
  289. package/dist/indicators/zlema.d.ts +16 -0
  290. package/dist/indicators/zlema.d.ts.map +1 -0
  291. package/dist/indicators/zlema.js +26 -0
  292. package/dist/indicators/zlema.js.map +1 -0
  293. package/dist/input/gesture.d.ts +125 -0
  294. package/dist/input/gesture.d.ts.map +1 -0
  295. package/dist/input/gesture.js +249 -0
  296. package/dist/input/gesture.js.map +1 -0
  297. package/dist/input/index.d.ts +9 -0
  298. package/dist/input/index.d.ts.map +1 -0
  299. package/dist/input/index.js +9 -0
  300. package/dist/input/index.js.map +1 -0
  301. package/dist/input/keyboard.d.ts +140 -0
  302. package/dist/input/keyboard.d.ts.map +1 -0
  303. package/dist/input/keyboard.js +260 -0
  304. package/dist/input/keyboard.js.map +1 -0
  305. package/dist/mcp/chartBridge.d.ts +2 -2
  306. package/dist/mcp/chartBridge.d.ts.map +1 -1
  307. package/dist/mcp/chartBridge.js +27 -21
  308. package/dist/mcp/chartBridge.js.map +1 -1
  309. package/dist/plugin/PluginHost.d.ts +0 -3
  310. package/dist/plugin/PluginHost.d.ts.map +1 -1
  311. package/dist/plugin/PluginHost.js +7 -3
  312. package/dist/plugin/PluginHost.js.map +1 -1
  313. package/dist/plugin/PluginRegistry.d.ts +0 -3
  314. package/dist/plugin/PluginRegistry.d.ts.map +1 -1
  315. package/dist/plugin/PluginRegistry.js +5 -1
  316. package/dist/plugin/PluginRegistry.js.map +1 -1
  317. package/dist/render/Renderer.d.ts +116 -0
  318. package/dist/render/Renderer.d.ts.map +1 -0
  319. package/dist/render/Renderer.js +31 -0
  320. package/dist/render/Renderer.js.map +1 -0
  321. package/dist/render/SurfaceBackend.d.ts +83 -0
  322. package/dist/render/SurfaceBackend.d.ts.map +1 -0
  323. package/dist/render/SurfaceBackend.js +27 -0
  324. package/dist/render/SurfaceBackend.js.map +1 -0
  325. package/dist/render/index.d.ts +12 -0
  326. package/dist/render/index.d.ts.map +1 -0
  327. package/dist/render/index.js +11 -0
  328. package/dist/render/index.js.map +1 -0
  329. package/dist/renderer-tier/detectRendererTier.d.ts +57 -0
  330. package/dist/renderer-tier/detectRendererTier.d.ts.map +1 -0
  331. package/dist/renderer-tier/detectRendererTier.js +143 -0
  332. package/dist/renderer-tier/detectRendererTier.js.map +1 -0
  333. package/dist/renderer-tier/index.d.ts +12 -0
  334. package/dist/renderer-tier/index.d.ts.map +1 -0
  335. package/dist/renderer-tier/index.js +12 -0
  336. package/dist/renderer-tier/index.js.map +1 -0
  337. package/dist/renderer-tier/selectBackend.d.ts +106 -0
  338. package/dist/renderer-tier/selectBackend.d.ts.map +1 -0
  339. package/dist/renderer-tier/selectBackend.js +113 -0
  340. package/dist/renderer-tier/selectBackend.js.map +1 -0
  341. package/dist/renderer-tier/types.d.ts +50 -0
  342. package/dist/renderer-tier/types.d.ts.map +1 -0
  343. package/dist/renderer-tier/types.js +24 -0
  344. package/dist/renderer-tier/types.js.map +1 -0
  345. package/dist/replay/createReplayController.d.ts +3 -0
  346. package/dist/replay/createReplayController.d.ts.map +1 -0
  347. package/dist/replay/createReplayController.js +251 -0
  348. package/dist/replay/createReplayController.js.map +1 -0
  349. package/dist/replay/index.d.ts +5 -0
  350. package/dist/replay/index.d.ts.map +1 -0
  351. package/dist/replay/index.js +3 -0
  352. package/dist/replay/index.js.map +1 -0
  353. package/dist/replay/timeline.d.ts +50 -0
  354. package/dist/replay/timeline.d.ts.map +1 -0
  355. package/dist/replay/timeline.js +104 -0
  356. package/dist/replay/timeline.js.map +1 -0
  357. package/dist/replay/types.d.ts +94 -0
  358. package/dist/replay/types.d.ts.map +1 -0
  359. package/dist/replay/types.js +21 -0
  360. package/dist/replay/types.js.map +1 -0
  361. package/dist/scale/anchoredZoom.d.ts +64 -0
  362. package/dist/scale/anchoredZoom.d.ts.map +1 -0
  363. package/dist/scale/anchoredZoom.js +67 -0
  364. package/dist/scale/anchoredZoom.js.map +1 -0
  365. package/dist/scale/createPriceScale.d.ts +49 -0
  366. package/dist/scale/createPriceScale.d.ts.map +1 -0
  367. package/dist/scale/createPriceScale.js +175 -0
  368. package/dist/scale/createPriceScale.js.map +1 -0
  369. package/dist/scale/createTimeScale.d.ts +27 -0
  370. package/dist/scale/createTimeScale.d.ts.map +1 -0
  371. package/dist/scale/createTimeScale.js +139 -0
  372. package/dist/scale/createTimeScale.js.map +1 -0
  373. package/dist/scale/index.d.ts +6 -0
  374. package/dist/scale/index.d.ts.map +1 -0
  375. package/dist/scale/index.js +5 -0
  376. package/dist/scale/index.js.map +1 -0
  377. package/dist/scale/originShift.d.ts +69 -0
  378. package/dist/scale/originShift.d.ts.map +1 -0
  379. package/dist/scale/originShift.js +41 -0
  380. package/dist/scale/originShift.js.map +1 -0
  381. package/dist/scale/types.d.ts +90 -0
  382. package/dist/scale/types.d.ts.map +1 -0
  383. package/dist/scale/types.js +17 -0
  384. package/dist/scale/types.js.map +1 -0
  385. package/dist/scene/createScene.d.ts +22 -0
  386. package/dist/scene/createScene.d.ts.map +1 -0
  387. package/dist/scene/createScene.js +114 -0
  388. package/dist/scene/createScene.js.map +1 -0
  389. package/dist/scene/index.d.ts +13 -0
  390. package/dist/scene/index.d.ts.map +1 -0
  391. package/dist/scene/index.js +11 -0
  392. package/dist/scene/index.js.map +1 -0
  393. package/dist/scene/layerRegistry.d.ts +83 -0
  394. package/dist/scene/layerRegistry.d.ts.map +1 -0
  395. package/dist/scene/layerRegistry.js +43 -0
  396. package/dist/scene/layerRegistry.js.map +1 -0
  397. package/dist/scene/types.d.ts +128 -0
  398. package/dist/scene/types.d.ts.map +1 -0
  399. package/dist/scene/types.js +21 -0
  400. package/dist/scene/types.js.map +1 -0
  401. package/dist/scheduler/createFrameBudget.d.ts +91 -0
  402. package/dist/scheduler/createFrameBudget.d.ts.map +1 -0
  403. package/dist/scheduler/createFrameBudget.js +232 -0
  404. package/dist/scheduler/createFrameBudget.js.map +1 -0
  405. package/dist/scheduler/index.d.ts +2 -0
  406. package/dist/scheduler/index.d.ts.map +1 -0
  407. package/dist/scheduler/index.js +2 -0
  408. package/dist/scheduler/index.js.map +1 -0
  409. package/dist/tokens/themeToCssVars.d.ts.map +1 -1
  410. package/dist/tokens/themeToCssVars.js +2 -28
  411. package/dist/tokens/themeToCssVars.js.map +1 -1
  412. package/dist/version.d.ts +1 -1
  413. package/dist/version.d.ts.map +1 -1
  414. package/dist/version.js +1 -1
  415. package/dist/version.js.map +1 -1
  416. package/package.json +1 -1
  417. package/src/__bench__/indicators.bench.ts +215 -0
  418. package/src/__bench__/orderBookHeatmap.bench.ts +68 -0
  419. package/src/__bench__/scale.bench.ts +80 -0
  420. package/src/__bench__/signal.bench.ts +41 -0
  421. package/src/__bench__/volumeProfile.bench.ts +66 -0
  422. package/src/__tests__/errors-help.test.ts +184 -0
  423. package/src/__tests__/errors.test.ts +187 -0
  424. package/src/alerts/__tests__/controller.test.ts +231 -0
  425. package/src/alerts/__tests__/predicates.test.ts +374 -0
  426. package/src/alerts/__tests__/ruleSchema.test.ts +180 -0
  427. package/src/alerts/createAlertController.ts +312 -0
  428. package/src/alerts/index.ts +18 -0
  429. package/src/alerts/predicates.ts +231 -0
  430. package/src/alerts/rollingVolume.ts +51 -0
  431. package/src/alerts/ruleSchema.ts +278 -0
  432. package/src/alerts/types.ts +177 -0
  433. package/src/chartTypes/__tests__/heikinAshi.test.ts +122 -0
  434. package/src/chartTypes/__tests__/pointAndFigure.test.ts +167 -0
  435. package/src/chartTypes/__tests__/rangeBars.test.ts +146 -0
  436. package/src/chartTypes/__tests__/renko.test.ts +160 -0
  437. package/src/chartTypes/heikinAshi.ts +116 -0
  438. package/src/chartTypes/index.ts +5 -0
  439. package/src/chartTypes/pointAndFigure.ts +278 -0
  440. package/src/chartTypes/rangeBars.ts +303 -0
  441. package/src/chartTypes/renko.ts +311 -0
  442. package/src/chartTypes/types.ts +99 -0
  443. package/src/components/anchoredVwap/__tests__/computeAnchoredVwap.test.ts +331 -0
  444. package/src/components/anchoredVwap/__tests__/controller.test.ts +430 -0
  445. package/src/components/anchoredVwap/computeAnchoredVwap.ts +174 -0
  446. package/src/components/anchoredVwap/createAnchoredVwapController.ts +358 -0
  447. package/src/components/anchoredVwap/index.ts +17 -0
  448. package/src/components/anchoredVwap/types.ts +187 -0
  449. package/src/components/crosshairSync/__tests__/crosshairSync.test.ts +261 -0
  450. package/src/components/crosshairSync/createCrosshairSync.ts +187 -0
  451. package/src/components/crosshairSync/index.ts +5 -0
  452. package/src/components/footprint/__tests__/aggressor.test.ts +127 -0
  453. package/src/components/footprint/__tests__/controller.test.ts +130 -0
  454. package/src/components/footprint/__tests__/perBarStats.test.ts +114 -0
  455. package/src/components/footprint/aggressor.ts +165 -0
  456. package/src/components/footprint/createFootprintController.ts +338 -0
  457. package/src/components/footprint/index.ts +21 -0
  458. package/src/components/footprint/perBarStats.ts +137 -0
  459. package/src/components/footprint/types.ts +232 -0
  460. package/src/components/mtfOverlay/__tests__/alignToBaseIndex.test.ts +103 -0
  461. package/src/components/mtfOverlay/__tests__/controller.test.ts +172 -0
  462. package/src/components/mtfOverlay/__tests__/resampleBars.test.ts +106 -0
  463. package/src/components/mtfOverlay/alignToBaseIndex.ts +108 -0
  464. package/src/components/mtfOverlay/createMtfController.ts +180 -0
  465. package/src/components/mtfOverlay/index.ts +26 -0
  466. package/src/components/mtfOverlay/resampleBars.ts +134 -0
  467. package/src/components/mtfOverlay/types.ts +148 -0
  468. package/src/components/orderBookHeatmap/__tests__/controller.test.ts +237 -0
  469. package/src/components/orderBookHeatmap/__tests__/deltaArchive.test.ts +88 -0
  470. package/src/components/orderBookHeatmap/__tests__/logColorScale.test.ts +69 -0
  471. package/src/components/orderBookHeatmap/__tests__/orderBookState.test.ts +113 -0
  472. package/src/components/orderBookHeatmap/__tests__/snapshotRing.test.ts +53 -0
  473. package/src/components/orderBookHeatmap/computeShader.wgsl.md +130 -0
  474. package/src/components/orderBookHeatmap/createHeatmapController.ts +273 -0
  475. package/src/components/orderBookHeatmap/createOrderBookState.ts +116 -0
  476. package/src/components/orderBookHeatmap/deltaArchive.ts +113 -0
  477. package/src/components/orderBookHeatmap/index.ts +25 -0
  478. package/src/components/orderBookHeatmap/logColorScale.ts +77 -0
  479. package/src/components/orderBookHeatmap/snapshotRing.ts +65 -0
  480. package/src/components/orderBookHeatmap/types.ts +168 -0
  481. package/src/components/volumeProfile/__tests__/binning.test.ts +133 -0
  482. package/src/components/volumeProfile/__tests__/poc.test.ts +44 -0
  483. package/src/components/volumeProfile/__tests__/valueArea.test.ts +177 -0
  484. package/src/components/volumeProfile/binning.ts +133 -0
  485. package/src/components/volumeProfile/createVolumeProfileController.ts +213 -0
  486. package/src/components/volumeProfile/index.ts +12 -0
  487. package/src/components/volumeProfile/poc.ts +53 -0
  488. package/src/components/volumeProfile/types.ts +148 -0
  489. package/src/components/volumeProfile/valueArea.ts +187 -0
  490. package/src/controllers/createChartController.ts +23 -10
  491. package/src/controllers/types.ts +5 -1
  492. package/src/data-fetchers/baostock.ts +2 -1
  493. package/src/data-fetchers/dataBuffer.effects.ts +3 -1
  494. package/src/data-fetchers/fetcherDefinitionRegistry.ts +2 -1
  495. package/src/data-fetchers/gotdx.ts +4 -3
  496. package/src/data-fetchers/router.ts +6 -3
  497. package/src/data-fetchers/tradingview.ts +3 -2
  498. package/src/engine/chart.ts +126 -3
  499. package/src/engine/data/chartDataManager.ts +26 -4
  500. package/src/engine/drawing/toolConfig.ts +2 -1
  501. package/src/engine/indicators/chartIndicatorManager.ts +2 -1
  502. package/src/engine/indicators/indicatorDefinitionRegistry.ts +2 -1
  503. package/src/engine/indicators/indicatorMetadata.ts +2 -1
  504. package/src/engine/indicators/indicatorRegistry.ts +6 -5
  505. package/src/engine/indicators/registerBuiltins.ts +2 -1
  506. package/src/engine/indicators/scheduler.ts +15 -0
  507. package/src/engine/indicators/soa.ts +2 -1
  508. package/src/engine/indicators/stateComposer.ts +2 -1
  509. package/src/engine/subPaneManager.ts +2 -1
  510. package/src/engine/utils/chartZoomController.ts +7 -1
  511. package/src/errors-help.ts +218 -0
  512. package/src/errors.ts +128 -0
  513. package/src/index.ts +37 -0
  514. package/src/indicators/__tests__/maFamily.test.ts +159 -0
  515. package/src/indicators/__tests__/oscillators.test.ts +150 -0
  516. package/src/indicators/alma.ts +61 -0
  517. package/src/indicators/awesomeOscillator.ts +54 -0
  518. package/src/indicators/dpo.ts +37 -0
  519. package/src/indicators/fisherTransform.ts +63 -0
  520. package/src/indicators/frama.ts +87 -0
  521. package/src/indicators/index.ts +39 -0
  522. package/src/indicators/lsma.ts +58 -0
  523. package/src/indicators/schaffTrendCycle.ts +92 -0
  524. package/src/indicators/stochRSI.ts +108 -0
  525. package/src/indicators/t3.ts +96 -0
  526. package/src/indicators/ultimateOscillator.ts +83 -0
  527. package/src/indicators/vidya.ts +80 -0
  528. package/src/indicators/zlema.ts +41 -0
  529. package/src/input/__tests__/gesture.test.ts +271 -0
  530. package/src/input/__tests__/keyboard.test.ts +317 -0
  531. package/src/input/gesture.ts +357 -0
  532. package/src/input/index.ts +26 -0
  533. package/src/input/keyboard.ts +373 -0
  534. package/src/mcp/chartBridge.ts +98 -72
  535. package/src/plugin/PluginHost.ts +4 -3
  536. package/src/plugin/PluginRegistry.ts +2 -1
  537. package/src/render/Renderer.ts +127 -0
  538. package/src/render/SurfaceBackend.ts +94 -0
  539. package/src/render/__tests__/contract.test.ts +176 -0
  540. package/src/render/index.ts +27 -0
  541. package/src/renderer-tier/__tests__/detectRendererTier.test.ts +180 -0
  542. package/src/renderer-tier/__tests__/selectBackend.test.ts +253 -0
  543. package/src/renderer-tier/detectRendererTier.ts +168 -0
  544. package/src/renderer-tier/index.ts +30 -0
  545. package/src/renderer-tier/selectBackend.ts +201 -0
  546. package/src/renderer-tier/types.ts +59 -0
  547. package/src/replay/__tests__/controller.test.ts +309 -0
  548. package/src/replay/__tests__/timeline.test.ts +99 -0
  549. package/src/replay/createReplayController.ts +302 -0
  550. package/src/replay/index.ts +15 -0
  551. package/src/replay/timeline.ts +106 -0
  552. package/src/replay/types.ts +107 -0
  553. package/src/scale/__tests__/anchoredZoom.test.ts +125 -0
  554. package/src/scale/__tests__/originShift.test.ts +97 -0
  555. package/src/scale/__tests__/priceScale.test.ts +219 -0
  556. package/src/scale/__tests__/timeScale.test.ts +119 -0
  557. package/src/scale/anchoredZoom.ts +104 -0
  558. package/src/scale/createPriceScale.ts +226 -0
  559. package/src/scale/createTimeScale.ts +150 -0
  560. package/src/scale/index.ts +9 -0
  561. package/src/scale/originShift.ts +111 -0
  562. package/src/scale/types.ts +100 -0
  563. package/src/scene/__tests__/layerRegistry.test.ts +207 -0
  564. package/src/scene/__tests__/scene.test.ts +411 -0
  565. package/src/scene/createScene.ts +117 -0
  566. package/src/scene/index.ts +29 -0
  567. package/src/scene/layerRegistry.ts +117 -0
  568. package/src/scene/types.ts +143 -0
  569. package/src/scheduler/__tests__/createFrameBudget.test.ts +315 -0
  570. package/src/scheduler/createFrameBudget.ts +316 -0
  571. package/src/scheduler/index.ts +7 -0
  572. package/src/tokens/themeToCssVars.ts +3 -1
  573. package/src/version.ts +1 -1
  574. package/dist/data-fetchers/gotdx/gotdx.d.ts +0 -7
  575. package/dist/data-fetchers/gotdx/gotdx.d.ts.map +0 -1
  576. package/dist/data-fetchers/gotdx/gotdx.js +0 -7
  577. package/dist/data-fetchers/gotdx/gotdx.js.map +0 -1
  578. package/src/data-fetchers/gotdx/gotdx.ts +0 -6
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Tests for `createFrameBudget`.
3
+ *
4
+ * The clock is injected via `opts.now`, so timing assertions are exact:
5
+ * we advance a counter manually and the scheduler reads from it.
6
+ *
7
+ * Coverage:
8
+ * 1. Construction validates targetMs / historySize / maxQueueSize.
9
+ * 2. submit:
10
+ * - rejects empty id with KLineChartError(INVALID_PARAM)
11
+ * - queues into correct priority tier (queueDepth updates)
12
+ * - coalesces same-id submission (the later wins)
13
+ * - re-buckets when coalesce changes priority
14
+ * - drops oldest low/medium under maxQueueSize pressure
15
+ * - never drops high under pressure
16
+ * 3. flush:
17
+ * - runs all queued tasks if deadline is generous
18
+ * - stops at deadline (remaining stay queued)
19
+ * - runs high before medium before low (priority ordering)
20
+ * - within a tier, FIFO
21
+ * - returns the number of tasks run
22
+ * - throw in task is caught + dropped, others continue
23
+ * 4. beginFrame / endFrame:
24
+ * - validate finite timestamps
25
+ * - recentFrameMs is the rolling average over historySize frames
26
+ * - overruns increments only when dur > targetMs
27
+ * 5. clear / dispose.
28
+ */
29
+
30
+ import { describe, it, expect } from 'vitest'
31
+
32
+ import { createFrameBudget, type FrameTask } from '..'
33
+ import { isKLineChartError } from '../../errors'
34
+
35
+ function fakeClock(): {
36
+ now: () => number
37
+ advance: (ms: number) => void
38
+ set: (t: number) => void
39
+ } {
40
+ let t = 0
41
+ return {
42
+ now: () => t,
43
+ advance: (ms: number) => {
44
+ t += ms
45
+ },
46
+ set: (next: number) => {
47
+ t = next
48
+ },
49
+ }
50
+ }
51
+
52
+ function record(id: string, store: string[], priority: FrameTask['priority'] = 'medium'): FrameTask {
53
+ return { id, priority, work: () => store.push(id) }
54
+ }
55
+
56
+ // ---------------------------------------------------------------------------
57
+ // Construction
58
+ // ---------------------------------------------------------------------------
59
+
60
+ describe('createFrameBudget — validation', () => {
61
+ it('rejects non-positive targetMs', () => {
62
+ for (const v of [0, -1, Number.NaN]) {
63
+ try {
64
+ createFrameBudget({ targetMs: v })
65
+ expect.fail(`expected throw for ${v}`)
66
+ } catch (e) {
67
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
68
+ }
69
+ }
70
+ })
71
+
72
+ it('rejects non-positive-integer historySize', () => {
73
+ for (const v of [0, -1, 1.5]) {
74
+ try {
75
+ createFrameBudget({ historySize: v })
76
+ expect.fail(`expected throw for ${v}`)
77
+ } catch (e) {
78
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
79
+ }
80
+ }
81
+ })
82
+
83
+ it('rejects non-positive-integer maxQueueSize', () => {
84
+ try {
85
+ createFrameBudget({ maxQueueSize: 0 })
86
+ expect.fail('expected throw')
87
+ } catch (e) {
88
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
89
+ }
90
+ })
91
+
92
+ it('exposes targetMs verbatim', () => {
93
+ expect(createFrameBudget({ targetMs: 8 }).targetMs).toBe(8)
94
+ })
95
+ })
96
+
97
+ // ---------------------------------------------------------------------------
98
+ // submit
99
+ // ---------------------------------------------------------------------------
100
+
101
+ describe('submit', () => {
102
+ it('rejects empty id', () => {
103
+ const fb = createFrameBudget()
104
+ try {
105
+ fb.submit({ id: '', priority: 'low', work: () => {} })
106
+ expect.fail('expected throw')
107
+ } catch (e) {
108
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
109
+ }
110
+ })
111
+
112
+ it('queueDepth tracks submissions across tiers', () => {
113
+ const fb = createFrameBudget()
114
+ const seen: string[] = []
115
+ fb.submit(record('a', seen, 'high'))
116
+ fb.submit(record('b', seen, 'medium'))
117
+ fb.submit(record('c', seen, 'low'))
118
+ expect(fb.queueDepth.peek()).toBe(3)
119
+ })
120
+
121
+ it('coalesces same-id submission (later wins)', () => {
122
+ const fb = createFrameBudget()
123
+ const seen: string[] = []
124
+ fb.submit({ id: 'x', priority: 'low', work: () => seen.push('first') })
125
+ fb.submit({ id: 'x', priority: 'low', work: () => seen.push('second') })
126
+ const clk = fakeClock()
127
+ // Cheap test: a fresh budget with default now — flush with a far deadline.
128
+ fb.flush(Number.POSITIVE_INFINITY)
129
+ expect(seen).toEqual(['second'])
130
+ })
131
+
132
+ it('re-buckets when coalesce changes priority', () => {
133
+ const seen: string[] = []
134
+ const fb = createFrameBudget({ now: fakeClock().now })
135
+ fb.submit({ id: 'x', priority: 'low', work: () => seen.push('low') })
136
+ fb.submit({ id: 'x', priority: 'high', work: () => seen.push('high') })
137
+ fb.submit(record('y', seen, 'medium'))
138
+ fb.flush(Number.POSITIVE_INFINITY)
139
+ // x runs first (it's now high), then y.
140
+ expect(seen).toEqual(['high', 'y'])
141
+ })
142
+
143
+ it('drops oldest low under maxQueueSize pressure', () => {
144
+ const seen: string[] = []
145
+ const fb = createFrameBudget({ maxQueueSize: 2 })
146
+ fb.submit(record('a', seen, 'low'))
147
+ fb.submit(record('b', seen, 'low'))
148
+ fb.submit(record('c', seen, 'high'))
149
+ fb.flush(Number.POSITIVE_INFINITY)
150
+ // 'a' was the oldest low; it got dropped to make room for 'c'.
151
+ expect(seen).toEqual(['c', 'b'])
152
+ })
153
+
154
+ it('never drops high under pressure', () => {
155
+ const seen: string[] = []
156
+ const fb = createFrameBudget({ maxQueueSize: 2 })
157
+ fb.submit(record('a', seen, 'high'))
158
+ fb.submit(record('b', seen, 'high'))
159
+ fb.submit(record('c', seen, 'high'))
160
+ fb.flush(Number.POSITIVE_INFINITY)
161
+ // All 3 high tasks present; the cap was exceeded but high
162
+ // is never dropped (producer-is-misbehaving signal).
163
+ expect(seen).toEqual(['a', 'b', 'c'])
164
+ })
165
+ })
166
+
167
+ // ---------------------------------------------------------------------------
168
+ // flush
169
+ // ---------------------------------------------------------------------------
170
+
171
+ describe('flush', () => {
172
+ it('runs high before medium before low (priority)', () => {
173
+ const seen: string[] = []
174
+ const fb = createFrameBudget()
175
+ fb.submit(record('low1', seen, 'low'))
176
+ fb.submit(record('med1', seen, 'medium'))
177
+ fb.submit(record('hi1', seen, 'high'))
178
+ fb.submit(record('hi2', seen, 'high'))
179
+ fb.submit(record('med2', seen, 'medium'))
180
+ fb.flush(Number.POSITIVE_INFINITY)
181
+ expect(seen).toEqual(['hi1', 'hi2', 'med1', 'med2', 'low1'])
182
+ })
183
+
184
+ it('within a tier, runs FIFO', () => {
185
+ const seen: string[] = []
186
+ const fb = createFrameBudget()
187
+ for (const id of ['a', 'b', 'c', 'd']) {
188
+ fb.submit(record(id, seen, 'medium'))
189
+ }
190
+ fb.flush(Number.POSITIVE_INFINITY)
191
+ expect(seen).toEqual(['a', 'b', 'c', 'd'])
192
+ })
193
+
194
+ it('stops at deadline; remaining tasks stay queued', () => {
195
+ const seen: string[] = []
196
+ const clk = fakeClock()
197
+ const fb = createFrameBudget({ now: clk.now })
198
+ for (let i = 0; i < 5; i++) {
199
+ fb.submit({
200
+ id: `t${i}`,
201
+ priority: 'medium',
202
+ work: () => {
203
+ seen.push(`t${i}`)
204
+ clk.advance(2) // each task costs 2ms
205
+ },
206
+ })
207
+ }
208
+ // Deadline at 5ms — 2 tasks complete (4ms), the 3rd would push us
209
+ // to 6ms but clock check happens BEFORE running each task. After
210
+ // 2 tasks, the next iteration sees now() = 4 < 5 — runs the 3rd
211
+ // (push to 6). After that, now() = 6 >= 5 — stop.
212
+ const done = fb.flush(5)
213
+ expect(done).toBe(3)
214
+ expect(seen).toEqual(['t0', 't1', 't2'])
215
+ expect(fb.queueDepth.peek()).toBe(2)
216
+ })
217
+
218
+ it('returns 0 if deadline already passed', () => {
219
+ const clk = fakeClock()
220
+ clk.set(100)
221
+ const fb = createFrameBudget({ now: clk.now })
222
+ fb.submit(record('a', [], 'high'))
223
+ expect(fb.flush(50)).toBe(0)
224
+ })
225
+
226
+ it('a throwing task is dropped; others continue', () => {
227
+ const seen: string[] = []
228
+ const fb = createFrameBudget()
229
+ fb.submit({ id: 'a', priority: 'high', work: () => seen.push('a') })
230
+ fb.submit({
231
+ id: 'bad',
232
+ priority: 'high',
233
+ work: () => {
234
+ throw new Error('boom')
235
+ },
236
+ })
237
+ fb.submit({ id: 'c', priority: 'high', work: () => seen.push('c') })
238
+ const done = fb.flush(Number.POSITIVE_INFINITY)
239
+ expect(done).toBe(2) // a + c, not bad
240
+ expect(seen).toEqual(['a', 'c'])
241
+ })
242
+ })
243
+
244
+ // ---------------------------------------------------------------------------
245
+ // beginFrame / endFrame
246
+ // ---------------------------------------------------------------------------
247
+
248
+ describe('beginFrame / endFrame', () => {
249
+ it('validates finite timestamps', () => {
250
+ const fb = createFrameBudget()
251
+ for (const m of ['beginFrame', 'endFrame'] as const) {
252
+ try {
253
+ fb[m](Number.NaN)
254
+ expect.fail('expected throw')
255
+ } catch (e) {
256
+ expect(isKLineChartError(e, 'INVALID_PARAM')).toBe(true)
257
+ }
258
+ }
259
+ })
260
+
261
+ it('recentFrameMs is the rolling average over historySize frames', () => {
262
+ const fb = createFrameBudget({ historySize: 3 })
263
+ // 3 frames at 10ms each → avg 10
264
+ for (let i = 0; i < 3; i++) {
265
+ fb.beginFrame(i * 16)
266
+ fb.endFrame(i * 16 + 10)
267
+ }
268
+ expect(fb.recentFrameMs.peek()).toBe(10)
269
+ // Push one 20ms frame; rolling window drops the oldest.
270
+ fb.beginFrame(48)
271
+ fb.endFrame(68)
272
+ // window: [10, 10, 20] → avg ≈ 13.33
273
+ expect(fb.recentFrameMs.peek()).toBeCloseTo((10 + 10 + 20) / 3, 5)
274
+ })
275
+
276
+ it('overruns increments only when frame > targetMs', () => {
277
+ const fb = createFrameBudget({ targetMs: 16 })
278
+ // 10ms frame — not an overrun
279
+ fb.beginFrame(0)
280
+ fb.endFrame(10)
281
+ expect(fb.overruns.peek()).toBe(0)
282
+ // 18ms frame — overrun
283
+ fb.beginFrame(16)
284
+ fb.endFrame(34)
285
+ expect(fb.overruns.peek()).toBe(1)
286
+ // Exactly at targetMs — not an overrun (> strict)
287
+ fb.beginFrame(32)
288
+ fb.endFrame(48)
289
+ expect(fb.overruns.peek()).toBe(1)
290
+ })
291
+ })
292
+
293
+ // ---------------------------------------------------------------------------
294
+ // clear / dispose
295
+ // ---------------------------------------------------------------------------
296
+
297
+ describe('clear', () => {
298
+ it('drops all queued tasks', () => {
299
+ const fb = createFrameBudget()
300
+ fb.submit(record('a', [], 'high'))
301
+ fb.submit(record('b', [], 'low'))
302
+ fb.clear()
303
+ expect(fb.queueDepth.peek()).toBe(0)
304
+ })
305
+ })
306
+
307
+ describe('dispose', () => {
308
+ it('makes submit / flush / frame markers no-ops', () => {
309
+ const fb = createFrameBudget()
310
+ fb.dispose()
311
+ expect(() => fb.submit(record('a', [], 'high'))).not.toThrow()
312
+ expect(fb.queueDepth.peek()).toBe(0)
313
+ expect(fb.flush(Number.POSITIVE_INFINITY)).toBe(0)
314
+ })
315
+ })
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Frame budget scheduler — adaptive workload manager.
3
+ *
4
+ * Real-time finance charts share a constraint with games and trading
5
+ * terminals: the renderer has a wall-clock budget per frame (16.67 ms
6
+ * at 60 fps, 6.94 ms at 144 fps), and exceeding it means dropped frames.
7
+ * Work that doesn't fit gets deferred to the next frame, but the work
8
+ * *queue* must not grow without bound — a stale indicator update is
9
+ * worse than a missed update.
10
+ *
11
+ * This module owns the policy. Consumers submit prioritised tasks;
12
+ * `flush(deadline)` drains as many as fit; the rest stay queued until
13
+ * the next call. A rolling-average frame-time signal lets components
14
+ * back off proactively rather than waiting for budget exhaustion.
15
+ *
16
+ * Pure data: no requestAnimationFrame, no performance.now() side effects.
17
+ * The host (browser / Node test / Deno) supplies the clock via a `now`
18
+ * function. Default: `performance.now()` if available, else `Date.now()`.
19
+ *
20
+ * const budget = createFrameBudget({ targetMs: 16 })
21
+ *
22
+ * // Host's rAF loop:
23
+ * function tick(t) {
24
+ * budget.beginFrame(t)
25
+ * budget.submit({ id: 'indicators', priority: 'high', work: recompute })
26
+ * budget.submit({ id: 'labels', priority: 'low', work: drawLabels })
27
+ * budget.flush(t + budget.targetMs)
28
+ * budget.endFrame(performance.now())
29
+ * requestAnimationFrame(tick)
30
+ * }
31
+ *
32
+ * // Consumers can read the load signal to back off:
33
+ * if (budget.recentFrameMs() > 18) skipLowPriorityWork()
34
+ */
35
+
36
+ import { createSignal, type Signal } from '../reactivity'
37
+ import { KLineChartError } from '../errors'
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Public shape
41
+ // ---------------------------------------------------------------------------
42
+
43
+ export type TaskPriority = 'high' | 'medium' | 'low'
44
+
45
+ export interface FrameTask {
46
+ /** Stable id. Duplicate submissions with the same id are coalesced — the
47
+ * later submission's `work` and `priority` win. */
48
+ readonly id: string
49
+ readonly priority: TaskPriority
50
+ /** Synchronous unit of work. Throws are caught and logged but do NOT
51
+ * abort the frame; the task is dropped. */
52
+ readonly work: () => void
53
+ }
54
+
55
+ export interface FrameBudgetOptions {
56
+ /** Target frame budget in milliseconds. Default 16 (≈60 fps). */
57
+ readonly targetMs?: number
58
+ /** Rolling window for `recentFrameMs`. Default 60 frames (1 s at 60 fps). */
59
+ readonly historySize?: number
60
+ /**
61
+ * Clock function. Default: `performance.now()` if available, else
62
+ * `Date.now()`. Injected for tests so timing is deterministic.
63
+ */
64
+ readonly now?: () => number
65
+ /**
66
+ * Maximum queued tasks. Older low/medium tasks are dropped when the
67
+ * queue exceeds this. Default 256 — high enough that legitimate
68
+ * workloads never hit it, low enough that runaway producers fail loud.
69
+ */
70
+ readonly maxQueueSize?: number
71
+ }
72
+
73
+ export interface FrameBudget {
74
+ readonly targetMs: number
75
+ /** Current rolling-average frame time in ms. */
76
+ readonly recentFrameMs: Signal<number>
77
+ /** Number of tasks currently queued (not yet flushed). */
78
+ readonly queueDepth: Signal<number>
79
+ /** Frames whose work exceeded targetMs (cumulative). */
80
+ readonly overruns: Signal<number>
81
+
82
+ /** Mark the start of a frame. Pass `performance.now()` (or test clock). */
83
+ beginFrame(t: number): void
84
+ /** Queue a task. Coalesces on id (later submission wins). */
85
+ submit(task: FrameTask): void
86
+ /**
87
+ * Drain queued tasks until the deadline (absolute timestamp in the
88
+ * `now`-clock's scale). Returns the number of tasks completed.
89
+ *
90
+ * Tasks run in priority order: all `high` first, then `medium`, then
91
+ * `low`. Within a priority, FIFO. A task that throws is caught and
92
+ * dropped; remaining tasks continue.
93
+ */
94
+ flush(deadlineAbs: number): number
95
+ /** Mark the end of a frame. Updates `recentFrameMs` + overrun count. */
96
+ endFrame(t: number): void
97
+ /** Drop all queued tasks. */
98
+ clear(): void
99
+ dispose(): void
100
+ }
101
+
102
+ const PRIORITY_ORDER: ReadonlyArray<TaskPriority> = ['high', 'medium', 'low']
103
+
104
+ // ---------------------------------------------------------------------------
105
+ // Internals
106
+ // ---------------------------------------------------------------------------
107
+
108
+ function defaultNow(): number {
109
+ const perf = (globalThis as { performance?: { now?: () => number } }).performance
110
+ if (typeof perf?.now === 'function') return perf.now()
111
+ return Date.now()
112
+ }
113
+
114
+ // ---------------------------------------------------------------------------
115
+ // Factory
116
+ // ---------------------------------------------------------------------------
117
+
118
+ export function createFrameBudget(opts: FrameBudgetOptions = {}): FrameBudget {
119
+ const targetMs = opts.targetMs ?? 16
120
+ const historySize = opts.historySize ?? 60
121
+ const maxQueueSize = opts.maxQueueSize ?? 256
122
+ const now = opts.now ?? defaultNow
123
+
124
+ if (!(targetMs > 0) || !Number.isFinite(targetMs)) {
125
+ throw new KLineChartError('INVALID_PARAM', `createFrameBudget: targetMs must be > 0, got ${targetMs}`)
126
+ }
127
+ if (!(historySize > 0) || !Number.isInteger(historySize)) {
128
+ throw new KLineChartError(
129
+ 'INVALID_PARAM',
130
+ `createFrameBudget: historySize must be a positive integer, got ${historySize}`,
131
+ )
132
+ }
133
+ if (!(maxQueueSize > 0) || !Number.isInteger(maxQueueSize)) {
134
+ throw new KLineChartError(
135
+ 'INVALID_PARAM',
136
+ `createFrameBudget: maxQueueSize must be a positive integer, got ${maxQueueSize}`,
137
+ )
138
+ }
139
+
140
+ const recentFrameMs = createSignal(0)
141
+ const queueDepth = createSignal(0)
142
+ const overruns = createSignal(0)
143
+
144
+ // One queue per priority; preserves FIFO inside a tier.
145
+ const queues: Record<TaskPriority, FrameTask[]> = {
146
+ high: [],
147
+ medium: [],
148
+ low: [],
149
+ }
150
+ // Reverse lookup so coalesce-by-id is O(1).
151
+ const byId = new Map<string, { tier: TaskPriority; index: number }>()
152
+
153
+ const frameTimes: number[] = []
154
+ let frameStart = 0
155
+ let disposed = false
156
+
157
+ function publishDepth(): void {
158
+ queueDepth.set(queues.high.length + queues.medium.length + queues.low.length)
159
+ }
160
+
161
+ function totalQueued(): number {
162
+ return queues.high.length + queues.medium.length + queues.low.length
163
+ }
164
+
165
+ function dropOldestLowOrMedium(): void {
166
+ // Prefer dropping low first, then medium. We never drop high.
167
+ if (queues.low.length > 0) {
168
+ const dropped = queues.low.shift()!
169
+ byId.delete(dropped.id)
170
+ return
171
+ }
172
+ if (queues.medium.length > 0) {
173
+ const dropped = queues.medium.shift()!
174
+ byId.delete(dropped.id)
175
+ return
176
+ }
177
+ // Only high tasks remain. We don't drop high tasks for queue
178
+ // pressure; the producer is misbehaving. Surface via overruns
179
+ // signal so the host can decide.
180
+ }
181
+
182
+ function submit(task: FrameTask): void {
183
+ if (disposed) return
184
+ if (task.id === '' || typeof task.id !== 'string') {
185
+ throw new KLineChartError(
186
+ 'INVALID_PARAM',
187
+ `FrameBudget.submit: task.id must be a non-empty string`,
188
+ )
189
+ }
190
+ // Coalesce by id — replace existing entry.
191
+ const existing = byId.get(task.id)
192
+ if (existing !== undefined) {
193
+ queues[existing.tier][existing.index] = task
194
+ // The tier might be changing; if it is, we need to re-bucket.
195
+ if (existing.tier !== task.priority) {
196
+ // Mark old slot as a tombstone (we can't splice cheaply mid-iteration
197
+ // in some paths). The flush loop tolerates undefined entries.
198
+ ;(queues[existing.tier] as Array<FrameTask | undefined>)[existing.index] = undefined
199
+ queues[task.priority].push(task)
200
+ byId.set(task.id, {
201
+ tier: task.priority,
202
+ index: queues[task.priority].length - 1,
203
+ })
204
+ }
205
+ publishDepth()
206
+ return
207
+ }
208
+ // Enforce maxQueueSize by dropping older low/medium first.
209
+ while (totalQueued() >= maxQueueSize) {
210
+ dropOldestLowOrMedium()
211
+ // If only high tasks left and we're still at the cap, bail.
212
+ if (totalQueued() >= maxQueueSize && queues.low.length === 0 && queues.medium.length === 0) {
213
+ break
214
+ }
215
+ }
216
+ queues[task.priority].push(task)
217
+ byId.set(task.id, {
218
+ tier: task.priority,
219
+ index: queues[task.priority].length - 1,
220
+ })
221
+ publishDepth()
222
+ }
223
+
224
+ function flush(deadlineAbs: number): number {
225
+ if (disposed) return 0
226
+ let completed = 0
227
+ for (const tier of PRIORITY_ORDER) {
228
+ const q = queues[tier] as Array<FrameTask | undefined>
229
+ while (q.length > 0) {
230
+ if (now() >= deadlineAbs) {
231
+ // Compact the tier so later flushes skip tombstones.
232
+ queues[tier] = q.filter((t): t is FrameTask => t !== undefined)
233
+ // Rebuild byId indices for this tier.
234
+ for (let i = 0; i < queues[tier].length; i++) {
235
+ const t = queues[tier][i]!
236
+ byId.set(t.id, { tier, index: i })
237
+ }
238
+ publishDepth()
239
+ return completed
240
+ }
241
+ const task = q.shift()
242
+ if (task === undefined) continue // tombstone
243
+ byId.delete(task.id)
244
+ try {
245
+ task.work()
246
+ completed++
247
+ } catch {
248
+ // Task threw; drop it. We don't propagate — one
249
+ // bad task must not poison the frame.
250
+ }
251
+ }
252
+ }
253
+ publishDepth()
254
+ return completed
255
+ }
256
+
257
+ function beginFrame(t: number): void {
258
+ if (disposed) return
259
+ if (!Number.isFinite(t)) {
260
+ throw new KLineChartError(
261
+ 'INVALID_PARAM',
262
+ `FrameBudget.beginFrame: t must be finite, got ${t}`,
263
+ )
264
+ }
265
+ frameStart = t
266
+ }
267
+
268
+ function endFrame(t: number): void {
269
+ if (disposed) return
270
+ if (!Number.isFinite(t)) {
271
+ throw new KLineChartError(
272
+ 'INVALID_PARAM',
273
+ `FrameBudget.endFrame: t must be finite, got ${t}`,
274
+ )
275
+ }
276
+ const dur = Math.max(0, t - frameStart)
277
+ frameTimes.push(dur)
278
+ while (frameTimes.length > historySize) frameTimes.shift()
279
+ let sum = 0
280
+ for (const v of frameTimes) sum += v
281
+ recentFrameMs.set(sum / frameTimes.length)
282
+ if (dur > targetMs) overruns.set(overruns.peek() + 1)
283
+ }
284
+
285
+ function clear(): void {
286
+ if (disposed) return
287
+ queues.high = []
288
+ queues.medium = []
289
+ queues.low = []
290
+ byId.clear()
291
+ publishDepth()
292
+ }
293
+
294
+ function dispose(): void {
295
+ if (disposed) return
296
+ disposed = true
297
+ queues.high = []
298
+ queues.medium = []
299
+ queues.low = []
300
+ byId.clear()
301
+ frameTimes.length = 0
302
+ }
303
+
304
+ return {
305
+ targetMs,
306
+ recentFrameMs,
307
+ queueDepth,
308
+ overruns,
309
+ beginFrame,
310
+ submit,
311
+ flush,
312
+ endFrame,
313
+ clear,
314
+ dispose,
315
+ }
316
+ }
@@ -0,0 +1,7 @@
1
+ export {
2
+ createFrameBudget,
3
+ type FrameBudget,
4
+ type FrameBudgetOptions,
5
+ type FrameTask,
6
+ type TaskPriority,
7
+ } from './createFrameBudget'
@@ -1,3 +1,5 @@
1
+ import { KLineChartError } from '../errors'
2
+
1
3
  /**
2
4
  * Theme → CSS custom-property emitter.
3
5
  *
@@ -103,7 +105,7 @@ export function themeToCssVars(
103
105
  if (!prefix.startsWith('--')) {
104
106
  // Misuse caught here is much friendlier than the silent no-op CSS
105
107
  // would give downstream.
106
- throw new Error(
108
+ throw new KLineChartError('INVALID_PARAM',
107
109
  `themeToCssVars: prefix must start with '--', got ${JSON.stringify(prefix)}`,
108
110
  )
109
111
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.8.11-alpha.0"
1
+ export const VERSION = "0.8.12"
@@ -1,7 +0,0 @@
1
- /**
2
- * Re-export from root gotdx fetcher.
3
- * This file exists for backward compatibility only.
4
- * All implementation lives in packages/core/src/data-fetchers/gotdx.ts
5
- */
6
- export * from '../gotdx';
7
- //# sourceMappingURL=gotdx.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gotdx.d.ts","sourceRoot":"","sources":["../../../src/data-fetchers/gotdx/gotdx.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,UAAU,CAAA"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Re-export from root gotdx fetcher.
3
- * This file exists for backward compatibility only.
4
- * All implementation lives in packages/core/src/data-fetchers/gotdx.ts
5
- */
6
- export * from '../gotdx';
7
- //# sourceMappingURL=gotdx.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gotdx.js","sourceRoot":"","sources":["../../../src/data-fetchers/gotdx/gotdx.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,UAAU,CAAA"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Re-export from root gotdx fetcher.
3
- * This file exists for backward compatibility only.
4
- * All implementation lives in packages/core/src/data-fetchers/gotdx.ts
5
- */
6
- export * from '../gotdx'