velo-plot 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/README.md +15 -8
  2. package/dist/{ChartCore-BhQ4j7f5.js → ChartCore-BpzRvN4Y.js} +998 -855
  3. package/dist/ChartCore-BpzRvN4Y.js.map +1 -0
  4. package/dist/a11y-Bw6urYpr.js +105 -0
  5. package/dist/a11y-Bw6urYpr.js.map +1 -0
  6. package/dist/angular/hooks-entry.d.ts +1 -0
  7. package/dist/angular/hooks.d.ts +26 -0
  8. package/dist/angular/index.d.ts +8 -0
  9. package/dist/angular/velo-plot.component.d.ts +46 -0
  10. package/dist/angular-hooks.d.ts +1 -0
  11. package/dist/angular-hooks.js +9 -0
  12. package/dist/angular-hooks.js.map +1 -0
  13. package/dist/angular.d.ts +1 -0
  14. package/dist/angular.js +166 -0
  15. package/dist/angular.js.map +1 -0
  16. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
  17. package/dist/astro/StackedPlot.astro +19 -0
  18. package/dist/astro/VeloPlot.astro +23 -0
  19. package/dist/{axisFormat-SPX-CD5s.js → axisFormat-CzumxpCL.js} +3 -3
  20. package/dist/axisFormat-CzumxpCL.js.map +1 -0
  21. package/dist/bindings/shared/a11y.d.ts +26 -0
  22. package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
  23. package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
  24. package/dist/bindings/shared/dimensions.d.ts +1 -0
  25. package/dist/bindings/shared/index.d.ts +9 -0
  26. package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
  27. package/dist/bindings/shared/optionsSync.d.ts +7 -0
  28. package/dist/bindings/shared/seriesDiff.d.ts +8 -0
  29. package/dist/bindings/shared/stackedSync.d.ts +9 -0
  30. package/dist/bindings/shared/types.d.ts +46 -0
  31. package/dist/bindings/test-utils/index.d.ts +35 -0
  32. package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
  33. package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
  34. package/dist/chartSyncBridge-DbWrwtyP.js +57 -0
  35. package/dist/chartSyncBridge-DbWrwtyP.js.map +1 -0
  36. package/dist/core/Chart.d.ts +1 -1
  37. package/dist/core/InteractionManager.d.ts +7 -1
  38. package/dist/core/OverlayRenderer.d.ts +5 -0
  39. package/dist/core/annotations/types.d.ts +1 -1
  40. package/dist/core/chart/ChartAxisManager.d.ts +2 -0
  41. package/dist/core/chart/ChartCore.d.ts +17 -2
  42. package/dist/core/chart/ChartPluginBridge.d.ts +1 -0
  43. package/dist/core/chart/ChartRenderLoop.d.ts +2 -0
  44. package/dist/core/chart/ChartStateManager.d.ts +2 -0
  45. package/dist/core/chart/types.d.ts +6 -1
  46. package/dist/core/clipboard/index.d.ts +1 -1
  47. package/dist/core/debug/index.d.ts +1 -1
  48. package/dist/core/keybindings/index.d.ts +1 -1
  49. package/dist/core/loading/index.d.ts +1 -1
  50. package/dist/core/locale/index.d.ts +1 -1
  51. package/dist/core/stacked/paneResize.d.ts +3 -0
  52. package/dist/core/stacked/types.d.ts +10 -0
  53. package/dist/core/sync/index.d.ts +0 -1
  54. package/dist/core/theme-editor/index.d.ts +1 -1
  55. package/dist/createStackedChart-Dm-YqUT7.js +756 -0
  56. package/dist/createStackedChart-Dm-YqUT7.js.map +1 -0
  57. package/dist/examples/PluginDemonstration.d.ts +1 -1
  58. package/dist/gpuRenderer-BpaMYz-k.js.map +1 -1
  59. package/dist/hooks-CYPCxoZx.js +69 -0
  60. package/dist/hooks-CYPCxoZx.js.map +1 -0
  61. package/dist/{index-D7dTq6VB.js → index-0InEyj0q.js} +130 -134
  62. package/dist/index-0InEyj0q.js.map +1 -0
  63. package/dist/index-BMiZoKmm.js.map +1 -1
  64. package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
  65. package/dist/index-CWxIHdwX.js.map +1 -0
  66. package/dist/{index-CUGS98p4.js → index-CaXWSOTk.js} +3 -6
  67. package/dist/index-CaXWSOTk.js.map +1 -0
  68. package/dist/index-Dag88bW4.js.map +1 -1
  69. package/dist/index-qhscKTDy.js.map +1 -1
  70. package/dist/{index-CWipqOLP.js → index-qunX30Xu.js} +2 -2
  71. package/dist/index-qunX30Xu.js.map +1 -0
  72. package/dist/index-x4stH3jD.js.map +1 -1
  73. package/dist/{index.core-fpZ1dYN0.js → index.core-BmZe2jRQ.js} +30 -29
  74. package/dist/index.core-BmZe2jRQ.js.map +1 -0
  75. package/dist/index.core.d.ts +1 -1
  76. package/dist/index.d.ts +3 -3
  77. package/dist/indicators--eJGmVox.js.map +1 -1
  78. package/dist/{mockDatafeed-Cdg5hKEo.js → mockDatafeed-DHIDPcpX.js} +150 -146
  79. package/dist/mockDatafeed-DHIDPcpX.js.map +1 -0
  80. package/dist/optionsSync-QUiN4Inw.js +119 -0
  81. package/dist/optionsSync-QUiN4Inw.js.map +1 -0
  82. package/dist/plugins/3d/index.d.ts +2 -2
  83. package/dist/plugins/3d.d.ts +2 -2
  84. package/dist/plugins/3d.js.map +1 -1
  85. package/dist/plugins/analysis/contours.d.ts +31 -0
  86. package/dist/plugins/analysis/index.d.ts +1 -1
  87. package/dist/plugins/analysis/indicators.d.ts +1 -1
  88. package/dist/plugins/analysis.d.ts +2 -2
  89. package/dist/plugins/analysis.js +495 -408
  90. package/dist/plugins/analysis.js.map +1 -1
  91. package/dist/plugins/annotations/index.d.ts +1 -1
  92. package/dist/plugins/annotations.d.ts +2 -2
  93. package/dist/plugins/annotations.js.map +1 -1
  94. package/dist/plugins/anomaly-detection.js +1 -1
  95. package/dist/plugins/anomaly-detection.js.map +1 -1
  96. package/dist/plugins/broken-axis.d.ts +2 -2
  97. package/dist/plugins/broken-axis.js +170 -181
  98. package/dist/plugins/broken-axis.js.map +1 -1
  99. package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
  100. package/dist/plugins/builtins/index.d.ts +1 -1
  101. package/dist/plugins/caching.d.ts +2 -2
  102. package/dist/plugins/clipboard/index.d.ts +2 -2
  103. package/dist/plugins/clipboard.d.ts +2 -2
  104. package/dist/plugins/clipboard.js.map +1 -1
  105. package/dist/plugins/context-menu/index.d.ts +1 -1
  106. package/dist/plugins/context-menu.d.ts +2 -2
  107. package/dist/plugins/context-menu.js +1 -1
  108. package/dist/plugins/context-menu.js.map +1 -1
  109. package/dist/plugins/data-export/index.d.ts +1 -1
  110. package/dist/plugins/data-export.d.ts +2 -2
  111. package/dist/plugins/data-export.js +2 -2
  112. package/dist/plugins/data-export.js.map +1 -1
  113. package/dist/plugins/data-transform.d.ts +2 -2
  114. package/dist/plugins/data-transform.js +19 -19
  115. package/dist/plugins/data-transform.js.map +1 -1
  116. package/dist/plugins/debug/index.d.ts +2 -2
  117. package/dist/plugins/debug.d.ts +2 -2
  118. package/dist/plugins/debug.js +2 -2
  119. package/dist/plugins/debug.js.map +1 -1
  120. package/dist/plugins/forecasting/algorithms.d.ts +7 -2
  121. package/dist/plugins/forecasting/index.d.ts +1 -1
  122. package/dist/plugins/forecasting/types.d.ts +13 -3
  123. package/dist/plugins/forecasting.js +355 -175
  124. package/dist/plugins/forecasting.js.map +1 -1
  125. package/dist/plugins/gpu/index.d.ts +2 -2
  126. package/dist/plugins/gpu.d.ts +2 -2
  127. package/dist/plugins/gpu.js.map +1 -1
  128. package/dist/plugins/i18n/index.d.ts +2 -2
  129. package/dist/plugins/i18n.d.ts +2 -2
  130. package/dist/plugins/i18n.js.map +1 -1
  131. package/dist/plugins/index.d.ts +1 -1
  132. package/dist/plugins/keyboard.d.ts +2 -2
  133. package/dist/plugins/keyboard.js +65 -5
  134. package/dist/plugins/keyboard.js.map +1 -1
  135. package/dist/plugins/latex/symbols.d.ts +50 -0
  136. package/dist/plugins/latex/types.d.ts +13 -1
  137. package/dist/plugins/latex.js +351 -331
  138. package/dist/plugins/latex.js.map +1 -1
  139. package/dist/plugins/lazy-load.d.ts +2 -2
  140. package/dist/plugins/loading/index.d.ts +1 -1
  141. package/dist/plugins/loading.d.ts +2 -2
  142. package/dist/plugins/ml-integration/native-algorithms.d.ts +24 -4
  143. package/dist/plugins/ml-integration/types.d.ts +19 -0
  144. package/dist/plugins/ml-integration.d.ts +2 -2
  145. package/dist/plugins/ml-integration.js +190 -139
  146. package/dist/plugins/ml-integration.js.map +1 -1
  147. package/dist/plugins/offscreen.d.ts +2 -2
  148. package/dist/plugins/pattern-recognition/types.d.ts +28 -1
  149. package/dist/plugins/pattern-recognition.d.ts +2 -2
  150. package/dist/plugins/pattern-recognition.js +417 -344
  151. package/dist/plugins/pattern-recognition.js.map +1 -1
  152. package/dist/plugins/radar.d.ts +2 -2
  153. package/dist/plugins/regression.d.ts +2 -2
  154. package/dist/plugins/regression.js +1 -1
  155. package/dist/plugins/regression.js.map +1 -1
  156. package/dist/plugins/roi.js +9 -9
  157. package/dist/plugins/roi.js.map +1 -1
  158. package/dist/plugins/snapshot/index.d.ts +1 -1
  159. package/dist/plugins/snapshot/types.d.ts +1 -1
  160. package/dist/plugins/snapshot.d.ts +2 -2
  161. package/dist/plugins/snapshot.js +36 -36
  162. package/dist/plugins/snapshot.js.map +1 -1
  163. package/dist/plugins/streaming/index.d.ts +2 -2
  164. package/dist/plugins/streaming.d.ts +2 -2
  165. package/dist/plugins/sync/index.d.ts +3 -2
  166. package/dist/plugins/sync.d.ts +2 -2
  167. package/dist/plugins/sync.js +1 -1
  168. package/dist/plugins/sync.js.map +1 -1
  169. package/dist/plugins/theme-editor/index.d.ts +1 -1
  170. package/dist/plugins/theme-editor.d.ts +2 -2
  171. package/dist/plugins/tools/index.d.ts +1 -1
  172. package/dist/plugins/tools/tooltip/index.d.ts +1 -1
  173. package/dist/plugins/tools.d.ts +2 -2
  174. package/dist/plugins/tools.js +1 -1
  175. package/dist/plugins/types.d.ts +1 -1
  176. package/dist/plugins/video-recorder.d.ts +2 -2
  177. package/dist/plugins/virtualization.d.ts +2 -2
  178. package/dist/plugins/virtualization.js +1 -1
  179. package/dist/pool-DZ8shSqv.js +109 -0
  180. package/dist/pool-DZ8shSqv.js.map +1 -0
  181. package/dist/react/StackedPlot.d.ts +31 -0
  182. package/dist/react/VeloPlot.d.ts +29 -0
  183. package/dist/react/index.d.ts +25 -3
  184. package/dist/react/useChartSync.d.ts +8 -0
  185. package/dist/react/useIndicator.d.ts +12 -0
  186. package/dist/react/useVeloPlot.d.ts +19 -0
  187. package/dist/react.js +328 -24
  188. package/dist/react.js.map +1 -1
  189. package/dist/scientific/index.d.ts +48 -0
  190. package/dist/scientific.d.ts +1 -0
  191. package/dist/scientific.js +91 -0
  192. package/dist/scientific.js.map +1 -0
  193. package/dist/solid/VeloPlot.d.ts +16 -0
  194. package/dist/solid/index.d.ts +13 -0
  195. package/dist/solid/useChartSync.d.ts +6 -0
  196. package/dist/solid/useIndicator.d.ts +11 -0
  197. package/dist/solid/useStackedPlot.d.ts +14 -0
  198. package/dist/solid/useVeloPlot.d.ts +18 -0
  199. package/dist/solid.d.ts +1 -0
  200. package/dist/solid.js +172 -0
  201. package/dist/solid.js.map +1 -0
  202. package/dist/stackedSync-tnrunZMt.js +100 -0
  203. package/dist/stackedSync-tnrunZMt.js.map +1 -0
  204. package/dist/svelte/StackedPlot.svelte +29 -0
  205. package/dist/svelte/StackedPlot.test.ts +114 -0
  206. package/dist/svelte/VeloPlot.svelte +44 -0
  207. package/dist/svelte/VeloPlot.test.ts +105 -0
  208. package/dist/svelte/index.d.ts +11 -0
  209. package/dist/svelte/index.test.ts +20 -0
  210. package/dist/svelte/index.ts +15 -0
  211. package/dist/svelte/useChartSync.d.ts +8 -0
  212. package/dist/svelte/useChartSync.test.ts +49 -0
  213. package/dist/svelte/useChartSync.ts +29 -0
  214. package/dist/svelte/useIndicator.d.ts +13 -0
  215. package/dist/svelte/useIndicator.test.ts +67 -0
  216. package/dist/svelte/useIndicator.ts +43 -0
  217. package/dist/svelte/useStackedPlot.d.ts +16 -0
  218. package/dist/svelte/useStackedPlot.test.ts +76 -0
  219. package/dist/svelte/useStackedPlot.ts +54 -0
  220. package/dist/svelte/useVeloPlot.d.ts +21 -0
  221. package/dist/svelte/useVeloPlot.test.ts +100 -0
  222. package/dist/svelte/useVeloPlot.ts +81 -0
  223. package/dist/svelte.d.ts +1 -0
  224. package/dist/svelte.js +143 -0
  225. package/dist/svelte.js.map +1 -0
  226. package/dist/symbols-DT0eLlpW.js +568 -0
  227. package/dist/symbols-DT0eLlpW.js.map +1 -0
  228. package/dist/testing/index.d.ts +1 -1
  229. package/dist/theme/index.d.ts +2 -1
  230. package/dist/trading.js +7 -7
  231. package/dist/types.d.ts +1 -1
  232. package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
  233. package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
  234. package/dist/velo-plot.full.js +444 -433
  235. package/dist/velo-plot.full.js.map +1 -1
  236. package/dist/velo-plot.js +15 -15
  237. package/dist/vue/StackedPlot.vue.d.ts +48 -0
  238. package/dist/vue/VeloPlot.vue.d.ts +64 -0
  239. package/dist/vue/index.d.ts +250 -0
  240. package/dist/vue/useChartSync.d.ts +52 -0
  241. package/dist/vue/useIndicator.d.ts +23 -0
  242. package/dist/vue/useStackedPlot.d.ts +15 -0
  243. package/dist/vue/useVeloPlot.d.ts +20 -0
  244. package/dist/vue.d.ts +1 -0
  245. package/dist/vue.js +312 -0
  246. package/dist/vue.js.map +1 -0
  247. package/dist/workers/indicatorsAsync.d.ts +26 -0
  248. package/dist/workers/pool.d.ts +9 -0
  249. package/package.json +88 -10
  250. package/dist/ChartCore-BhQ4j7f5.js.map +0 -1
  251. package/dist/SciPlot-GJvw7GJo.js +0 -463
  252. package/dist/SciPlot-GJvw7GJo.js.map +0 -1
  253. package/dist/axisFormat-SPX-CD5s.js.map +0 -1
  254. package/dist/createStackedChart-DJSmqerD.js +0 -706
  255. package/dist/createStackedChart-DJSmqerD.js.map +0 -1
  256. package/dist/index-CUGS98p4.js.map +0 -1
  257. package/dist/index-CWipqOLP.js.map +0 -1
  258. package/dist/index-D7dTq6VB.js.map +0 -1
  259. package/dist/index-DoYxf1cV.js.map +0 -1
  260. package/dist/index.core-fpZ1dYN0.js.map +0 -1
  261. package/dist/mockDatafeed-Cdg5hKEo.js.map +0 -1
  262. package/dist/pool-15HMCNv8.js +0 -88
  263. package/dist/pool-15HMCNv8.js.map +0 -1
  264. package/dist/react/SciPlot.d.ts +0 -60
  265. package/dist/react/useSciPlot.d.ts +0 -56
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-0InEyj0q.js","sources":["../src/workers/downsample.ts","../src/workers/downsampleAsync.ts","../src/plugins/virtualization/index.ts"],"sourcesContent":["/**\n * LTTB (Largest-Triangle-Three-Buckets) Downsampling Algorithm\n *\n * This algorithm downsamples time-series data while preserving visual features.\n * It's much better than naive sampling for preserving peaks and valleys.\n *\n * Reference: https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf\n */\n\nexport interface DownsampleResult {\n x: Float32Array;\n y: Float32Array;\n /** Original indices of selected points */\n indices: Uint32Array;\n}\n\n/**\n * Downsample data using LTTB algorithm\n *\n * @param x - X values (e.g., potential)\n * @param y - Y values (e.g., current)\n * @param targetPoints - Number of output points\n * @returns Downsampled data\n */\nexport function lttbDownsample(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n targetPoints: number\n): DownsampleResult {\n const length = x.length;\n\n // No need to downsample\n if (targetPoints >= length || targetPoints <= 2) {\n return {\n x: new Float32Array(x),\n y: new Float32Array(y),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const outX = new Float32Array(targetPoints);\n const outY = new Float32Array(targetPoints);\n const outIndices = new Uint32Array(targetPoints);\n\n // Always include first point\n outX[0] = x[0];\n outY[0] = y[0];\n outIndices[0] = 0;\n\n // Bucket size\n const bucketSize = (length - 2) / (targetPoints - 2);\n\n let a = 0; // Previous selected point index\n let outIdx = 1;\n\n for (let i = 0; i < targetPoints - 2; i++) {\n // Calculate bucket boundaries\n const bucketStart = Math.floor((i + 1) * bucketSize) + 1;\n const bucketEnd = Math.floor((i + 2) * bucketSize) + 1;\n\n // Calculate average point of next bucket\n const nextBucketStart = Math.min(bucketEnd, length - 1);\n const nextBucketEnd = Math.min(\n Math.floor((i + 3) * bucketSize) + 1,\n length\n );\n\n let avgX = 0;\n let avgY = 0;\n let avgCount = 0;\n\n for (let j = nextBucketStart; j < nextBucketEnd; j++) {\n avgX += x[j];\n avgY += y[j];\n avgCount++;\n }\n\n if (avgCount > 0) {\n avgX /= avgCount;\n avgY /= avgCount;\n }\n\n // Find point in current bucket with largest triangle area\n let maxArea = -1;\n let maxIndex = bucketStart;\n\n const aX = x[a];\n const aY = y[a];\n\n for (let j = bucketStart; j < bucketEnd && j < length; j++) {\n // Calculate triangle area (simplified: |x1(y2-y3) + x2(y3-y1) + x3(y1-y2)| / 2)\n const area = Math.abs(\n (aX - avgX) * (y[j] - aY) - (aX - x[j]) * (avgY - aY)\n );\n\n if (area > maxArea) {\n maxArea = area;\n maxIndex = j;\n }\n }\n\n // Store selected point\n outX[outIdx] = x[maxIndex];\n outY[outIdx] = y[maxIndex];\n outIndices[outIdx] = maxIndex;\n\n a = maxIndex;\n outIdx++;\n }\n\n // Always include last point\n outX[targetPoints - 1] = x[length - 1];\n outY[targetPoints - 1] = y[length - 1];\n outIndices[targetPoints - 1] = length - 1;\n\n return { x: outX, y: outY, indices: outIndices };\n}\n\n/**\n * Min-Max per bucket downsampling\n *\n * Simpler alternative to LTTB that preserves extremes in each bucket.\n * Uses 2 points per bucket (min and max), so output is ~2x target.\n */\nexport function minMaxDownsample(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n bucketCount: number\n): DownsampleResult {\n const length = x.length;\n\n if (bucketCount >= length / 2) {\n return {\n x: new Float32Array(x),\n y: new Float32Array(y),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const bucketSize = length / bucketCount;\n const outX: number[] = [];\n const outY: number[] = [];\n const outIndices: number[] = [];\n\n for (let b = 0; b < bucketCount; b++) {\n const start = Math.floor(b * bucketSize);\n const end = Math.floor((b + 1) * bucketSize);\n\n let minY = Infinity;\n let maxY = -Infinity;\n let minIdx = start;\n let maxIdx = start;\n\n for (let i = start; i < end && i < length; i++) {\n if (y[i] < minY) {\n minY = y[i];\n minIdx = i;\n }\n if (y[i] > maxY) {\n maxY = y[i];\n maxIdx = i;\n }\n }\n\n // Add points in order (min first if it comes before max)\n if (minIdx <= maxIdx) {\n outX.push(x[minIdx], x[maxIdx]);\n outY.push(y[minIdx], y[maxIdx]);\n outIndices.push(minIdx, maxIdx);\n } else {\n outX.push(x[maxIdx], x[minIdx]);\n outY.push(y[maxIdx], y[minIdx]);\n outIndices.push(maxIdx, minIdx);\n }\n }\n\n return {\n x: new Float32Array(outX),\n y: new Float32Array(outY),\n indices: new Uint32Array(outIndices),\n };\n}\n\n/**\n * Calculate optimal target points based on canvas width\n */\nexport function calculateTargetPoints(\n dataLength: number,\n canvasWidth: number,\n pointsPerPixel = 2\n): number {\n // Never draw more than pointsPerPixel per pixel\n const maxPoints = canvasWidth * pointsPerPixel;\n return Math.min(dataLength, maxPoints);\n}\n\nexport interface OhlcDownsampleResult {\n x: Float32Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n indices: Uint32Array;\n}\n\n/**\n * Aggregate OHLC bars into fewer buckets while preserving extremes.\n * Each bucket: open=first open, close=last close, high=max high, low=min low, x=last x.\n */\nexport function ohlcMinMaxDownsample(\n x: Float32Array | Float64Array,\n open: Float32Array | Float64Array,\n high: Float32Array | Float64Array,\n low: Float32Array | Float64Array,\n close: Float32Array | Float64Array,\n targetBars: number,\n): OhlcDownsampleResult {\n const length = x.length;\n if (targetBars >= length || targetBars <= 1 || length === 0) {\n return {\n x: new Float32Array(x),\n open: new Float32Array(open),\n high: new Float32Array(high),\n low: new Float32Array(low),\n close: new Float32Array(close),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const bucketSize = length / targetBars;\n const outX: number[] = [];\n const outOpen: number[] = [];\n const outHigh: number[] = [];\n const outLow: number[] = [];\n const outClose: number[] = [];\n const outIndices: number[] = [];\n\n for (let b = 0; b < targetBars; b++) {\n const start = Math.floor(b * bucketSize);\n const end = Math.min(length, Math.floor((b + 1) * bucketSize));\n if (start >= end) continue;\n\n let hi = -Infinity;\n let lo = Infinity;\n let lastIdx = start;\n\n for (let i = start; i < end; i++) {\n if (high[i] > hi) hi = high[i];\n if (low[i] < lo) lo = low[i];\n lastIdx = i;\n }\n\n outOpen.push(open[start]);\n outHigh.push(hi);\n outLow.push(lo);\n outClose.push(close[lastIdx]);\n outX.push(x[lastIdx]);\n outIndices.push(lastIdx);\n }\n\n return {\n x: new Float32Array(outX),\n open: new Float32Array(outOpen),\n high: new Float32Array(outHigh),\n low: new Float32Array(outLow),\n close: new Float32Array(outClose),\n indices: new Uint32Array(outIndices),\n };\n}\n\n/** Binary search lower bound: first index where x[i] >= value */\nexport function lowerBoundX(\n x: Float32Array | Float64Array,\n value: number,\n): number {\n let lo = 0;\n let hi = x.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (x[mid] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/** Binary search upper bound: first index where x[i] > value */\nexport function upperBoundX(\n x: Float32Array | Float64Array,\n value: number,\n): number {\n let lo = 0;\n let hi = x.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (x[mid] <= value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nexport interface ViewportSlice {\n x: Float32Array;\n y?: Float32Array;\n open?: Float32Array;\n high?: Float32Array;\n low?: Float32Array;\n close?: Float32Array;\n start: number;\n end: number;\n}\n\n/**\n * Slice sorted x-series to visible range plus buffer (fraction of visible width).\n */\nexport function sliceSeriesToViewport(\n source: {\n x: Float32Array | Float64Array;\n y?: Float32Array | Float64Array;\n open?: Float32Array | Float64Array;\n high?: Float32Array | Float64Array;\n low?: Float32Array | Float64Array;\n close?: Float32Array | Float64Array;\n },\n xMin: number,\n xMax: number,\n bufferRatio = 0.5,\n): ViewportSlice {\n const length = source.x.length;\n if (length === 0) {\n return { x: new Float32Array(0), start: 0, end: 0 };\n }\n\n const range = Math.max(xMax - xMin, 1e-12);\n const paddedMin = xMin - range * bufferRatio;\n const paddedMax = xMax + range * bufferRatio;\n\n let start = lowerBoundX(source.x, paddedMin);\n let end = upperBoundX(source.x, paddedMax);\n start = Math.max(0, start);\n end = Math.min(length, Math.max(end, start + 1));\n\n const slice = <T extends Float32Array | Float64Array>(arr: T | undefined): Float32Array | undefined => {\n if (!arr) return undefined;\n return new Float32Array(arr.subarray(start, end));\n };\n\n return {\n x: new Float32Array(source.x.subarray(start, end)),\n y: slice(source.y),\n open: slice(source.open),\n high: slice(source.high),\n low: slice(source.low),\n close: slice(source.close),\n start,\n end,\n };\n}\n","/**\n * Async downsampling via shared worker pool (main-thread fallback in Node/tests).\n * @module workers/downsampleAsync\n */\n\nimport {\n lttbDownsample,\n minMaxDownsample,\n ohlcMinMaxDownsample,\n type OhlcDownsampleResult,\n type DownsampleResult,\n} from \"./downsample\";\nimport { WorkerPool, nextTaskId } from \"./pool\";\n\ntype DownsampleTask = {\n id: string;\n type: \"downsample\";\n x: Float32Array;\n y: Float32Array;\n targetPoints: number;\n algorithm: \"lttb\" | \"minmax\";\n};\n\ntype OhlcDownsampleTask = {\n id: string;\n type: \"ohlc-downsample\";\n x: Float32Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n targetBars: number;\n};\n\ntype DownsampleWorkerResult =\n | {\n id: string;\n type: \"downsample-result\";\n x: Float32Array;\n y: Float32Array;\n }\n | {\n id: string;\n type: \"ohlc-downsample-result\";\n x: Float32Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n }\n | { id: string; type: \"error\"; error: string };\n\nlet pool: WorkerPool<DownsampleTask | OhlcDownsampleTask, DownsampleWorkerResult> | null = null;\n\nfunction getPool() {\n if (pool) return pool;\n\n pool = new WorkerPool<DownsampleTask | OhlcDownsampleTask, DownsampleWorkerResult>(\n () => new Worker(new URL(\"./downsample.worker.ts\", import.meta.url), { type: \"module\" }),\n {\n poolSize: 2,\n syncFallback: true,\n syncHandler: (task) => {\n if (task.type === \"downsample\") {\n const result =\n task.algorithm === \"minmax\"\n ? minMaxDownsample(task.x, task.y, Math.ceil(task.targetPoints / 2))\n : lttbDownsample(task.x, task.y, task.targetPoints);\n return { id: task.id, type: \"downsample-result\", x: result.x, y: result.y };\n }\n\n const result = ohlcMinMaxDownsample(\n task.x,\n task.open,\n task.high,\n task.low,\n task.close,\n task.targetBars,\n );\n return {\n id: task.id,\n type: \"ohlc-downsample-result\",\n x: result.x,\n open: result.open,\n high: result.high,\n low: result.low,\n close: result.close,\n };\n },\n },\n );\n\n return pool;\n}\n\nexport async function downsampleAsync(\n x: Float32Array,\n y: Float32Array,\n targetPoints: number,\n algorithm: \"lttb\" | \"minmax\" = \"lttb\",\n): Promise<DownsampleResult> {\n const id = nextTaskId(\"downsample\");\n const result = await getPool().run({\n id,\n type: \"downsample\",\n x,\n y,\n targetPoints,\n algorithm,\n });\n\n // Worker/pool failures surface as a rejected run() promise (sync fallback or\n // reject), so a resolved value is always a success payload; we only guard the\n // shape here.\n if (result.type !== \"downsample-result\") {\n throw new Error(\"Unexpected downsample worker response\");\n }\n\n return {\n x: result.x,\n y: result.y,\n indices: new Uint32Array(result.x.length),\n };\n}\n\nexport async function ohlcDownsampleAsync(\n x: Float32Array,\n open: Float32Array,\n high: Float32Array,\n low: Float32Array,\n close: Float32Array,\n targetBars: number,\n): Promise<OhlcDownsampleResult> {\n const id = nextTaskId(\"ohlc-downsample\");\n const result = await getPool().run({\n id,\n type: \"ohlc-downsample\",\n x,\n open,\n high,\n low,\n close,\n targetBars,\n });\n\n if (result.type !== \"ohlc-downsample-result\") {\n throw new Error(\"Unexpected OHLC downsample worker response\");\n }\n\n return {\n x: result.x,\n open: result.open,\n high: result.high,\n low: result.low,\n close: result.close,\n indices: new Uint32Array(result.x.length),\n };\n}\n\nexport function destroyDownsamplePool(): void {\n pool?.destroy();\n pool = null;\n}\n\nexport function getDownsamplePoolSize(): number {\n return pool?.size() ?? 0;\n}\n","/**\n * @fileoverview Data virtualization plugin (LOD/min-max)\n * @module plugins/virtualization\n */\n\nimport type {\n PluginVirtualizationConfig,\n VirtualizationAPI,\n VirtualizationStats,\n VirtualizationMode,\n VirtualizationStrategy,\n} from \"./types\";\nimport type { ChartPlugin, PluginContext, PluginManifest } from \"../types\";\nimport type { Series } from \"../../core/Series\";\nimport type { SeriesUpdateData } from \"../../types\";\nimport {\n lttbDownsample,\n minMaxDownsample,\n ohlcMinMaxDownsample,\n calculateTargetPoints,\n sliceSeriesToViewport,\n} from \"../../workers/downsample\";\nimport { downsampleAsync, ohlcDownsampleAsync } from \"../../workers/downsampleAsync\";\n\nconst manifest: PluginManifest = {\n name: \"velo-plot-virtualization\",\n version: \"1.0.0\",\n description: \"Viewport-aware data virtualization with LOD strategies\",\n provides: [\"performance\", \"data-virtualization\"],\n tags: [\"performance\", \"lod\", \"virtualization\"],\n};\n\nconst DEFAULT_CONFIG: Required<PluginVirtualizationConfig> = {\n enabled: true,\n precision: \"lod\",\n mode: \"lod\",\n targetPoints: \"auto\",\n pointsPerPixel: 2,\n lodLevels: [1, 4, 8, 16],\n strategy: \"lttb\",\n reuseOriginalData: true,\n syncWithLazyLoad: true,\n includeSeries: [],\n excludeSeries: [],\n debug: false,\n viewportBuffer: 0.5,\n useWorker: true,\n workerThreshold: 250_000,\n};\n\ntype SeriesCache = {\n x: Float32Array | Float64Array;\n y?: Float32Array | Float64Array;\n open?: Float32Array | Float64Array;\n high?: Float32Array | Float64Array;\n low?: Float32Array | Float64Array;\n close?: Float32Array | Float64Array;\n};\n\nexport function PluginVirtualization(\n userConfig: Partial<PluginVirtualizationConfig> = {}\n): ChartPlugin<PluginVirtualizationConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n let isInternalUpdate = false;\n\n const originalData = new Map<string, SeriesCache>();\n const stats = new Map<string, VirtualizationStats>();\n\n let originalUpdateSeries: ((id: string, data: SeriesUpdateData) => void) | null = null;\n let originalAppendData: ((id: string, x: number[] | Float32Array, y: number[] | Float32Array) => void) | null = null;\n let refreshRaf = 0;\n const applyGeneration = new Map<string, number>();\n let lastViewKey = \"\";\n\n function log(message: string, ...args: unknown[]) {\n if (config.debug && ctx) {\n ctx.log.info(`[Virtualization] ${message}`, ...args);\n }\n }\n\n function shouldVirtualize(series: Series): boolean {\n if (!config.enabled) return false;\n if (config.precision === \"full\") return false;\n if (config.includeSeries.length > 0 && !config.includeSeries.includes(series.getId())) return false;\n if (config.excludeSeries.includes(series.getId())) return false;\n\n const type = series.getType();\n return (\n type === \"line\" ||\n type === \"scatter\" ||\n type === \"line+scatter\" ||\n type === \"step\" ||\n type === \"step+scatter\" ||\n type === \"candlestick\" ||\n type === \"bar\"\n );\n }\n\n function isOhlcSeries(series: Series): boolean {\n return series.getType() === \"candlestick\";\n }\n\n function buildUpdatePayload(cache: SeriesCache): SeriesUpdateData {\n if (cache.open && cache.high && cache.low && cache.close) {\n return {\n x: cache.x,\n open: cache.open,\n high: cache.high,\n low: cache.low,\n close: cache.close,\n };\n }\n return { x: cache.x, y: cache.y! };\n }\n\n function getTargetPoints(dataLength: number): number {\n if (config.targetPoints !== \"auto\") return Math.max(2, config.targetPoints);\n const width = ctx!.render.canvasSize.width / ctx!.render.pixelRatio;\n return calculateTargetPoints(dataLength, width, config.pointsPerPixel);\n }\n\n function downsampleData(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n targetPoints: number,\n strategy: VirtualizationStrategy\n ): { x: Float32Array; y: Float32Array } {\n if (targetPoints >= x.length || x.length <= 2) {\n return { x: new Float32Array(x), y: new Float32Array(y) };\n }\n\n if (strategy === \"minmax\") {\n const bucketCount = Math.ceil(targetPoints / 2);\n const result = minMaxDownsample(x, y, bucketCount);\n return { x: result.x, y: result.y };\n }\n\n const result = lttbDownsample(x, y, targetPoints);\n return { x: result.x, y: result.y };\n }\n\n function cacheOriginal(seriesId: string, data: SeriesCache): void {\n if (!config.reuseOriginalData) return;\n originalData.set(seriesId, { ...data });\n }\n\n function restoreOriginal(seriesId: string): SeriesCache | null {\n return originalData.get(seriesId) ?? null;\n }\n\n function updateStats(\n seriesId: string,\n originalPoints: number,\n renderedPoints: number,\n targetPoints: number,\n mode: VirtualizationMode,\n strategy: VirtualizationStrategy,\n ): void {\n stats.set(seriesId, {\n seriesId,\n originalPoints,\n renderedPoints,\n targetPoints,\n lastUpdated: Date.now(),\n mode,\n strategy,\n });\n }\n\n function captureOriginalFromSeries(series: Series): SeriesCache | null {\n const live = series.getData();\n if (!live?.x?.length) return null;\n\n if (isOhlcSeries(series)) {\n if (!live.open || !live.high || !live.low || !live.close) return null;\n const cache: SeriesCache = {\n x: live.x,\n open: live.open,\n high: live.high,\n low: live.low,\n close: live.close,\n };\n cacheOriginal(series.getId(), cache);\n return cache;\n }\n\n if (!live.y) return null;\n const cache: SeriesCache = { x: live.x, y: live.y };\n cacheOriginal(series.getId(), cache);\n return cache;\n }\n\n function getSourceData(series: Series): SeriesCache | null {\n return restoreOriginal(series.getId()) ?? captureOriginalFromSeries(series);\n }\n\n function getViewportSource(source: SeriesCache): SeriesCache {\n const bounds = ctx!.data.getViewBounds?.();\n if (!bounds) return source;\n\n const sliced = sliceSeriesToViewport(\n source,\n bounds.xMin,\n bounds.xMax,\n config.viewportBuffer,\n );\n if (sliced.end - sliced.start >= source.x.length) return source;\n\n return {\n x: sliced.x,\n y: sliced.y,\n open: sliced.open,\n high: sliced.high,\n low: sliced.low,\n close: sliced.close,\n };\n }\n\n function commitDownsampled(seriesId: string, payload: SeriesUpdateData): void {\n isInternalUpdate = true;\n originalUpdateSeries!(seriesId, payload);\n isInternalUpdate = false;\n }\n\n async function runDownsample(\n source: SeriesCache,\n targetPoints: number,\n strategy: VirtualizationStrategy,\n ): Promise<{ x: Float32Array; y: Float32Array }> {\n const x = new Float32Array(source.x);\n const y = new Float32Array(source.y!);\n\n if (config.useWorker && x.length >= config.workerThreshold) {\n const algorithm = strategy === \"minmax\" ? \"minmax\" : \"lttb\";\n const result = await downsampleAsync(x, y, targetPoints, algorithm);\n return { x: result.x, y: result.y };\n }\n\n return downsampleData(x, y, targetPoints, strategy);\n }\n\n async function applyVirtualization(series: Series): Promise<void> {\n if (!ctx || !originalUpdateSeries) return;\n const seriesId = series.getId();\n\n if (!shouldVirtualize(series)) {\n const original = restoreOriginal(seriesId);\n if (original && config.reuseOriginalData) {\n commitDownsampled(seriesId, buildUpdatePayload(original));\n }\n return;\n }\n\n const source = getSourceData(series);\n if (!source?.x?.length) return;\n\n const viewportSource = getViewportSource(source);\n const gen = (applyGeneration.get(seriesId) ?? 0) + 1;\n applyGeneration.set(seriesId, gen);\n\n if (isOhlcSeries(series)) {\n if (!viewportSource.open || !viewportSource.high || !viewportSource.low || !viewportSource.close) {\n return;\n }\n\n const targetBars = getTargetPoints(viewportSource.x.length);\n const x = new Float32Array(viewportSource.x);\n const open = new Float32Array(viewportSource.open);\n const high = new Float32Array(viewportSource.high);\n const low = new Float32Array(viewportSource.low);\n const close = new Float32Array(viewportSource.close);\n\n const downsampled =\n config.useWorker && x.length >= config.workerThreshold\n ? await ohlcDownsampleAsync(x, open, high, low, close, targetBars)\n : ohlcMinMaxDownsample(x, open, high, low, close, targetBars);\n\n if (applyGeneration.get(seriesId) !== gen) return;\n\n commitDownsampled(seriesId, {\n x: downsampled.x,\n open: downsampled.open,\n high: downsampled.high,\n low: downsampled.low,\n close: downsampled.close,\n });\n\n updateStats(seriesId, source.x.length, downsampled.x.length, targetBars, config.mode, \"minmax\");\n return;\n }\n\n if (!viewportSource.y) return;\n\n const targetPoints = getTargetPoints(viewportSource.x.length);\n const strategy = series.getType() === \"bar\" ? \"minmax\" : config.strategy;\n const downsampled = await runDownsample(viewportSource, targetPoints, strategy);\n\n if (applyGeneration.get(seriesId) !== gen) return;\n\n commitDownsampled(seriesId, { x: downsampled.x, y: downsampled.y });\n updateStats(seriesId, source.x.length, downsampled.x.length, targetPoints, config.mode, strategy);\n }\n\n function refreshAll(): void {\n if (!ctx) return;\n ctx.data.getAllSeries().forEach((series) => {\n void applyVirtualization(series);\n });\n }\n\n function scheduleRefreshAll(): void {\n if (!ctx) return;\n const bounds = ctx.data.getViewBounds?.();\n if (bounds) {\n const key = `${bounds.xMin}:${bounds.xMax}:${bounds.yMin}:${bounds.yMax}:${ctx.render.canvasSize.width}`;\n if (key === lastViewKey) return;\n lastViewKey = key;\n }\n\n if (refreshRaf) return;\n refreshRaf = requestAnimationFrame(() => {\n refreshRaf = 0;\n refreshAll();\n });\n }\n\n function handleUpdateSeries(id: string, data: SeriesUpdateData): void {\n if (!ctx || !originalUpdateSeries) return;\n if (!config.enabled || isInternalUpdate) {\n originalUpdateSeries(id, data);\n return;\n }\n\n const series = ctx.chart.getSeries?.(id) as Series | undefined;\n if (!series) {\n originalUpdateSeries(id, data);\n return;\n }\n\n const original = restoreOriginal(id);\n if (original && config.reuseOriginalData) {\n isInternalUpdate = true;\n originalUpdateSeries(id, buildUpdatePayload(original));\n isInternalUpdate = false;\n }\n\n originalUpdateSeries(id, data);\n\n const updatedSeries = ctx.chart.getSeries?.(id) as Series | undefined;\n if (updatedSeries) {\n originalData.delete(id);\n captureOriginalFromSeries(updatedSeries);\n void applyVirtualization(updatedSeries);\n }\n }\n\n function handleAppendData(\n id: string,\n x: number[] | Float32Array,\n y: number[] | Float32Array\n ): void {\n if (!ctx || !originalAppendData || !originalUpdateSeries) return;\n\n if (!config.enabled || isInternalUpdate) {\n originalAppendData(id, x, y);\n return;\n }\n\n const series = ctx.chart.getSeries?.(id) as Series | undefined;\n if (!series) {\n originalAppendData(id, x, y);\n return;\n }\n\n const original = restoreOriginal(id);\n if (original && config.reuseOriginalData) {\n isInternalUpdate = true;\n originalUpdateSeries(id, buildUpdatePayload(original));\n isInternalUpdate = false;\n }\n\n originalAppendData(id, x, y);\n\n const updatedSeries = ctx.chart.getSeries?.(id) as Series | undefined;\n if (updatedSeries) {\n const cached = restoreOriginal(id);\n if (cached?.y && config.reuseOriginalData) {\n // Replace (not cacheOriginal, which no-ops on an existing entry) so the\n // full-resolution cache grows with the appended points.\n originalData.set(id, {\n x: appendTyped(cached.x, x),\n y: appendTyped(cached.y, y),\n });\n } else {\n originalData.delete(id);\n captureOriginalFromSeries(updatedSeries);\n }\n void applyVirtualization(updatedSeries);\n }\n }\n\n function appendTyped(\n existing: Float32Array | Float64Array,\n incoming: number[] | Float32Array,\n ): Float32Array {\n const next = incoming instanceof Float32Array ? incoming : Float32Array.from(incoming);\n const merged = new Float32Array(existing.length + next.length);\n merged.set(existing);\n merged.set(next, existing.length);\n return merged;\n }\n\n const api: VirtualizationAPI & Record<string, unknown> = {\n enable() {\n config.enabled = true;\n refreshAll();\n },\n disable() {\n config.enabled = false;\n if (!ctx || !originalUpdateSeries) return;\n const updater = originalUpdateSeries;\n ctx.data.getAllSeries().forEach((series) => {\n const original = restoreOriginal(series.getId());\n if (original) {\n isInternalUpdate = true;\n updater(series.getId(), buildUpdatePayload(original));\n isInternalUpdate = false;\n }\n });\n },\n isEnabled() {\n return config.enabled;\n },\n updateConfig(newConfig) {\n Object.assign(config, newConfig);\n refreshAll();\n },\n invalidate(seriesId) {\n if (!ctx) return;\n if (seriesId) {\n const series = ctx.chart.getSeries?.(seriesId) as Series | undefined;\n if (series) applyVirtualization(series);\n return;\n }\n refreshAll();\n },\n getStats(seriesId) {\n return stats.get(seriesId) ?? null;\n },\n getAllStats() {\n return Array.from(stats.values());\n },\n };\n\n return {\n manifest,\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n // API is exposed via plugin.api / chart.virtualization getter (ChartPluginBridge)\n\n const chart = ctx.chart as any;\n originalUpdateSeries = chart.updateSeries?.bind(chart) ?? null;\n originalAppendData = chart.appendData?.bind(chart) ?? null;\n\n if (originalUpdateSeries) {\n chart.updateSeries = (id: string, data: SeriesUpdateData) => handleUpdateSeries(id, data);\n }\n\n if (originalAppendData) {\n chart.appendData = (id: string, x: number[] | Float32Array, y: number[] | Float32Array) =>\n handleAppendData(id, x, y);\n }\n\n ctx.events.on(\"zoom\", () => scheduleRefreshAll());\n ctx.events.on(\"pan\", () => scheduleRefreshAll());\n ctx.events.on(\"resize\", () => {\n lastViewKey = \"\";\n scheduleRefreshAll();\n });\n\n refreshAll();\n log(\"Initialized\");\n },\n onDestroy(pluginCtx: PluginContext) {\n if (refreshRaf) cancelAnimationFrame(refreshRaf);\n refreshRaf = 0;\n applyGeneration.clear();\n if (originalUpdateSeries) {\n (pluginCtx.chart as any).updateSeries = originalUpdateSeries;\n }\n if (originalAppendData) {\n (pluginCtx.chart as any).appendData = originalAppendData;\n }\n ctx = null;\n originalData.clear();\n stats.clear();\n },\n api,\n };\n}\n\nexport default PluginVirtualization;\n\n// Type exports\nexport type {\n PluginVirtualizationConfig,\n VirtualizationAPI,\n VirtualizationStats,\n VirtualizationMode,\n VirtualizationStrategy,\n} from \"./types\";\n"],"names":["lttbDownsample","x","y","targetPoints","length","_","i","outX","outY","outIndices","bucketSize","a","outIdx","bucketStart","bucketEnd","nextBucketStart","nextBucketEnd","avgX","avgY","avgCount","j","maxArea","maxIndex","aX","aY","area","minMaxDownsample","bucketCount","b","start","end","minY","maxY","minIdx","maxIdx","calculateTargetPoints","dataLength","canvasWidth","pointsPerPixel","maxPoints","ohlcMinMaxDownsample","open","high","low","close","targetBars","outOpen","outHigh","outLow","outClose","hi","lo","lastIdx","lowerBoundX","value","mid","upperBoundX","sliceSeriesToViewport","source","xMin","xMax","bufferRatio","range","paddedMin","paddedMax","slice","arr","pool","getPool","WorkerPool","task","result","downsampleAsync","algorithm","id","nextTaskId","ohlcDownsampleAsync","destroyDownsamplePool","getDownsamplePoolSize","manifest","DEFAULT_CONFIG","PluginVirtualization","userConfig","config","ctx","isInternalUpdate","originalData","stats","originalUpdateSeries","originalAppendData","refreshRaf","applyGeneration","lastViewKey","log","message","args","shouldVirtualize","series","type","isOhlcSeries","buildUpdatePayload","cache","getTargetPoints","width","downsampleData","strategy","cacheOriginal","seriesId","data","restoreOriginal","updateStats","originalPoints","renderedPoints","mode","captureOriginalFromSeries","live","_a","getSourceData","getViewportSource","bounds","_b","sliced","commitDownsampled","payload","runDownsample","applyVirtualization","original","viewportSource","gen","downsampled","refreshAll","scheduleRefreshAll","key","handleUpdateSeries","updatedSeries","_d","_c","handleAppendData","cached","appendTyped","existing","incoming","next","merged","pluginCtx","chart","updater","newConfig"],"mappings":";AAwBO,SAASA,EACdC,GACAC,GACAC,GACkB;AAClB,QAAMC,IAASH,EAAE;AAGjB,MAAIE,KAAgBC,KAAUD,KAAgB;AAC5C,WAAO;AAAA,MACL,GAAG,IAAI,aAAaF,CAAC;AAAA,MACrB,GAAG,IAAI,aAAaC,CAAC;AAAA,MACrB,SAAS,IAAI,YAAY,MAAM,KAAK,EAAE,QAAAE,EAAA,GAAU,CAACC,GAAGC,MAAMA,CAAC,CAAC;AAAA,IAAA;AAIhE,QAAMC,IAAO,IAAI,aAAaJ,CAAY,GACpCK,IAAO,IAAI,aAAaL,CAAY,GACpCM,IAAa,IAAI,YAAYN,CAAY;AAG/C,EAAAI,EAAK,CAAC,IAAIN,EAAE,CAAC,GACbO,EAAK,CAAC,IAAIN,EAAE,CAAC,GACbO,EAAW,CAAC,IAAI;AAGhB,QAAMC,KAAcN,IAAS,MAAMD,IAAe;AAElD,MAAIQ,IAAI,GACJC,IAAS;AAEb,WAASN,IAAI,GAAGA,IAAIH,IAAe,GAAGG,KAAK;AAEzC,UAAMO,IAAc,KAAK,OAAOP,IAAI,KAAKI,CAAU,IAAI,GACjDI,IAAY,KAAK,OAAOR,IAAI,KAAKI,CAAU,IAAI,GAG/CK,IAAkB,KAAK,IAAID,GAAWV,IAAS,CAAC,GAChDY,IAAgB,KAAK;AAAA,MACzB,KAAK,OAAOV,IAAI,KAAKI,CAAU,IAAI;AAAA,MACnCN;AAAA,IAAA;AAGF,QAAIa,IAAO,GACPC,IAAO,GACPC,IAAW;AAEf,aAASC,IAAIL,GAAiBK,IAAIJ,GAAeI;AAC/C,MAAAH,KAAQhB,EAAEmB,CAAC,GACXF,KAAQhB,EAAEkB,CAAC,GACXD;AAGF,IAAIA,IAAW,MACbF,KAAQE,GACRD,KAAQC;AAIV,QAAIE,IAAU,IACVC,IAAWT;AAEf,UAAMU,IAAKtB,EAAEU,CAAC,GACRa,IAAKtB,EAAES,CAAC;AAEd,aAASS,IAAIP,GAAaO,IAAIN,KAAaM,IAAIhB,GAAQgB,KAAK;AAE1D,YAAMK,IAAO,KAAK;AAAA,SACfF,IAAKN,MAASf,EAAEkB,CAAC,IAAII,MAAOD,IAAKtB,EAAEmB,CAAC,MAAMF,IAAOM;AAAA,MAAA;AAGpD,MAAIC,IAAOJ,MACTA,IAAUI,GACVH,IAAWF;AAAA,IAEf;AAGA,IAAAb,EAAKK,CAAM,IAAIX,EAAEqB,CAAQ,GACzBd,EAAKI,CAAM,IAAIV,EAAEoB,CAAQ,GACzBb,EAAWG,CAAM,IAAIU,GAErBX,IAAIW,GACJV;AAAA,EACF;AAGA,SAAAL,EAAKJ,IAAe,CAAC,IAAIF,EAAEG,IAAS,CAAC,GACrCI,EAAKL,IAAe,CAAC,IAAID,EAAEE,IAAS,CAAC,GACrCK,EAAWN,IAAe,CAAC,IAAIC,IAAS,GAEjC,EAAE,GAAGG,GAAM,GAAGC,GAAM,SAASC,EAAA;AACtC;AAQO,SAASiB,EACdzB,GACAC,GACAyB,GACkB;AAClB,QAAMvB,IAASH,EAAE;AAEjB,MAAI0B,KAAevB,IAAS;AAC1B,WAAO;AAAA,MACL,GAAG,IAAI,aAAaH,CAAC;AAAA,MACrB,GAAG,IAAI,aAAaC,CAAC;AAAA,MACrB,SAAS,IAAI,YAAY,MAAM,KAAK,EAAE,QAAAE,EAAA,GAAU,CAACC,GAAGC,MAAMA,CAAC,CAAC;AAAA,IAAA;AAIhE,QAAMI,IAAaN,IAASuB,GACtBpB,IAAiB,CAAA,GACjBC,IAAiB,CAAA,GACjBC,IAAuB,CAAA;AAE7B,WAASmB,IAAI,GAAGA,IAAID,GAAaC,KAAK;AACpC,UAAMC,IAAQ,KAAK,MAAMD,IAAIlB,CAAU,GACjCoB,IAAM,KAAK,OAAOF,IAAI,KAAKlB,CAAU;AAE3C,QAAIqB,IAAO,OACPC,IAAO,QACPC,IAASJ,GACTK,IAASL;AAEb,aAASvB,IAAIuB,GAAOvB,IAAIwB,KAAOxB,IAAIF,GAAQE;AACzC,MAAIJ,EAAEI,CAAC,IAAIyB,MACTA,IAAO7B,EAAEI,CAAC,GACV2B,IAAS3B,IAEPJ,EAAEI,CAAC,IAAI0B,MACTA,IAAO9B,EAAEI,CAAC,GACV4B,IAAS5B;AAKb,IAAI2B,KAAUC,KACZ3B,EAAK,KAAKN,EAAEgC,CAAM,GAAGhC,EAAEiC,CAAM,CAAC,GAC9B1B,EAAK,KAAKN,EAAE+B,CAAM,GAAG/B,EAAEgC,CAAM,CAAC,GAC9BzB,EAAW,KAAKwB,GAAQC,CAAM,MAE9B3B,EAAK,KAAKN,EAAEiC,CAAM,GAAGjC,EAAEgC,CAAM,CAAC,GAC9BzB,EAAK,KAAKN,EAAEgC,CAAM,GAAGhC,EAAE+B,CAAM,CAAC,GAC9BxB,EAAW,KAAKyB,GAAQD,CAAM;AAAA,EAElC;AAEA,SAAO;AAAA,IACL,GAAG,IAAI,aAAa1B,CAAI;AAAA,IACxB,GAAG,IAAI,aAAaC,CAAI;AAAA,IACxB,SAAS,IAAI,YAAYC,CAAU;AAAA,EAAA;AAEvC;AAKO,SAAS0B,GACdC,GACAC,GACAC,IAAiB,GACT;AAER,QAAMC,IAAYF,IAAcC;AAChC,SAAO,KAAK,IAAIF,GAAYG,CAAS;AACvC;AAeO,SAASC,EACdvC,GACAwC,GACAC,GACAC,GACAC,GACAC,GACsB;AACtB,QAAMzC,IAASH,EAAE;AACjB,MAAI4C,KAAczC,KAAUyC,KAAc,KAAKzC,MAAW;AACxD,WAAO;AAAA,MACL,GAAG,IAAI,aAAaH,CAAC;AAAA,MACrB,MAAM,IAAI,aAAawC,CAAI;AAAA,MAC3B,MAAM,IAAI,aAAaC,CAAI;AAAA,MAC3B,KAAK,IAAI,aAAaC,CAAG;AAAA,MACzB,OAAO,IAAI,aAAaC,CAAK;AAAA,MAC7B,SAAS,IAAI,YAAY,MAAM,KAAK,EAAE,QAAAxC,EAAA,GAAU,CAACC,GAAGC,MAAMA,CAAC,CAAC;AAAA,IAAA;AAIhE,QAAMI,IAAaN,IAASyC,GACtBtC,IAAiB,CAAA,GACjBuC,IAAoB,CAAA,GACpBC,IAAoB,CAAA,GACpBC,IAAmB,CAAA,GACnBC,IAAqB,CAAA,GACrBxC,IAAuB,CAAA;AAE7B,WAASmB,IAAI,GAAGA,IAAIiB,GAAYjB,KAAK;AACnC,UAAMC,IAAQ,KAAK,MAAMD,IAAIlB,CAAU,GACjCoB,IAAM,KAAK,IAAI1B,GAAQ,KAAK,OAAOwB,IAAI,KAAKlB,CAAU,CAAC;AAC7D,QAAImB,KAASC,EAAK;AAElB,QAAIoB,IAAK,QACLC,IAAK,OACLC,IAAUvB;AAEd,aAASvB,IAAIuB,GAAOvB,IAAIwB,GAAKxB;AAC3B,MAAIoC,EAAKpC,CAAC,IAAI4C,MAAIA,IAAKR,EAAKpC,CAAC,IACzBqC,EAAIrC,CAAC,IAAI6C,MAAIA,IAAKR,EAAIrC,CAAC,IAC3B8C,IAAU9C;AAGZ,IAAAwC,EAAQ,KAAKL,EAAKZ,CAAK,CAAC,GACxBkB,EAAQ,KAAKG,CAAE,GACfF,EAAO,KAAKG,CAAE,GACdF,EAAS,KAAKL,EAAMQ,CAAO,CAAC,GAC5B7C,EAAK,KAAKN,EAAEmD,CAAO,CAAC,GACpB3C,EAAW,KAAK2C,CAAO;AAAA,EACzB;AAEA,SAAO;AAAA,IACL,GAAG,IAAI,aAAa7C,CAAI;AAAA,IACxB,MAAM,IAAI,aAAauC,CAAO;AAAA,IAC9B,MAAM,IAAI,aAAaC,CAAO;AAAA,IAC9B,KAAK,IAAI,aAAaC,CAAM;AAAA,IAC5B,OAAO,IAAI,aAAaC,CAAQ;AAAA,IAChC,SAAS,IAAI,YAAYxC,CAAU;AAAA,EAAA;AAEvC;AAGO,SAAS4C,GACdpD,GACAqD,GACQ;AACR,MAAIH,IAAK,GACLD,IAAKjD,EAAE;AACX,SAAOkD,IAAKD,KAAI;AACd,UAAMK,IAAOJ,IAAKD,MAAQ;AAC1B,IAAIjD,EAAEsD,CAAG,IAAID,QAAYC,IAAM,IAC1BL,IAAKK;AAAA,EACZ;AACA,SAAOJ;AACT;AAGO,SAASK,GACdvD,GACAqD,GACQ;AACR,MAAIH,IAAK,GACLD,IAAKjD,EAAE;AACX,SAAOkD,IAAKD,KAAI;AACd,UAAMK,IAAOJ,IAAKD,MAAQ;AAC1B,IAAIjD,EAAEsD,CAAG,KAAKD,QAAYC,IAAM,IAC3BL,IAAKK;AAAA,EACZ;AACA,SAAOJ;AACT;AAgBO,SAASM,GACdC,GAQAC,GACAC,GACAC,IAAc,KACC;AACf,QAAMzD,IAASsD,EAAO,EAAE;AACxB,MAAItD,MAAW;AACb,WAAO,EAAE,GAAG,IAAI,aAAa,CAAC,GAAG,OAAO,GAAG,KAAK,EAAA;AAGlD,QAAM0D,IAAQ,KAAK,IAAIF,IAAOD,GAAM,KAAK,GACnCI,IAAYJ,IAAOG,IAAQD,GAC3BG,IAAYJ,IAAOE,IAAQD;AAEjC,MAAIhC,IAAQwB,GAAYK,EAAO,GAAGK,CAAS,GACvCjC,IAAM0B,GAAYE,EAAO,GAAGM,CAAS;AACzC,EAAAnC,IAAQ,KAAK,IAAI,GAAGA,CAAK,GACzBC,IAAM,KAAK,IAAI1B,GAAQ,KAAK,IAAI0B,GAAKD,IAAQ,CAAC,CAAC;AAE/C,QAAMoC,IAAQ,CAAwCC,MAAiD;AACrG,QAAKA;AACL,aAAO,IAAI,aAAaA,EAAI,SAASrC,GAAOC,CAAG,CAAC;AAAA,EAClD;AAEA,SAAO;AAAA,IACL,GAAG,IAAI,aAAa4B,EAAO,EAAE,SAAS7B,GAAOC,CAAG,CAAC;AAAA,IACjD,GAAGmC,EAAMP,EAAO,CAAC;AAAA,IACjB,MAAMO,EAAMP,EAAO,IAAI;AAAA,IACvB,MAAMO,EAAMP,EAAO,IAAI;AAAA,IACvB,KAAKO,EAAMP,EAAO,GAAG;AAAA,IACrB,OAAOO,EAAMP,EAAO,KAAK;AAAA,IACzB,OAAA7B;AAAA,IACA,KAAAC;AAAA,EAAA;AAEJ;AChTA,IAAIqC,IAAuF;AAE3F,SAASC,IAAU;AACjB,SAAID,MAEJA,IAAO,IAAIE;AAAA,IACT,MAAM,IAAI,OAAO,IAAA;AAAA;AAAA,MAAA;AAAA,MAAA,YAAA;AAAA,IAAA,GAAoD,EAAE,MAAM,SAAA,CAAU;AAAA,IACvF;AAAA,MACE,UAAU;AAAA,MACV,cAAc;AAAA,MACd,aAAa,CAACC,MAAS;AACrB,YAAIA,EAAK,SAAS,cAAc;AAC9B,gBAAMC,IACJD,EAAK,cAAc,WACf5C,EAAiB4C,EAAK,GAAGA,EAAK,GAAG,KAAK,KAAKA,EAAK,eAAe,CAAC,CAAC,IACjEtE,EAAesE,EAAK,GAAGA,EAAK,GAAGA,EAAK,YAAY;AACtD,iBAAO,EAAE,IAAIA,EAAK,IAAI,MAAM,qBAAqB,GAAGC,EAAO,GAAG,GAAGA,EAAO,EAAA;AAAA,QAC1E;AAEA,cAAMA,IAAS/B;AAAA,UACb8B,EAAK;AAAA,UACLA,EAAK;AAAA,UACLA,EAAK;AAAA,UACLA,EAAK;AAAA,UACLA,EAAK;AAAA,UACLA,EAAK;AAAA,QAAA;AAEP,eAAO;AAAA,UACL,IAAIA,EAAK;AAAA,UACT,MAAM;AAAA,UACN,GAAGC,EAAO;AAAA,UACV,MAAMA,EAAO;AAAA,UACb,MAAMA,EAAO;AAAA,UACb,KAAKA,EAAO;AAAA,UACZ,OAAOA,EAAO;AAAA,QAAA;AAAA,MAElB;AAAA,IAAA;AAAA,EACF,GAGKJ;AACT;AAEA,eAAsBK,GACpBvE,GACAC,GACAC,GACAsE,IAA+B,QACJ;AAC3B,QAAMC,IAAKC,EAAW,YAAY,GAC5BJ,IAAS,MAAMH,EAAA,EAAU,IAAI;AAAA,IACjC,IAAAM;AAAA,IACA,MAAM;AAAA,IACN,GAAAzE;AAAA,IACA,GAAAC;AAAA,IACA,cAAAC;AAAA,IACA,WAAAsE;AAAA,EAAA,CACD;AAKD,MAAIF,EAAO,SAAS;AAClB,UAAM,IAAI,MAAM,uCAAuC;AAGzD,SAAO;AAAA,IACL,GAAGA,EAAO;AAAA,IACV,GAAGA,EAAO;AAAA,IACV,SAAS,IAAI,YAAYA,EAAO,EAAE,MAAM;AAAA,EAAA;AAE5C;AAEA,eAAsBK,GACpB3E,GACAwC,GACAC,GACAC,GACAC,GACAC,GAC+B;AAC/B,QAAM6B,IAAKC,EAAW,iBAAiB,GACjCJ,IAAS,MAAMH,EAAA,EAAU,IAAI;AAAA,IACjC,IAAAM;AAAA,IACA,MAAM;AAAA,IACN,GAAAzE;AAAA,IACA,MAAAwC;AAAA,IACA,MAAAC;AAAA,IACA,KAAAC;AAAA,IACA,OAAAC;AAAA,IACA,YAAAC;AAAA,EAAA,CACD;AAED,MAAI0B,EAAO,SAAS;AAClB,UAAM,IAAI,MAAM,4CAA4C;AAG9D,SAAO;AAAA,IACL,GAAGA,EAAO;AAAA,IACV,MAAMA,EAAO;AAAA,IACb,MAAMA,EAAO;AAAA,IACb,KAAKA,EAAO;AAAA,IACZ,OAAOA,EAAO;AAAA,IACd,SAAS,IAAI,YAAYA,EAAO,EAAE,MAAM;AAAA,EAAA;AAE5C;AAEO,SAASM,KAA8B;AAC5C,EAAAV,KAAA,QAAAA,EAAM,WACNA,IAAO;AACT;AAEO,SAASW,KAAgC;AAC9C,UAAOX,KAAA,gBAAAA,EAAM,WAAU;AACzB;AC9IA,MAAMY,KAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,eAAe,qBAAqB;AAAA,EAC/C,MAAM,CAAC,eAAe,OAAO,gBAAgB;AAC/C,GAEMC,KAAuD;AAAA,EAC3D,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,EACN,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE;AAAA,EACvB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe,CAAA;AAAA,EACf,eAAe,CAAA;AAAA,EACf,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,iBAAiB;AACnB;AAWO,SAASC,GACdC,IAAkD,IACT;AACzC,QAAMC,IAAS,EAAE,GAAGH,IAAgB,GAAGE,EAAA;AACvC,MAAIE,IAA4B,MAC5BC,IAAmB;AAEvB,QAAMC,wBAAmB,IAAA,GACnBC,wBAAY,IAAA;AAElB,MAAIC,IAA8E,MAC9EC,IAA4G,MAC5GC,IAAa;AACjB,QAAMC,wBAAsB,IAAA;AAC5B,MAAIC,IAAc;AAElB,WAASC,EAAIC,MAAoBC,GAAiB;AAChD,IAAIZ,EAAO,SAASC,KAClBA,EAAI,IAAI,KAAK,oBAAoBU,CAAO,IAAI,GAAGC,CAAI;AAAA,EAEvD;AAEA,WAASC,EAAiBC,GAAyB;AAIjD,QAHI,CAACd,EAAO,WACRA,EAAO,cAAc,UACrBA,EAAO,cAAc,SAAS,KAAK,CAACA,EAAO,cAAc,SAASc,EAAO,MAAA,CAAO,KAChFd,EAAO,cAAc,SAASc,EAAO,MAAA,CAAO,EAAG,QAAO;AAE1D,UAAMC,IAAOD,EAAO,QAAA;AACpB,WACEC,MAAS,UACTA,MAAS,aACTA,MAAS,kBACTA,MAAS,UACTA,MAAS,kBACTA,MAAS,iBACTA,MAAS;AAAA,EAEb;AAEA,WAASC,EAAaF,GAAyB;AAC7C,WAAOA,EAAO,cAAc;AAAA,EAC9B;AAEA,WAASG,EAAmBC,GAAsC;AAChE,WAAIA,EAAM,QAAQA,EAAM,QAAQA,EAAM,OAAOA,EAAM,QAC1C;AAAA,MACL,GAAGA,EAAM;AAAA,MACT,MAAMA,EAAM;AAAA,MACZ,MAAMA,EAAM;AAAA,MACZ,KAAKA,EAAM;AAAA,MACX,OAAOA,EAAM;AAAA,IAAA,IAGV,EAAE,GAAGA,EAAM,GAAG,GAAGA,EAAM,EAAA;AAAA,EAChC;AAEA,WAASC,EAAgBlE,GAA4B;AACnD,QAAI+C,EAAO,iBAAiB,OAAQ,QAAO,KAAK,IAAI,GAAGA,EAAO,YAAY;AAC1E,UAAMoB,IAAQnB,EAAK,OAAO,WAAW,QAAQA,EAAK,OAAO;AACzD,WAAOjD,GAAsBC,GAAYmE,GAAOpB,EAAO,cAAc;AAAA,EACvE;AAEA,WAASqB,EACPvG,GACAC,GACAC,GACAsG,GACsC;AACtC,QAAItG,KAAgBF,EAAE,UAAUA,EAAE,UAAU;AAC1C,aAAO,EAAE,GAAG,IAAI,aAAaA,CAAC,GAAG,GAAG,IAAI,aAAaC,CAAC,EAAA;AAGxD,QAAIuG,MAAa,UAAU;AACzB,YAAM9E,IAAc,KAAK,KAAKxB,IAAe,CAAC,GACxCoE,IAAS7C,EAAiBzB,GAAGC,GAAGyB,CAAW;AACjD,aAAO,EAAE,GAAG4C,EAAO,GAAG,GAAGA,EAAO,EAAA;AAAA,IAClC;AAEA,UAAMA,IAASvE,EAAeC,GAAGC,GAAGC,CAAY;AAChD,WAAO,EAAE,GAAGoE,EAAO,GAAG,GAAGA,EAAO,EAAA;AAAA,EAClC;AAEA,WAASmC,EAAcC,GAAkBC,GAAyB;AAChE,IAAKzB,EAAO,qBACZG,EAAa,IAAIqB,GAAU,EAAE,GAAGC,GAAM;AAAA,EACxC;AAEA,WAASC,EAAgBF,GAAsC;AAC7D,WAAOrB,EAAa,IAAIqB,CAAQ,KAAK;AAAA,EACvC;AAEA,WAASG,EACPH,GACAI,GACAC,GACA7G,GACA8G,GACAR,GACM;AACN,IAAAlB,EAAM,IAAIoB,GAAU;AAAA,MAClB,UAAAA;AAAA,MACA,gBAAAI;AAAA,MACA,gBAAAC;AAAA,MACA,cAAA7G;AAAA,MACA,aAAa,KAAK,IAAA;AAAA,MAClB,MAAA8G;AAAA,MACA,UAAAR;AAAA,IAAA,CACD;AAAA,EACH;AAEA,WAASS,EAA0BjB,GAAoC;;AACrE,UAAMkB,IAAOlB,EAAO,QAAA;AACpB,QAAI,GAACmB,IAAAD,KAAA,gBAAAA,EAAM,MAAN,QAAAC,EAAS,QAAQ,QAAO;AAE7B,QAAIjB,EAAaF,CAAM,GAAG;AACxB,UAAI,CAACkB,EAAK,QAAQ,CAACA,EAAK,QAAQ,CAACA,EAAK,OAAO,CAACA,EAAK,MAAO,QAAO;AACjE,YAAMd,IAAqB;AAAA,QACzB,GAAGc,EAAK;AAAA,QACR,MAAMA,EAAK;AAAA,QACX,MAAMA,EAAK;AAAA,QACX,KAAKA,EAAK;AAAA,QACV,OAAOA,EAAK;AAAA,MAAA;AAEd,aAAAT,EAAcT,EAAO,MAAA,GAASI,CAAK,GAC5BA;AAAAA,IACT;AAEA,QAAI,CAACc,EAAK,EAAG,QAAO;AACpB,UAAMd,IAAqB,EAAE,GAAGc,EAAK,GAAG,GAAGA,EAAK,EAAA;AAChD,WAAAT,EAAcT,EAAO,MAAA,GAASI,CAAK,GAC5BA;AAAA,EACT;AAEA,WAASgB,EAAcpB,GAAoC;AACzD,WAAOY,EAAgBZ,EAAO,MAAA,CAAO,KAAKiB,EAA0BjB,CAAM;AAAA,EAC5E;AAEA,WAASqB,EAAkB5D,GAAkC;;AAC3D,UAAM6D,KAASC,KAAAJ,IAAAhC,EAAK,MAAK,kBAAV,gBAAAoC,EAAA,KAAAJ;AACf,QAAI,CAACG,EAAQ,QAAO7D;AAEpB,UAAM+D,IAAShE;AAAA,MACbC;AAAA,MACA6D,EAAO;AAAA,MACPA,EAAO;AAAA,MACPpC,EAAO;AAAA,IAAA;AAET,WAAIsC,EAAO,MAAMA,EAAO,SAAS/D,EAAO,EAAE,SAAeA,IAElD;AAAA,MACL,GAAG+D,EAAO;AAAA,MACV,GAAGA,EAAO;AAAA,MACV,MAAMA,EAAO;AAAA,MACb,MAAMA,EAAO;AAAA,MACb,KAAKA,EAAO;AAAA,MACZ,OAAOA,EAAO;AAAA,IAAA;AAAA,EAElB;AAEA,WAASC,EAAkBf,GAAkBgB,GAAiC;AAC5E,IAAAtC,IAAmB,IACnBG,EAAsBmB,GAAUgB,CAAO,GACvCtC,IAAmB;AAAA,EACrB;AAEA,iBAAeuC,EACblE,GACAvD,GACAsG,GAC+C;AAC/C,UAAMxG,IAAI,IAAI,aAAayD,EAAO,CAAC,GAC7BxD,IAAI,IAAI,aAAawD,EAAO,CAAE;AAEpC,QAAIyB,EAAO,aAAalF,EAAE,UAAUkF,EAAO,iBAAiB;AAE1D,YAAMZ,IAAS,MAAMC,GAAgBvE,GAAGC,GAAGC,GADzBsG,MAAa,WAAW,WAAW,MACa;AAClE,aAAO,EAAE,GAAGlC,EAAO,GAAG,GAAGA,EAAO,EAAA;AAAA,IAClC;AAEA,WAAOiC,EAAevG,GAAGC,GAAGC,GAAcsG,CAAQ;AAAA,EACpD;AAEA,iBAAeoB,EAAoB5B,GAA+B;;AAChE,QAAI,CAACb,KAAO,CAACI,EAAsB;AACnC,UAAMmB,IAAWV,EAAO,MAAA;AAExB,QAAI,CAACD,EAAiBC,CAAM,GAAG;AAC7B,YAAM6B,IAAWjB,EAAgBF,CAAQ;AACzC,MAAImB,KAAY3C,EAAO,qBACrBuC,EAAkBf,GAAUP,EAAmB0B,CAAQ,CAAC;AAE1D;AAAA,IACF;AAEA,UAAMpE,IAAS2D,EAAcpB,CAAM;AACnC,QAAI,GAACmB,IAAA1D,KAAA,gBAAAA,EAAQ,MAAR,QAAA0D,EAAW,QAAQ;AAExB,UAAMW,IAAiBT,EAAkB5D,CAAM,GACzCsE,KAAOrC,EAAgB,IAAIgB,CAAQ,KAAK,KAAK;AAGnD,QAFAhB,EAAgB,IAAIgB,GAAUqB,CAAG,GAE7B7B,EAAaF,CAAM,GAAG;AACxB,UAAI,CAAC8B,EAAe,QAAQ,CAACA,EAAe,QAAQ,CAACA,EAAe,OAAO,CAACA,EAAe;AACzF;AAGF,YAAMlF,IAAayD,EAAgByB,EAAe,EAAE,MAAM,GACpD9H,IAAI,IAAI,aAAa8H,EAAe,CAAC,GACrCtF,IAAO,IAAI,aAAasF,EAAe,IAAI,GAC3CrF,IAAO,IAAI,aAAaqF,EAAe,IAAI,GAC3CpF,IAAM,IAAI,aAAaoF,EAAe,GAAG,GACzCnF,IAAQ,IAAI,aAAamF,EAAe,KAAK,GAE7CE,IACJ9C,EAAO,aAAalF,EAAE,UAAUkF,EAAO,kBACnC,MAAMP,GAAoB3E,GAAGwC,GAAMC,GAAMC,GAAKC,GAAOC,CAAU,IAC/DL,EAAqBvC,GAAGwC,GAAMC,GAAMC,GAAKC,GAAOC,CAAU;AAEhE,UAAI8C,EAAgB,IAAIgB,CAAQ,MAAMqB,EAAK;AAE3C,MAAAN,EAAkBf,GAAU;AAAA,QAC1B,GAAGsB,EAAY;AAAA,QACf,MAAMA,EAAY;AAAA,QAClB,MAAMA,EAAY;AAAA,QAClB,KAAKA,EAAY;AAAA,QACjB,OAAOA,EAAY;AAAA,MAAA,CACpB,GAEDnB,EAAYH,GAAUjD,EAAO,EAAE,QAAQuE,EAAY,EAAE,QAAQpF,GAAYsC,EAAO,MAAM,QAAQ;AAC9F;AAAA,IACF;AAEA,QAAI,CAAC4C,EAAe,EAAG;AAEvB,UAAM5H,IAAemG,EAAgByB,EAAe,EAAE,MAAM,GACtDtB,IAAWR,EAAO,QAAA,MAAc,QAAQ,WAAWd,EAAO,UAC1D8C,IAAc,MAAML,EAAcG,GAAgB5H,GAAcsG,CAAQ;AAE9E,IAAId,EAAgB,IAAIgB,CAAQ,MAAMqB,MAEtCN,EAAkBf,GAAU,EAAE,GAAGsB,EAAY,GAAG,GAAGA,EAAY,GAAG,GAClEnB,EAAYH,GAAUjD,EAAO,EAAE,QAAQuE,EAAY,EAAE,QAAQ9H,GAAcgF,EAAO,MAAMsB,CAAQ;AAAA,EAClG;AAEA,WAASyB,IAAmB;AAC1B,IAAK9C,KACLA,EAAI,KAAK,aAAA,EAAe,QAAQ,CAACa,MAAW;AAC1C,MAAK4B,EAAoB5B,CAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAEA,WAASkC,IAA2B;;AAClC,QAAI,CAAC/C,EAAK;AACV,UAAMmC,KAASC,KAAAJ,IAAAhC,EAAI,MAAK,kBAAT,gBAAAoC,EAAA,KAAAJ;AACf,QAAIG,GAAQ;AACV,YAAMa,IAAM,GAAGb,EAAO,IAAI,IAAIA,EAAO,IAAI,IAAIA,EAAO,IAAI,IAAIA,EAAO,IAAI,IAAInC,EAAI,OAAO,WAAW,KAAK;AACtG,UAAIgD,MAAQxC,EAAa;AACzB,MAAAA,IAAcwC;AAAA,IAChB;AAEA,IAAI1C,MACJA,IAAa,sBAAsB,MAAM;AACvC,MAAAA,IAAa,GACbwC,EAAA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAASG,EAAmB3D,GAAYkC,GAA8B;;AACpE,QAAI,CAACxB,KAAO,CAACI,EAAsB;AACnC,QAAI,CAACL,EAAO,WAAWE,GAAkB;AACvC,MAAAG,EAAqBd,GAAIkC,CAAI;AAC7B;AAAA,IACF;AAGA,QAAI,GADWY,KAAAJ,IAAAhC,EAAI,OAAM,cAAV,gBAAAoC,EAAA,KAAAJ,GAAsB1C,KACxB;AACX,MAAAc,EAAqBd,GAAIkC,CAAI;AAC7B;AAAA,IACF;AAEA,UAAMkB,IAAWjB,EAAgBnC,CAAE;AACnC,IAAIoD,KAAY3C,EAAO,sBACrBE,IAAmB,IACnBG,EAAqBd,GAAI0B,EAAmB0B,CAAQ,CAAC,GACrDzC,IAAmB,KAGrBG,EAAqBd,GAAIkC,CAAI;AAE7B,UAAM0B,KAAgBC,KAAAC,IAAApD,EAAI,OAAM,cAAV,gBAAAmD,EAAA,KAAAC,GAAsB9D;AAC5C,IAAI4D,MACFhD,EAAa,OAAOZ,CAAE,GACtBwC,EAA0BoB,CAAa,GAClCT,EAAoBS,CAAa;AAAA,EAE1C;AAEA,WAASG,EACP/D,GACAzE,GACAC,GACM;;AACN,QAAI,CAACkF,KAAO,CAACK,KAAsB,CAACD,EAAsB;AAE1D,QAAI,CAACL,EAAO,WAAWE,GAAkB;AACvC,MAAAI,EAAmBf,GAAIzE,GAAGC,CAAC;AAC3B;AAAA,IACF;AAGA,QAAI,GADWsH,KAAAJ,IAAAhC,EAAI,OAAM,cAAV,gBAAAoC,EAAA,KAAAJ,GAAsB1C,KACxB;AACX,MAAAe,EAAmBf,GAAIzE,GAAGC,CAAC;AAC3B;AAAA,IACF;AAEA,UAAM4H,IAAWjB,EAAgBnC,CAAE;AACnC,IAAIoD,KAAY3C,EAAO,sBACrBE,IAAmB,IACnBG,EAAqBd,GAAI0B,EAAmB0B,CAAQ,CAAC,GACrDzC,IAAmB,KAGrBI,EAAmBf,GAAIzE,GAAGC,CAAC;AAE3B,UAAMoI,KAAgBC,KAAAC,IAAApD,EAAI,OAAM,cAAV,gBAAAmD,EAAA,KAAAC,GAAsB9D;AAC5C,QAAI4D,GAAe;AACjB,YAAMI,IAAS7B,EAAgBnC,CAAE;AACjC,MAAIgE,KAAA,QAAAA,EAAQ,KAAKvD,EAAO,oBAGtBG,EAAa,IAAIZ,GAAI;AAAA,QACnB,GAAGiE,EAAYD,EAAO,GAAGzI,CAAC;AAAA,QAC1B,GAAG0I,EAAYD,EAAO,GAAGxI,CAAC;AAAA,MAAA,CAC3B,KAEDoF,EAAa,OAAOZ,CAAE,GACtBwC,EAA0BoB,CAAa,IAEpCT,EAAoBS,CAAa;AAAA,IACxC;AAAA,EACF;AAEA,WAASK,EACPC,GACAC,GACc;AACd,UAAMC,IAAOD,aAAoB,eAAeA,IAAW,aAAa,KAAKA,CAAQ,GAC/EE,IAAS,IAAI,aAAaH,EAAS,SAASE,EAAK,MAAM;AAC7D,WAAAC,EAAO,IAAIH,CAAQ,GACnBG,EAAO,IAAID,GAAMF,EAAS,MAAM,GACzBG;AAAA,EACT;AA4CA,SAAO;AAAA,IACL,UAAAhE;AAAA,IACA,OAAOiE,GAA0B;;AAC/B,MAAA5D,IAAM4D;AAGN,YAAMC,IAAQ7D,EAAI;AAClB,MAAAI,MAAuB4B,IAAA6B,EAAM,iBAAN,gBAAA7B,EAAoB,KAAK6B,OAAU,MAC1DxD,MAAqB+B,IAAAyB,EAAM,eAAN,gBAAAzB,EAAkB,KAAKyB,OAAU,MAElDzD,MACFyD,EAAM,eAAe,CAACvE,GAAYkC,MAA2ByB,EAAmB3D,GAAIkC,CAAI,IAGtFnB,MACFwD,EAAM,aAAa,CAACvE,GAAYzE,GAA4BC,MAC1DuI,EAAiB/D,GAAIzE,GAAGC,CAAC,IAG7BkF,EAAI,OAAO,GAAG,QAAQ,MAAM+C,GAAoB,GAChD/C,EAAI,OAAO,GAAG,OAAO,MAAM+C,GAAoB,GAC/C/C,EAAI,OAAO,GAAG,UAAU,MAAM;AAC5B,QAAAQ,IAAc,IACduC,EAAA;AAAA,MACF,CAAC,GAEDD,EAAA,GACArC,EAAI,aAAa;AAAA,IACnB;AAAA,IACA,UAAUmD,GAA0B;AAClC,MAAItD,0BAAiCA,CAAU,GAC/CA,IAAa,GACbC,EAAgB,MAAA,GACZH,MACDwD,EAAU,MAAc,eAAexD,IAEtCC,MACDuD,EAAU,MAAc,aAAavD,IAExCL,IAAM,MACNE,EAAa,MAAA,GACbC,EAAM,MAAA;AAAA,IACR;AAAA,IACA,KArFuD;AAAA,MACvD,SAAS;AACP,QAAAJ,EAAO,UAAU,IACjB+C,EAAA;AAAA,MACF;AAAA,MACA,UAAU;AAER,YADA/C,EAAO,UAAU,IACb,CAACC,KAAO,CAACI,EAAsB;AACnC,cAAM0D,IAAU1D;AAChB,QAAAJ,EAAI,KAAK,aAAA,EAAe,QAAQ,CAACa,MAAW;AAC1C,gBAAM6B,IAAWjB,EAAgBZ,EAAO,MAAA,CAAO;AAC/C,UAAI6B,MACFzC,IAAmB,IACnB6D,EAAQjD,EAAO,MAAA,GAASG,EAAmB0B,CAAQ,CAAC,GACpDzC,IAAmB;AAAA,QAEvB,CAAC;AAAA,MACH;AAAA,MACA,YAAY;AACV,eAAOF,EAAO;AAAA,MAChB;AAAA,MACA,aAAagE,GAAW;AACtB,eAAO,OAAOhE,GAAQgE,CAAS,GAC/BjB,EAAA;AAAA,MACF;AAAA,MACA,WAAWvB,GAAU;;AACnB,YAAKvB,GACL;AAAA,cAAIuB,GAAU;AACZ,kBAAMV,KAASuB,KAAAJ,IAAAhC,EAAI,OAAM,cAAV,gBAAAoC,EAAA,KAAAJ,GAAsBT;AACrC,YAAIV,OAA4BA,CAAM;AACtC;AAAA,UACF;AACA,UAAAiC,EAAA;AAAA;AAAA,MACF;AAAA,MACA,SAASvB,GAAU;AACjB,eAAOpB,EAAM,IAAIoB,CAAQ,KAAK;AAAA,MAChC;AAAA,MACA,cAAc;AACZ,eAAO,MAAM,KAAKpB,EAAM,OAAA,CAAQ;AAAA,MAClC;AAAA,IAAA;AAAA,EA8CA;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-BMiZoKmm.js","sources":["../src/streaming/utils.ts","../src/streaming/websocket.ts","../src/streaming/backpressure.ts","../src/streaming/mock.ts","../src/plugins/streaming/index.ts"],"sourcesContent":["/**\n * WebSocket Streaming Utilities\n */\nimport { DataPoint, WebSocketStream } from \"./types\";\n\n/**\n * Default message parser - expects { x, y, seriesId? } or array of same\n */\nexport function defaultParser(data: unknown): DataPoint | DataPoint[] | null {\n if (!data || typeof data !== 'object') return null;\n \n // Array of points\n if (Array.isArray(data)) {\n return data\n .filter((item): item is DataPoint => \n typeof item === 'object' && \n item !== null && \n typeof item.x === 'number' && \n typeof item.y === 'number'\n );\n }\n \n // Single point\n const point = data as Record<string, unknown>;\n if (typeof point.x === 'number' && typeof point.y === 'number') {\n return {\n x: point.x,\n y: point.y,\n seriesId: typeof point.seriesId === 'string' ? point.seriesId : undefined,\n };\n }\n \n return null;\n}\n\n/**\n * Helper to create a parser for custom message formats\n */\nexport function createMessageParser<T>(\n transform: (message: T) => DataPoint | DataPoint[] | null\n): (data: unknown) => DataPoint | DataPoint[] | null {\n return (data: unknown) => {\n try {\n return transform(data as T);\n } catch {\n return null;\n }\n };\n}\n\n/**\n * Helper to connect a WebSocket stream to a chart\n */\nexport function connectStreamToChart(\n stream: WebSocketStream,\n chart: { appendData: (seriesId: string, data: { x: Float32Array; y: Float32Array }) => void },\n seriesIds: string[] = ['default']\n): () => void {\n const unsubscribers: (() => void)[] = [];\n\n for (const seriesId of seriesIds) {\n const unsubscribe = stream.subscribe(seriesId, (points) => {\n if (points.length === 0) return;\n \n const x = new Float32Array(points.map(p => p.x));\n const y = new Float32Array(points.map(p => p.y));\n \n chart.appendData(seriesId, { x, y });\n });\n \n unsubscribers.push(unsubscribe);\n }\n\n // Return cleanup function\n return () => {\n for (const unsubscribe of unsubscribers) {\n unsubscribe();\n }\n };\n}\n","/**\n * WebSocket Stream Implementation\n */\nimport { \n WebSocketStreamConfig, \n DataPoint, \n WebSocketStream, \n StreamStats, \n WebSocketState \n} from \"./types\";\nimport { defaultParser } from \"./utils\";\n\n/**\n * Create a WebSocket stream for real-time chart data\n */\nexport function createWebSocketStream(config: WebSocketStreamConfig): WebSocketStream {\n const {\n url,\n maxReconnectAttempts = 5,\n reconnectDelay = 1000,\n bufferSize = 10,\n throttleMs = 16,\n parseMessage = defaultParser,\n onConnect,\n onDisconnect,\n onError,\n onReconnect,\n } = config;\n\n let ws: WebSocket | null = null;\n let state: WebSocketState = 'disconnected';\n let reconnectAttempts = 0;\n let reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n let connectionStartTime: number | null = null;\n\n const buffers = new Map<string, DataPoint[]>();\n const subscribers = new Map<string, Set<(points: DataPoint[]) => void>>();\n \n const stats: StreamStats = {\n messagesReceived: 0,\n pointsProcessed: 0,\n reconnectCount: 0,\n lastMessageTime: null,\n connectionUptime: 0,\n bufferSize: 0,\n };\n\n let lastFlushTime = 0;\n let flushScheduled = false;\n\n function connect(): void {\n if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) {\n return;\n }\n state = 'connecting';\n try {\n ws = new WebSocket(url);\n ws.onopen = () => {\n state = 'connected';\n reconnectAttempts = 0;\n connectionStartTime = Date.now();\n onConnect?.();\n };\n ws.onmessage = (event) => handleMessage(event.data);\n ws.onclose = (event) => {\n state = 'disconnected';\n connectionStartTime = null;\n onDisconnect?.(event);\n if (!event.wasClean && reconnectAttempts < maxReconnectAttempts) scheduleReconnect();\n };\n ws.onerror = (error) => {\n state = 'error';\n onError?.(error);\n };\n } catch (error) {\n state = 'error';\n onError?.(error as Event);\n }\n }\n\n function disconnect(): void {\n if (reconnectTimeout) { clearTimeout(reconnectTimeout); reconnectTimeout = null; }\n if (ws) { ws.close(1000, 'Client disconnect'); ws = null; }\n state = 'disconnected';\n reconnectAttempts = 0;\n buffers.clear();\n }\n\n function scheduleReconnect(): void {\n if (reconnectTimeout) return;\n state = 'reconnecting';\n reconnectAttempts++;\n stats.reconnectCount++;\n onReconnect?.(reconnectAttempts);\n reconnectTimeout = setTimeout(() => {\n reconnectTimeout = null;\n connect();\n }, reconnectDelay * reconnectAttempts);\n }\n\n function handleMessage(data: unknown): void {\n stats.messagesReceived++;\n stats.lastMessageTime = Date.now();\n try {\n const parsed = typeof data === 'string' ? JSON.parse(data) : data;\n const points = parseMessage(parsed);\n if (!points) return;\n const pointArray = Array.isArray(points) ? points : [points];\n for (const point of pointArray) {\n const seriesId = point.seriesId || 'default';\n if (!buffers.has(seriesId)) buffers.set(seriesId, []);\n buffers.get(seriesId)!.push(point);\n stats.pointsProcessed++;\n }\n stats.bufferSize = Array.from(buffers.values()).reduce((sum, b) => sum + b.length, 0);\n scheduleFlush();\n } catch {}\n }\n\n function scheduleFlush(): void {\n if (flushScheduled) return;\n const now = performance.now();\n const timeSinceLastFlush = now - lastFlushTime;\n if (timeSinceLastFlush >= throttleMs) {\n flush();\n } else {\n flushScheduled = true;\n setTimeout(() => { flushScheduled = false; flush(); }, throttleMs - timeSinceLastFlush);\n }\n }\n\n function flush(): void {\n lastFlushTime = performance.now();\n for (const [seriesId, buffer] of buffers.entries()) {\n if (buffer.length === 0) continue;\n if (buffer.length >= bufferSize || performance.now() - lastFlushTime > throttleMs * 2) {\n const callbacks = subscribers.get(seriesId);\n if (callbacks) {\n const points = buffer.splice(0, buffer.length);\n for (const callback of callbacks) callback(points);\n } else {\n buffer.length = 0;\n }\n }\n }\n stats.bufferSize = Array.from(buffers.values()).reduce((sum, b) => sum + b.length, 0);\n }\n\n return {\n connect,\n disconnect,\n isConnected: () => ws !== null && ws.readyState === WebSocket.OPEN,\n getState: () => state,\n subscribe: (seriesId, callback) => {\n if (!subscribers.has(seriesId)) subscribers.set(seriesId, new Set());\n subscribers.get(seriesId)!.add(callback);\n return () => {\n const callbacks = subscribers.get(seriesId);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) subscribers.delete(seriesId);\n }\n };\n },\n unsubscribeAll: () => { subscribers.clear(); buffers.clear(); },\n send: (message) => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(typeof message === 'string' ? message : JSON.stringify(message));\n }\n },\n getStats: () => ({ ...stats, connectionUptime: connectionStartTime ? Date.now() - connectionStartTime : 0 }),\n };\n}\n","/**\n * Sci Plot - Backpressure Management Module\n * \n * Provides advanced backpressure handling for streaming data:\n * - Configurable buffer limits\n * - Multiple overflow strategies (drop-oldest, pause, sample)\n * - Health monitoring and metrics\n * - Automatic flow control\n * \n * @module backpressure\n */\n\nimport type { DataPoint } from \"./types\";\n\n// ============================================\n// Types\n// ============================================\n\nexport type OverflowStrategy = 'drop-oldest' | 'drop-newest' | 'pause' | 'sample' | 'block';\n\nexport interface BackpressureConfig {\n /** Maximum buffer size before triggering backpressure (default: 10000) */\n maxBuffer: number;\n /** Warning threshold as fraction of maxBuffer (default: 0.7) */\n warningThreshold?: number;\n /** Critical threshold as fraction of maxBuffer (default: 0.9) */\n criticalThreshold?: number;\n /** Overflow handling strategy (default: 'drop-oldest') */\n strategy: OverflowStrategy;\n /** For 'sample' strategy: keep every Nth point (default: 2) */\n sampleRate?: number;\n /** Callback when pressure level changes */\n onPressure?: (stats: PressureStats) => void;\n /** Callback when buffer overflows */\n onOverflow?: (droppedCount: number) => void;\n /** Callback when back to normal */\n onRecovery?: () => void;\n}\n\nexport interface PressureStats {\n /** Current buffer fill level (0-1) */\n fillLevel: number;\n /** Pressure state */\n state: 'normal' | 'warning' | 'critical' | 'overflow';\n /** Current buffer size */\n bufferSize: number;\n /** Maximum buffer size */\n maxBuffer: number;\n /** Points dropped due to overflow */\n droppedCount: number;\n /** Points sampled/skipped */\n sampledCount: number;\n /** Incoming rate (points per second) */\n incomingRate: number;\n /** Outgoing rate (points per second) */\n outgoingRate: number;\n /** Whether stream is paused due to backpressure */\n isPaused: boolean;\n}\n\nexport interface BufferHealth {\n /** Overall health score (0-100) */\n score: number;\n /** Health status */\n status: 'healthy' | 'degraded' | 'critical';\n /** Recommendations */\n recommendations: string[];\n}\n\n// ============================================\n// Circular Buffer Implementation\n// ============================================\n\nexport class CircularBuffer<T> {\n private buffer: T[];\n private head: number = 0;\n private tail: number = 0;\n private count: number = 0;\n private readonly capacity: number;\n\n constructor(capacity: number) {\n this.capacity = capacity;\n this.buffer = new Array(capacity);\n }\n\n /**\n * Add item to buffer\n * @returns true if item was added, false if buffer was full\n */\n push(item: T): boolean {\n if (this.count === this.capacity) {\n return false;\n }\n this.buffer[this.tail] = item;\n this.tail = (this.tail + 1) % this.capacity;\n this.count++;\n return true;\n }\n\n /**\n * Add item, overwriting oldest if full\n * @returns the overwritten item, or undefined\n */\n pushOverwrite(item: T): T | undefined {\n let overwritten: T | undefined;\n if (this.count === this.capacity) {\n overwritten = this.buffer[this.head];\n this.head = (this.head + 1) % this.capacity;\n this.count--;\n }\n this.buffer[this.tail] = item;\n this.tail = (this.tail + 1) % this.capacity;\n this.count++;\n return overwritten;\n }\n\n /**\n * Remove and return oldest item\n */\n shift(): T | undefined {\n if (this.count === 0) {\n return undefined;\n }\n const item = this.buffer[this.head];\n this.head = (this.head + 1) % this.capacity;\n this.count--;\n return item;\n }\n\n /**\n * Remove and return multiple items\n */\n shiftMany(n: number): T[] {\n const result: T[] = [];\n const toRemove = Math.min(n, this.count);\n for (let i = 0; i < toRemove; i++) {\n result.push(this.buffer[this.head]);\n this.head = (this.head + 1) % this.capacity;\n }\n this.count -= toRemove;\n return result;\n }\n\n /**\n * Peek at oldest item without removing\n */\n peek(): T | undefined {\n return this.count > 0 ? this.buffer[this.head] : undefined;\n }\n\n /**\n * Get all items as array\n */\n toArray(): T[] {\n const result: T[] = [];\n let current = this.head;\n for (let i = 0; i < this.count; i++) {\n result.push(this.buffer[current]);\n current = (current + 1) % this.capacity;\n }\n return result;\n }\n\n /**\n * Clear the buffer\n */\n clear(): void {\n this.head = 0;\n this.tail = 0;\n this.count = 0;\n }\n\n /**\n * Get current size\n */\n size(): number {\n return this.count;\n }\n\n /**\n * Check if buffer is full\n */\n isFull(): boolean {\n return this.count === this.capacity;\n }\n\n /**\n * Check if buffer is empty\n */\n isEmpty(): boolean {\n return this.count === 0;\n }\n\n /**\n * Get fill level (0-1)\n */\n fillLevel(): number {\n return this.count / this.capacity;\n }\n\n /**\n * Get capacity\n */\n getCapacity(): number {\n return this.capacity;\n }\n}\n\n// ============================================\n// Backpressure Manager\n// ============================================\n\nexport class BackpressureManager {\n private config: Required<BackpressureConfig>;\n private buffers: Map<string, CircularBuffer<DataPoint>> = new Map();\n private stats: Map<string, { dropped: number; sampled: number; lastIncoming: number; lastOutgoing: number }> = new Map();\n private paused: boolean = false;\n private sampleCounter: number = 0;\n\n // Rate tracking\n private incomingHistory: number[] = [];\n private outgoingHistory: number[] = [];\n private lastRateUpdate: number = 0;\n private currentIncoming: number = 0;\n private currentOutgoing: number = 0;\n\n constructor(config: BackpressureConfig) {\n this.config = {\n warningThreshold: 0.7,\n criticalThreshold: 0.9,\n sampleRate: 2,\n onPressure: undefined,\n onOverflow: undefined,\n onRecovery: undefined,\n ...config,\n } as Required<BackpressureConfig>;\n }\n\n /**\n * Add points to the buffer with backpressure handling\n */\n push(seriesId: string, points: DataPoint[]): number {\n if (!this.buffers.has(seriesId)) {\n this.buffers.set(seriesId, new CircularBuffer(this.config.maxBuffer));\n this.stats.set(seriesId, { dropped: 0, sampled: 0, lastIncoming: 0, lastOutgoing: 0 });\n }\n\n const buffer = this.buffers.get(seriesId)!;\n const stats = this.stats.get(seriesId)!;\n let added = 0;\n let dropped = 0;\n\n for (const point of points) {\n this.currentIncoming++;\n stats.lastIncoming = Date.now();\n\n // Handle based on strategy when buffer is under pressure\n if (buffer.fillLevel() >= this.config.criticalThreshold) {\n switch (this.config.strategy) {\n case 'drop-oldest':\n // Overwrite oldest points\n const overwritten = buffer.pushOverwrite(point);\n if (overwritten) {\n dropped++;\n stats.dropped++;\n }\n added++;\n break;\n\n case 'drop-newest':\n // Skip new points\n dropped++;\n stats.dropped++;\n continue;\n\n case 'pause':\n // Signal pause (external handling required)\n this.paused = true;\n return added;\n\n case 'sample':\n // Keep every Nth point\n this.sampleCounter++;\n if (this.sampleCounter >= this.config.sampleRate) {\n this.sampleCounter = 0;\n buffer.pushOverwrite(point);\n added++;\n } else {\n stats.sampled++;\n }\n break;\n\n case 'block':\n // Block until buffer has space\n if (!buffer.isFull()) {\n buffer.push(point);\n added++;\n }\n break;\n }\n } else {\n // Normal operation\n if (buffer.push(point)) {\n added++;\n } else {\n // Shouldn't happen in normal operation\n buffer.pushOverwrite(point);\n added++;\n dropped++;\n stats.dropped++;\n }\n }\n }\n\n // Track drops\n if (dropped > 0) {\n this.config.onOverflow?.(dropped);\n }\n\n // Check and report pressure state\n this.checkPressure(seriesId);\n this.updateRates();\n\n return added;\n }\n\n /**\n * Consume points from buffer\n */\n consume(seriesId: string, count?: number): DataPoint[] {\n const buffer = this.buffers.get(seriesId);\n if (!buffer) return [];\n\n const stats = this.stats.get(seriesId)!;\n const toConsume = count ?? buffer.size();\n const points = buffer.shiftMany(toConsume);\n\n this.currentOutgoing += points.length;\n stats.lastOutgoing = Date.now();\n\n // Check for recovery from paused state\n if (this.paused && buffer.fillLevel() < this.config.warningThreshold) {\n this.paused = false;\n this.config.onRecovery?.();\n }\n\n this.updateRates();\n return points;\n }\n\n /**\n * Consume all points from buffer\n */\n consumeAll(seriesId: string): DataPoint[] {\n return this.consume(seriesId);\n }\n\n /**\n * Get current pressure stats for a series\n */\n getPressureStats(seriesId: string): PressureStats {\n const buffer = this.buffers.get(seriesId);\n const stats = this.stats.get(seriesId);\n\n if (!buffer || !stats) {\n return {\n fillLevel: 0,\n state: 'normal',\n bufferSize: 0,\n maxBuffer: this.config.maxBuffer,\n droppedCount: 0,\n sampledCount: 0,\n incomingRate: 0,\n outgoingRate: 0,\n isPaused: false,\n };\n }\n\n const fillLevel = buffer.fillLevel();\n let state: PressureStats['state'] = 'normal';\n if (fillLevel >= this.config.criticalThreshold) {\n state = buffer.isFull() ? 'overflow' : 'critical';\n } else if (fillLevel >= this.config.warningThreshold) {\n state = 'warning';\n }\n\n return {\n fillLevel,\n state,\n bufferSize: buffer.size(),\n maxBuffer: this.config.maxBuffer,\n droppedCount: stats.dropped,\n sampledCount: stats.sampled,\n incomingRate: this.getAverageRate(this.incomingHistory),\n outgoingRate: this.getAverageRate(this.outgoingHistory),\n isPaused: this.paused,\n };\n }\n\n /**\n * Get aggregate stats for all series\n */\n getGlobalStats(): PressureStats {\n let totalSize = 0;\n let totalDropped = 0;\n let totalSampled = 0;\n\n for (const [seriesId] of this.buffers) {\n const buffer = this.buffers.get(seriesId)!;\n const stats = this.stats.get(seriesId)!;\n totalSize += buffer.size();\n totalDropped += stats.dropped;\n totalSampled += stats.sampled;\n }\n\n const maxTotal = this.config.maxBuffer * this.buffers.size;\n const fillLevel = maxTotal > 0 ? totalSize / maxTotal : 0;\n\n let state: PressureStats['state'] = 'normal';\n if (fillLevel >= this.config.criticalThreshold) {\n state = 'critical';\n } else if (fillLevel >= this.config.warningThreshold) {\n state = 'warning';\n }\n\n return {\n fillLevel,\n state,\n bufferSize: totalSize,\n maxBuffer: maxTotal,\n droppedCount: totalDropped,\n sampledCount: totalSampled,\n incomingRate: this.getAverageRate(this.incomingHistory),\n outgoingRate: this.getAverageRate(this.outgoingHistory),\n isPaused: this.paused,\n };\n }\n\n /**\n * Get buffer health assessment\n */\n getHealth(): BufferHealth {\n const stats = this.getGlobalStats();\n const recommendations: string[] = [];\n let score = 100;\n\n // Deduct for fill level\n if (stats.fillLevel > 0.9) {\n score -= 40;\n recommendations.push('Buffer critically full - reduce data rate or increase buffer size');\n } else if (stats.fillLevel > 0.7) {\n score -= 20;\n recommendations.push('Buffer filling up - consider increasing consumption rate');\n }\n\n // Deduct for drops\n if (stats.droppedCount > 0) {\n const dropRate = stats.droppedCount / (stats.droppedCount + stats.bufferSize + 1);\n score -= Math.min(30, dropRate * 100);\n recommendations.push(`Data being dropped (${stats.droppedCount} points) - buffer overflow`);\n }\n\n // Deduct for rate imbalance\n if (stats.incomingRate > stats.outgoingRate * 1.5) {\n score -= 15;\n recommendations.push('Incoming rate exceeds processing rate - consider sampling or throttling');\n }\n\n // Deduct for pause state\n if (stats.isPaused) {\n score -= 25;\n recommendations.push('Stream paused due to backpressure');\n }\n\n let status: BufferHealth['status'] = 'healthy';\n if (score < 50) {\n status = 'critical';\n } else if (score < 75) {\n status = 'degraded';\n }\n\n return {\n score: Math.max(0, score),\n status,\n recommendations,\n };\n }\n\n /**\n * Check if paused due to backpressure\n */\n isPaused(): boolean {\n return this.paused;\n }\n\n /**\n * Resume if paused\n */\n resume(): void {\n this.paused = false;\n }\n\n /**\n * Clear all buffers\n */\n clear(seriesId?: string): void {\n if (seriesId) {\n this.buffers.get(seriesId)?.clear();\n const stats = this.stats.get(seriesId);\n if (stats) {\n stats.dropped = 0;\n stats.sampled = 0;\n }\n } else {\n for (const buffer of this.buffers.values()) {\n buffer.clear();\n }\n for (const stats of this.stats.values()) {\n stats.dropped = 0;\n stats.sampled = 0;\n }\n }\n this.paused = false;\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<BackpressureConfig>): void {\n Object.assign(this.config, config);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): BackpressureConfig {\n return { ...this.config };\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private checkPressure(seriesId: string): void {\n const stats = this.getPressureStats(seriesId);\n this.config.onPressure?.(stats);\n }\n\n private updateRates(): void {\n const now = Date.now();\n const elapsed = now - this.lastRateUpdate;\n\n // Update every second\n if (elapsed >= 1000) {\n this.incomingHistory.push(this.currentIncoming);\n this.outgoingHistory.push(this.currentOutgoing);\n\n // Keep last 10 seconds\n if (this.incomingHistory.length > 10) this.incomingHistory.shift();\n if (this.outgoingHistory.length > 10) this.outgoingHistory.shift();\n\n this.currentIncoming = 0;\n this.currentOutgoing = 0;\n this.lastRateUpdate = now;\n }\n }\n\n private getAverageRate(history: number[]): number {\n if (history.length === 0) return 0;\n return history.reduce((a, b) => a + b, 0) / history.length;\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a backpressure manager with default settings\n */\nexport function createBackpressureManager(\n maxBuffer: number = 10000,\n strategy: OverflowStrategy = 'drop-oldest'\n): BackpressureManager {\n return new BackpressureManager({ maxBuffer, strategy });\n}\n\n/**\n * Create a high-performance backpressure manager optimized for real-time\n */\nexport function createRealtimeBackpressure(\n maxBuffer: number = 50000\n): BackpressureManager {\n return new BackpressureManager({\n maxBuffer,\n strategy: 'drop-oldest',\n warningThreshold: 0.8,\n criticalThreshold: 0.95,\n });\n}\n\n/**\n * Create a lossless backpressure manager (for when data loss is unacceptable)\n */\nexport function createLosslessBackpressure(\n maxBuffer: number = 100000\n): BackpressureManager {\n return new BackpressureManager({\n maxBuffer,\n strategy: 'pause',\n warningThreshold: 0.6,\n criticalThreshold: 0.8,\n });\n}\n","/**\n * Mock WebSocket Stream for Testing\n */\nimport { DataPoint, WebSocketStream, StreamStats } from \"./types\";\n\n/**\n * Mock WebSocket stream for testing\n */\nexport function createMockStream(config: {\n interval?: number;\n generatePoint?: () => DataPoint;\n}): WebSocketStream & { start: () => void; stop: () => void } {\n const { interval = 100, generatePoint = defaultGenerator } = config;\n \n let intervalId: ReturnType<typeof setInterval> | null = null;\n let connected = false;\n const subscribers = new Map<string, Set<(points: DataPoint[]) => void>>();\n \n const stats: StreamStats = {\n messagesReceived: 0,\n pointsProcessed: 0,\n reconnectCount: 0,\n lastMessageTime: null,\n connectionUptime: 0,\n bufferSize: 0,\n };\n\n let startTime: number | null = null;\n\n function start(): void {\n if (intervalId) return;\n \n startTime = Date.now();\n intervalId = setInterval(() => {\n const point = generatePoint();\n stats.messagesReceived++;\n stats.pointsProcessed++;\n stats.lastMessageTime = Date.now();\n \n const seriesId = point.seriesId || 'default';\n const callbacks = subscribers.get(seriesId);\n \n if (callbacks) {\n for (const callback of callbacks) {\n callback([point]);\n }\n }\n }, interval);\n }\n\n function stop(): void {\n if (intervalId) {\n clearInterval(intervalId);\n intervalId = null;\n }\n startTime = null;\n }\n\n return {\n connect: () => { connected = true; start(); },\n disconnect: () => { connected = false; stop(); },\n isConnected: () => connected,\n getState: () => connected ? 'connected' : 'disconnected',\n subscribe: (seriesId, callback) => {\n if (!subscribers.has(seriesId)) {\n subscribers.set(seriesId, new Set());\n }\n subscribers.get(seriesId)!.add(callback);\n return () => {\n subscribers.get(seriesId)?.delete(callback);\n };\n },\n unsubscribeAll: () => subscribers.clear(),\n send: () => {},\n getStats: () => ({\n ...stats,\n connectionUptime: startTime ? Date.now() - startTime : 0,\n }),\n start,\n stop,\n };\n}\n\nlet mockX = 0;\nfunction defaultGenerator(): DataPoint {\n return {\n x: mockX++,\n y: Math.sin(mockX * 0.1) + Math.random() * 0.2,\n };\n}\n","/**\n * Sci Plot - Streaming Plugin\n * \n * Provides real-time data streaming capabilities including:\n * - WebSocket connections\n * - Backpressure management\n * - Mock data streaming for testing\n * \n * @module plugins/streaming\n */\n\nexport {\n createWebSocketStream,\n} from \"../../streaming/websocket\";\n\nexport {\n connectStreamToChart,\n createMessageParser,\n} from \"../../streaming/utils\";\n\nexport {\n BackpressureManager,\n CircularBuffer,\n createBackpressureManager,\n} from \"../../streaming/backpressure\";\n\nexport { createMockStream } from \"../../streaming/mock\";\n\nexport * from \"../../streaming/types\";\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginStreamingConfig {\n /** Default WebSocket URL */\n url?: string;\n /** Backpressure strategy */\n backpressure?: {\n maxBufferSize?: number;\n overflowStrategy?: \"drop-oldest\" | \"drop-newest\" | \"error\";\n };\n}\n\nconst manifestStreaming: PluginManifest = {\n name: \"velo-plot-streaming\",\n version: \"1.0.0\",\n description: \"Real-time data streaming support for velo-plot\",\n provides: [\"data-source\"],\n tags: [\"websocket\", \"real-time\", \"streaming\", \"backpressure\"],\n};\n\n/**\n * SciPlot Streaming Plugin\n * \n * Enables seamless integration with real-time data sources.\n */\nexport function PluginStreaming(_config: PluginStreamingConfig = {}): ChartPlugin<PluginStreamingConfig> {\n return {\n manifest: manifestStreaming,\n\n onInit(_ctx: PluginContext) {\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport default PluginStreaming;\n"],"names":["defaultParser","data","item","point","createMessageParser","transform","connectStreamToChart","stream","chart","seriesIds","unsubscribers","seriesId","unsubscribe","points","x","p","y","createWebSocketStream","config","url","maxReconnectAttempts","reconnectDelay","bufferSize","throttleMs","parseMessage","onConnect","onDisconnect","onError","onReconnect","ws","state","reconnectAttempts","reconnectTimeout","connectionStartTime","buffers","subscribers","stats","lastFlushTime","flushScheduled","connect","event","handleMessage","scheduleReconnect","error","disconnect","parsed","pointArray","sum","b","scheduleFlush","timeSinceLastFlush","flush","buffer","callbacks","callback","message","CircularBuffer","capacity","__publicField","overwritten","n","result","toRemove","i","current","BackpressureManager","_a","_b","added","dropped","count","toConsume","fillLevel","totalSize","totalDropped","totalSampled","maxTotal","recommendations","score","dropRate","status","now","history","a","createBackpressureManager","maxBuffer","strategy","createRealtimeBackpressure","createLosslessBackpressure","createMockStream","interval","generatePoint","defaultGenerator","intervalId","connected","startTime","start","stop","mockX","manifestStreaming","PluginStreaming","_config","_ctx"],"mappings":"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"}
1
+ {"version":3,"file":"index-BMiZoKmm.js","sources":["../src/streaming/utils.ts","../src/streaming/websocket.ts","../src/streaming/backpressure.ts","../src/streaming/mock.ts","../src/plugins/streaming/index.ts"],"sourcesContent":["/**\n * WebSocket Streaming Utilities\n */\nimport { DataPoint, WebSocketStream } from \"./types\";\n\n/**\n * Default message parser - expects { x, y, seriesId? } or array of same\n */\nexport function defaultParser(data: unknown): DataPoint | DataPoint[] | null {\n if (!data || typeof data !== 'object') return null;\n \n // Array of points\n if (Array.isArray(data)) {\n return data\n .filter((item): item is DataPoint => \n typeof item === 'object' && \n item !== null && \n typeof item.x === 'number' && \n typeof item.y === 'number'\n );\n }\n \n // Single point\n const point = data as Record<string, unknown>;\n if (typeof point.x === 'number' && typeof point.y === 'number') {\n return {\n x: point.x,\n y: point.y,\n seriesId: typeof point.seriesId === 'string' ? point.seriesId : undefined,\n };\n }\n \n return null;\n}\n\n/**\n * Helper to create a parser for custom message formats\n */\nexport function createMessageParser<T>(\n transform: (message: T) => DataPoint | DataPoint[] | null\n): (data: unknown) => DataPoint | DataPoint[] | null {\n return (data: unknown) => {\n try {\n return transform(data as T);\n } catch {\n return null;\n }\n };\n}\n\n/**\n * Helper to connect a WebSocket stream to a chart\n */\nexport function connectStreamToChart(\n stream: WebSocketStream,\n chart: { appendData: (seriesId: string, data: { x: Float32Array; y: Float32Array }) => void },\n seriesIds: string[] = ['default']\n): () => void {\n const unsubscribers: (() => void)[] = [];\n\n for (const seriesId of seriesIds) {\n const unsubscribe = stream.subscribe(seriesId, (points) => {\n if (points.length === 0) return;\n \n const x = new Float32Array(points.map(p => p.x));\n const y = new Float32Array(points.map(p => p.y));\n \n chart.appendData(seriesId, { x, y });\n });\n \n unsubscribers.push(unsubscribe);\n }\n\n // Return cleanup function\n return () => {\n for (const unsubscribe of unsubscribers) {\n unsubscribe();\n }\n };\n}\n","/**\n * WebSocket Stream Implementation\n */\nimport { \n WebSocketStreamConfig, \n DataPoint, \n WebSocketStream, \n StreamStats, \n WebSocketState \n} from \"./types\";\nimport { defaultParser } from \"./utils\";\n\n/**\n * Create a WebSocket stream for real-time chart data\n */\nexport function createWebSocketStream(config: WebSocketStreamConfig): WebSocketStream {\n const {\n url,\n maxReconnectAttempts = 5,\n reconnectDelay = 1000,\n bufferSize = 10,\n throttleMs = 16,\n parseMessage = defaultParser,\n onConnect,\n onDisconnect,\n onError,\n onReconnect,\n } = config;\n\n let ws: WebSocket | null = null;\n let state: WebSocketState = 'disconnected';\n let reconnectAttempts = 0;\n let reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n let connectionStartTime: number | null = null;\n\n const buffers = new Map<string, DataPoint[]>();\n const subscribers = new Map<string, Set<(points: DataPoint[]) => void>>();\n \n const stats: StreamStats = {\n messagesReceived: 0,\n pointsProcessed: 0,\n reconnectCount: 0,\n lastMessageTime: null,\n connectionUptime: 0,\n bufferSize: 0,\n };\n\n let lastFlushTime = 0;\n let flushScheduled = false;\n\n function connect(): void {\n if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) {\n return;\n }\n state = 'connecting';\n try {\n ws = new WebSocket(url);\n ws.onopen = () => {\n state = 'connected';\n reconnectAttempts = 0;\n connectionStartTime = Date.now();\n onConnect?.();\n };\n ws.onmessage = (event) => handleMessage(event.data);\n ws.onclose = (event) => {\n state = 'disconnected';\n connectionStartTime = null;\n onDisconnect?.(event);\n if (!event.wasClean && reconnectAttempts < maxReconnectAttempts) scheduleReconnect();\n };\n ws.onerror = (error) => {\n state = 'error';\n onError?.(error);\n };\n } catch (error) {\n state = 'error';\n onError?.(error as Event);\n }\n }\n\n function disconnect(): void {\n if (reconnectTimeout) { clearTimeout(reconnectTimeout); reconnectTimeout = null; }\n if (ws) { ws.close(1000, 'Client disconnect'); ws = null; }\n state = 'disconnected';\n reconnectAttempts = 0;\n buffers.clear();\n }\n\n function scheduleReconnect(): void {\n if (reconnectTimeout) return;\n state = 'reconnecting';\n reconnectAttempts++;\n stats.reconnectCount++;\n onReconnect?.(reconnectAttempts);\n reconnectTimeout = setTimeout(() => {\n reconnectTimeout = null;\n connect();\n }, reconnectDelay * reconnectAttempts);\n }\n\n function handleMessage(data: unknown): void {\n stats.messagesReceived++;\n stats.lastMessageTime = Date.now();\n try {\n const parsed = typeof data === 'string' ? JSON.parse(data) : data;\n const points = parseMessage(parsed);\n if (!points) return;\n const pointArray = Array.isArray(points) ? points : [points];\n for (const point of pointArray) {\n const seriesId = point.seriesId || 'default';\n if (!buffers.has(seriesId)) buffers.set(seriesId, []);\n buffers.get(seriesId)!.push(point);\n stats.pointsProcessed++;\n }\n stats.bufferSize = Array.from(buffers.values()).reduce((sum, b) => sum + b.length, 0);\n scheduleFlush();\n } catch {}\n }\n\n function scheduleFlush(): void {\n if (flushScheduled) return;\n const now = performance.now();\n const timeSinceLastFlush = now - lastFlushTime;\n if (timeSinceLastFlush >= throttleMs) {\n flush();\n } else {\n flushScheduled = true;\n setTimeout(() => { flushScheduled = false; flush(); }, throttleMs - timeSinceLastFlush);\n }\n }\n\n function flush(): void {\n lastFlushTime = performance.now();\n for (const [seriesId, buffer] of buffers.entries()) {\n if (buffer.length === 0) continue;\n if (buffer.length >= bufferSize || performance.now() - lastFlushTime > throttleMs * 2) {\n const callbacks = subscribers.get(seriesId);\n if (callbacks) {\n const points = buffer.splice(0, buffer.length);\n for (const callback of callbacks) callback(points);\n } else {\n buffer.length = 0;\n }\n }\n }\n stats.bufferSize = Array.from(buffers.values()).reduce((sum, b) => sum + b.length, 0);\n }\n\n return {\n connect,\n disconnect,\n isConnected: () => ws !== null && ws.readyState === WebSocket.OPEN,\n getState: () => state,\n subscribe: (seriesId, callback) => {\n if (!subscribers.has(seriesId)) subscribers.set(seriesId, new Set());\n subscribers.get(seriesId)!.add(callback);\n return () => {\n const callbacks = subscribers.get(seriesId);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) subscribers.delete(seriesId);\n }\n };\n },\n unsubscribeAll: () => { subscribers.clear(); buffers.clear(); },\n send: (message) => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(typeof message === 'string' ? message : JSON.stringify(message));\n }\n },\n getStats: () => ({ ...stats, connectionUptime: connectionStartTime ? Date.now() - connectionStartTime : 0 }),\n };\n}\n","/**\n * Velo Plot - Backpressure Management Module\n * \n * Provides advanced backpressure handling for streaming data:\n * - Configurable buffer limits\n * - Multiple overflow strategies (drop-oldest, pause, sample)\n * - Health monitoring and metrics\n * - Automatic flow control\n * \n * @module backpressure\n */\n\nimport type { DataPoint } from \"./types\";\n\n// ============================================\n// Types\n// ============================================\n\nexport type OverflowStrategy = 'drop-oldest' | 'drop-newest' | 'pause' | 'sample' | 'block';\n\nexport interface BackpressureConfig {\n /** Maximum buffer size before triggering backpressure (default: 10000) */\n maxBuffer: number;\n /** Warning threshold as fraction of maxBuffer (default: 0.7) */\n warningThreshold?: number;\n /** Critical threshold as fraction of maxBuffer (default: 0.9) */\n criticalThreshold?: number;\n /** Overflow handling strategy (default: 'drop-oldest') */\n strategy: OverflowStrategy;\n /** For 'sample' strategy: keep every Nth point (default: 2) */\n sampleRate?: number;\n /** Callback when pressure level changes */\n onPressure?: (stats: PressureStats) => void;\n /** Callback when buffer overflows */\n onOverflow?: (droppedCount: number) => void;\n /** Callback when back to normal */\n onRecovery?: () => void;\n}\n\nexport interface PressureStats {\n /** Current buffer fill level (0-1) */\n fillLevel: number;\n /** Pressure state */\n state: 'normal' | 'warning' | 'critical' | 'overflow';\n /** Current buffer size */\n bufferSize: number;\n /** Maximum buffer size */\n maxBuffer: number;\n /** Points dropped due to overflow */\n droppedCount: number;\n /** Points sampled/skipped */\n sampledCount: number;\n /** Incoming rate (points per second) */\n incomingRate: number;\n /** Outgoing rate (points per second) */\n outgoingRate: number;\n /** Whether stream is paused due to backpressure */\n isPaused: boolean;\n}\n\nexport interface BufferHealth {\n /** Overall health score (0-100) */\n score: number;\n /** Health status */\n status: 'healthy' | 'degraded' | 'critical';\n /** Recommendations */\n recommendations: string[];\n}\n\n// ============================================\n// Circular Buffer Implementation\n// ============================================\n\nexport class CircularBuffer<T> {\n private buffer: T[];\n private head: number = 0;\n private tail: number = 0;\n private count: number = 0;\n private readonly capacity: number;\n\n constructor(capacity: number) {\n this.capacity = capacity;\n this.buffer = new Array(capacity);\n }\n\n /**\n * Add item to buffer\n * @returns true if item was added, false if buffer was full\n */\n push(item: T): boolean {\n if (this.count === this.capacity) {\n return false;\n }\n this.buffer[this.tail] = item;\n this.tail = (this.tail + 1) % this.capacity;\n this.count++;\n return true;\n }\n\n /**\n * Add item, overwriting oldest if full\n * @returns the overwritten item, or undefined\n */\n pushOverwrite(item: T): T | undefined {\n let overwritten: T | undefined;\n if (this.count === this.capacity) {\n overwritten = this.buffer[this.head];\n this.head = (this.head + 1) % this.capacity;\n this.count--;\n }\n this.buffer[this.tail] = item;\n this.tail = (this.tail + 1) % this.capacity;\n this.count++;\n return overwritten;\n }\n\n /**\n * Remove and return oldest item\n */\n shift(): T | undefined {\n if (this.count === 0) {\n return undefined;\n }\n const item = this.buffer[this.head];\n this.head = (this.head + 1) % this.capacity;\n this.count--;\n return item;\n }\n\n /**\n * Remove and return multiple items\n */\n shiftMany(n: number): T[] {\n const result: T[] = [];\n const toRemove = Math.min(n, this.count);\n for (let i = 0; i < toRemove; i++) {\n result.push(this.buffer[this.head]);\n this.head = (this.head + 1) % this.capacity;\n }\n this.count -= toRemove;\n return result;\n }\n\n /**\n * Peek at oldest item without removing\n */\n peek(): T | undefined {\n return this.count > 0 ? this.buffer[this.head] : undefined;\n }\n\n /**\n * Get all items as array\n */\n toArray(): T[] {\n const result: T[] = [];\n let current = this.head;\n for (let i = 0; i < this.count; i++) {\n result.push(this.buffer[current]);\n current = (current + 1) % this.capacity;\n }\n return result;\n }\n\n /**\n * Clear the buffer\n */\n clear(): void {\n this.head = 0;\n this.tail = 0;\n this.count = 0;\n }\n\n /**\n * Get current size\n */\n size(): number {\n return this.count;\n }\n\n /**\n * Check if buffer is full\n */\n isFull(): boolean {\n return this.count === this.capacity;\n }\n\n /**\n * Check if buffer is empty\n */\n isEmpty(): boolean {\n return this.count === 0;\n }\n\n /**\n * Get fill level (0-1)\n */\n fillLevel(): number {\n return this.count / this.capacity;\n }\n\n /**\n * Get capacity\n */\n getCapacity(): number {\n return this.capacity;\n }\n}\n\n// ============================================\n// Backpressure Manager\n// ============================================\n\nexport class BackpressureManager {\n private config: Required<BackpressureConfig>;\n private buffers: Map<string, CircularBuffer<DataPoint>> = new Map();\n private stats: Map<string, { dropped: number; sampled: number; lastIncoming: number; lastOutgoing: number }> = new Map();\n private paused: boolean = false;\n private sampleCounter: number = 0;\n\n // Rate tracking\n private incomingHistory: number[] = [];\n private outgoingHistory: number[] = [];\n private lastRateUpdate: number = 0;\n private currentIncoming: number = 0;\n private currentOutgoing: number = 0;\n\n constructor(config: BackpressureConfig) {\n this.config = {\n warningThreshold: 0.7,\n criticalThreshold: 0.9,\n sampleRate: 2,\n onPressure: undefined,\n onOverflow: undefined,\n onRecovery: undefined,\n ...config,\n } as Required<BackpressureConfig>;\n }\n\n /**\n * Add points to the buffer with backpressure handling\n */\n push(seriesId: string, points: DataPoint[]): number {\n if (!this.buffers.has(seriesId)) {\n this.buffers.set(seriesId, new CircularBuffer(this.config.maxBuffer));\n this.stats.set(seriesId, { dropped: 0, sampled: 0, lastIncoming: 0, lastOutgoing: 0 });\n }\n\n const buffer = this.buffers.get(seriesId)!;\n const stats = this.stats.get(seriesId)!;\n let added = 0;\n let dropped = 0;\n\n for (const point of points) {\n this.currentIncoming++;\n stats.lastIncoming = Date.now();\n\n // Handle based on strategy when buffer is under pressure\n if (buffer.fillLevel() >= this.config.criticalThreshold) {\n switch (this.config.strategy) {\n case 'drop-oldest':\n // Overwrite oldest points\n const overwritten = buffer.pushOverwrite(point);\n if (overwritten) {\n dropped++;\n stats.dropped++;\n }\n added++;\n break;\n\n case 'drop-newest':\n // Skip new points\n dropped++;\n stats.dropped++;\n continue;\n\n case 'pause':\n // Signal pause (external handling required)\n this.paused = true;\n return added;\n\n case 'sample':\n // Keep every Nth point\n this.sampleCounter++;\n if (this.sampleCounter >= this.config.sampleRate) {\n this.sampleCounter = 0;\n buffer.pushOverwrite(point);\n added++;\n } else {\n stats.sampled++;\n }\n break;\n\n case 'block':\n // Block until buffer has space\n if (!buffer.isFull()) {\n buffer.push(point);\n added++;\n }\n break;\n }\n } else {\n // Normal operation\n if (buffer.push(point)) {\n added++;\n } else {\n // Shouldn't happen in normal operation\n buffer.pushOverwrite(point);\n added++;\n dropped++;\n stats.dropped++;\n }\n }\n }\n\n // Track drops\n if (dropped > 0) {\n this.config.onOverflow?.(dropped);\n }\n\n // Check and report pressure state\n this.checkPressure(seriesId);\n this.updateRates();\n\n return added;\n }\n\n /**\n * Consume points from buffer\n */\n consume(seriesId: string, count?: number): DataPoint[] {\n const buffer = this.buffers.get(seriesId);\n if (!buffer) return [];\n\n const stats = this.stats.get(seriesId)!;\n const toConsume = count ?? buffer.size();\n const points = buffer.shiftMany(toConsume);\n\n this.currentOutgoing += points.length;\n stats.lastOutgoing = Date.now();\n\n // Check for recovery from paused state\n if (this.paused && buffer.fillLevel() < this.config.warningThreshold) {\n this.paused = false;\n this.config.onRecovery?.();\n }\n\n this.updateRates();\n return points;\n }\n\n /**\n * Consume all points from buffer\n */\n consumeAll(seriesId: string): DataPoint[] {\n return this.consume(seriesId);\n }\n\n /**\n * Get current pressure stats for a series\n */\n getPressureStats(seriesId: string): PressureStats {\n const buffer = this.buffers.get(seriesId);\n const stats = this.stats.get(seriesId);\n\n if (!buffer || !stats) {\n return {\n fillLevel: 0,\n state: 'normal',\n bufferSize: 0,\n maxBuffer: this.config.maxBuffer,\n droppedCount: 0,\n sampledCount: 0,\n incomingRate: 0,\n outgoingRate: 0,\n isPaused: false,\n };\n }\n\n const fillLevel = buffer.fillLevel();\n let state: PressureStats['state'] = 'normal';\n if (fillLevel >= this.config.criticalThreshold) {\n state = buffer.isFull() ? 'overflow' : 'critical';\n } else if (fillLevel >= this.config.warningThreshold) {\n state = 'warning';\n }\n\n return {\n fillLevel,\n state,\n bufferSize: buffer.size(),\n maxBuffer: this.config.maxBuffer,\n droppedCount: stats.dropped,\n sampledCount: stats.sampled,\n incomingRate: this.getAverageRate(this.incomingHistory),\n outgoingRate: this.getAverageRate(this.outgoingHistory),\n isPaused: this.paused,\n };\n }\n\n /**\n * Get aggregate stats for all series\n */\n getGlobalStats(): PressureStats {\n let totalSize = 0;\n let totalDropped = 0;\n let totalSampled = 0;\n\n for (const [seriesId] of this.buffers) {\n const buffer = this.buffers.get(seriesId)!;\n const stats = this.stats.get(seriesId)!;\n totalSize += buffer.size();\n totalDropped += stats.dropped;\n totalSampled += stats.sampled;\n }\n\n const maxTotal = this.config.maxBuffer * this.buffers.size;\n const fillLevel = maxTotal > 0 ? totalSize / maxTotal : 0;\n\n let state: PressureStats['state'] = 'normal';\n if (fillLevel >= this.config.criticalThreshold) {\n state = 'critical';\n } else if (fillLevel >= this.config.warningThreshold) {\n state = 'warning';\n }\n\n return {\n fillLevel,\n state,\n bufferSize: totalSize,\n maxBuffer: maxTotal,\n droppedCount: totalDropped,\n sampledCount: totalSampled,\n incomingRate: this.getAverageRate(this.incomingHistory),\n outgoingRate: this.getAverageRate(this.outgoingHistory),\n isPaused: this.paused,\n };\n }\n\n /**\n * Get buffer health assessment\n */\n getHealth(): BufferHealth {\n const stats = this.getGlobalStats();\n const recommendations: string[] = [];\n let score = 100;\n\n // Deduct for fill level\n if (stats.fillLevel > 0.9) {\n score -= 40;\n recommendations.push('Buffer critically full - reduce data rate or increase buffer size');\n } else if (stats.fillLevel > 0.7) {\n score -= 20;\n recommendations.push('Buffer filling up - consider increasing consumption rate');\n }\n\n // Deduct for drops\n if (stats.droppedCount > 0) {\n const dropRate = stats.droppedCount / (stats.droppedCount + stats.bufferSize + 1);\n score -= Math.min(30, dropRate * 100);\n recommendations.push(`Data being dropped (${stats.droppedCount} points) - buffer overflow`);\n }\n\n // Deduct for rate imbalance\n if (stats.incomingRate > stats.outgoingRate * 1.5) {\n score -= 15;\n recommendations.push('Incoming rate exceeds processing rate - consider sampling or throttling');\n }\n\n // Deduct for pause state\n if (stats.isPaused) {\n score -= 25;\n recommendations.push('Stream paused due to backpressure');\n }\n\n let status: BufferHealth['status'] = 'healthy';\n if (score < 50) {\n status = 'critical';\n } else if (score < 75) {\n status = 'degraded';\n }\n\n return {\n score: Math.max(0, score),\n status,\n recommendations,\n };\n }\n\n /**\n * Check if paused due to backpressure\n */\n isPaused(): boolean {\n return this.paused;\n }\n\n /**\n * Resume if paused\n */\n resume(): void {\n this.paused = false;\n }\n\n /**\n * Clear all buffers\n */\n clear(seriesId?: string): void {\n if (seriesId) {\n this.buffers.get(seriesId)?.clear();\n const stats = this.stats.get(seriesId);\n if (stats) {\n stats.dropped = 0;\n stats.sampled = 0;\n }\n } else {\n for (const buffer of this.buffers.values()) {\n buffer.clear();\n }\n for (const stats of this.stats.values()) {\n stats.dropped = 0;\n stats.sampled = 0;\n }\n }\n this.paused = false;\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<BackpressureConfig>): void {\n Object.assign(this.config, config);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): BackpressureConfig {\n return { ...this.config };\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private checkPressure(seriesId: string): void {\n const stats = this.getPressureStats(seriesId);\n this.config.onPressure?.(stats);\n }\n\n private updateRates(): void {\n const now = Date.now();\n const elapsed = now - this.lastRateUpdate;\n\n // Update every second\n if (elapsed >= 1000) {\n this.incomingHistory.push(this.currentIncoming);\n this.outgoingHistory.push(this.currentOutgoing);\n\n // Keep last 10 seconds\n if (this.incomingHistory.length > 10) this.incomingHistory.shift();\n if (this.outgoingHistory.length > 10) this.outgoingHistory.shift();\n\n this.currentIncoming = 0;\n this.currentOutgoing = 0;\n this.lastRateUpdate = now;\n }\n }\n\n private getAverageRate(history: number[]): number {\n if (history.length === 0) return 0;\n return history.reduce((a, b) => a + b, 0) / history.length;\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a backpressure manager with default settings\n */\nexport function createBackpressureManager(\n maxBuffer: number = 10000,\n strategy: OverflowStrategy = 'drop-oldest'\n): BackpressureManager {\n return new BackpressureManager({ maxBuffer, strategy });\n}\n\n/**\n * Create a high-performance backpressure manager optimized for real-time\n */\nexport function createRealtimeBackpressure(\n maxBuffer: number = 50000\n): BackpressureManager {\n return new BackpressureManager({\n maxBuffer,\n strategy: 'drop-oldest',\n warningThreshold: 0.8,\n criticalThreshold: 0.95,\n });\n}\n\n/**\n * Create a lossless backpressure manager (for when data loss is unacceptable)\n */\nexport function createLosslessBackpressure(\n maxBuffer: number = 100000\n): BackpressureManager {\n return new BackpressureManager({\n maxBuffer,\n strategy: 'pause',\n warningThreshold: 0.6,\n criticalThreshold: 0.8,\n });\n}\n","/**\n * Mock WebSocket Stream for Testing\n */\nimport { DataPoint, WebSocketStream, StreamStats } from \"./types\";\n\n/**\n * Mock WebSocket stream for testing\n */\nexport function createMockStream(config: {\n interval?: number;\n generatePoint?: () => DataPoint;\n}): WebSocketStream & { start: () => void; stop: () => void } {\n const { interval = 100, generatePoint = defaultGenerator } = config;\n \n let intervalId: ReturnType<typeof setInterval> | null = null;\n let connected = false;\n const subscribers = new Map<string, Set<(points: DataPoint[]) => void>>();\n \n const stats: StreamStats = {\n messagesReceived: 0,\n pointsProcessed: 0,\n reconnectCount: 0,\n lastMessageTime: null,\n connectionUptime: 0,\n bufferSize: 0,\n };\n\n let startTime: number | null = null;\n\n function start(): void {\n if (intervalId) return;\n \n startTime = Date.now();\n intervalId = setInterval(() => {\n const point = generatePoint();\n stats.messagesReceived++;\n stats.pointsProcessed++;\n stats.lastMessageTime = Date.now();\n \n const seriesId = point.seriesId || 'default';\n const callbacks = subscribers.get(seriesId);\n \n if (callbacks) {\n for (const callback of callbacks) {\n callback([point]);\n }\n }\n }, interval);\n }\n\n function stop(): void {\n if (intervalId) {\n clearInterval(intervalId);\n intervalId = null;\n }\n startTime = null;\n }\n\n return {\n connect: () => { connected = true; start(); },\n disconnect: () => { connected = false; stop(); },\n isConnected: () => connected,\n getState: () => connected ? 'connected' : 'disconnected',\n subscribe: (seriesId, callback) => {\n if (!subscribers.has(seriesId)) {\n subscribers.set(seriesId, new Set());\n }\n subscribers.get(seriesId)!.add(callback);\n return () => {\n subscribers.get(seriesId)?.delete(callback);\n };\n },\n unsubscribeAll: () => subscribers.clear(),\n send: () => {},\n getStats: () => ({\n ...stats,\n connectionUptime: startTime ? Date.now() - startTime : 0,\n }),\n start,\n stop,\n };\n}\n\nlet mockX = 0;\nfunction defaultGenerator(): DataPoint {\n return {\n x: mockX++,\n y: Math.sin(mockX * 0.1) + Math.random() * 0.2,\n };\n}\n","/**\n * Velo Plot - Streaming Plugin\n * \n * Provides real-time data streaming capabilities including:\n * - WebSocket connections\n * - Backpressure management\n * - Mock data streaming for testing\n * \n * @module plugins/streaming\n */\n\nexport {\n createWebSocketStream,\n} from \"../../streaming/websocket\";\n\nexport {\n connectStreamToChart,\n createMessageParser,\n} from \"../../streaming/utils\";\n\nexport {\n BackpressureManager,\n CircularBuffer,\n createBackpressureManager,\n} from \"../../streaming/backpressure\";\n\nexport { createMockStream } from \"../../streaming/mock\";\n\nexport * from \"../../streaming/types\";\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginStreamingConfig {\n /** Default WebSocket URL */\n url?: string;\n /** Backpressure strategy */\n backpressure?: {\n maxBufferSize?: number;\n overflowStrategy?: \"drop-oldest\" | \"drop-newest\" | \"error\";\n };\n}\n\nconst manifestStreaming: PluginManifest = {\n name: \"velo-plot-streaming\",\n version: \"1.0.0\",\n description: \"Real-time data streaming support for velo-plot\",\n provides: [\"data-source\"],\n tags: [\"websocket\", \"real-time\", \"streaming\", \"backpressure\"],\n};\n\n/**\n * VeloPlot Streaming Plugin\n * \n * Enables seamless integration with real-time data sources.\n */\nexport function PluginStreaming(_config: PluginStreamingConfig = {}): ChartPlugin<PluginStreamingConfig> {\n return {\n manifest: manifestStreaming,\n\n onInit(_ctx: PluginContext) {\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport default PluginStreaming;\n"],"names":["defaultParser","data","item","point","createMessageParser","transform","connectStreamToChart","stream","chart","seriesIds","unsubscribers","seriesId","unsubscribe","points","x","p","y","createWebSocketStream","config","url","maxReconnectAttempts","reconnectDelay","bufferSize","throttleMs","parseMessage","onConnect","onDisconnect","onError","onReconnect","ws","state","reconnectAttempts","reconnectTimeout","connectionStartTime","buffers","subscribers","stats","lastFlushTime","flushScheduled","connect","event","handleMessage","scheduleReconnect","error","disconnect","parsed","pointArray","sum","b","scheduleFlush","timeSinceLastFlush","flush","buffer","callbacks","callback","message","CircularBuffer","capacity","__publicField","overwritten","n","result","toRemove","i","current","BackpressureManager","_a","_b","added","dropped","count","toConsume","fillLevel","totalSize","totalDropped","totalSampled","maxTotal","recommendations","score","dropRate","status","now","history","a","createBackpressureManager","maxBuffer","strategy","createRealtimeBackpressure","createLosslessBackpressure","createMockStream","interval","generatePoint","defaultGenerator","intervalId","connected","startTime","start","stop","mockX","manifestStreaming","PluginStreaming","_config","_ctx"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  var Y = Object.defineProperty;
2
- var _ = (s, e, n) => e in s ? Y(s, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : s[e] = n;
3
- var o = (s, e, n) => _(s, typeof e != "symbol" ? e + "" : e, n);
2
+ var _ = (a, e, n) => e in a ? Y(a, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : a[e] = n;
3
+ var r = (a, e, n) => _(a, typeof e != "symbol" ? e + "" : e, n);
4
4
  const F = [
5
5
  // Zoom/Scale
6
6
  { key: "KeyR", action: "resetZoom", description: "Reset zoom to fit data" },
@@ -33,14 +33,14 @@ const F = [
33
33
  { key: "KeyZ", action: "redo", ctrl: !0, shift: !0, description: "Redo" },
34
34
  { key: "KeyY", action: "redo", ctrl: !0, description: "Redo" }
35
35
  ];
36
- class G {
36
+ class X {
37
37
  constructor(e) {
38
- o(this, "bindings", []);
39
- o(this, "callbacks");
40
- o(this, "target");
41
- o(this, "enabled", !0);
42
- o(this, "preventDefault", !0);
43
- o(this, "boundHandler");
38
+ r(this, "bindings", []);
39
+ r(this, "callbacks");
40
+ r(this, "target");
41
+ r(this, "enabled", !0);
42
+ r(this, "preventDefault", !0);
43
+ r(this, "boundHandler");
44
44
  this.callbacks = e.callbacks, this.target = e.target || document, this.enabled = e.enabled !== !1, this.preventDefault = e.preventDefault !== !1, e.replaceDefaults ? this.bindings = [...e.bindings || []] : this.bindings = [...F, ...e.bindings || []], this.boundHandler = this.handleKeyDown.bind(this), this.attach();
45
45
  }
46
46
  /**
@@ -83,14 +83,14 @@ class G {
83
83
  * Update an existing binding
84
84
  */
85
85
  updateBinding(e, n) {
86
- const t = this.bindings.find((a) => a.key === e);
86
+ const t = this.bindings.find((i) => i.key === e);
87
87
  t && Object.assign(t, n);
88
88
  }
89
89
  /**
90
90
  * Enable/disable a specific binding
91
91
  */
92
92
  setBindingEnabled(e, n) {
93
- const t = this.bindings.find((a) => a.key === e);
93
+ const t = this.bindings.find((i) => i.key === e);
94
94
  t && (t.enabled = n);
95
95
  }
96
96
  /**
@@ -145,40 +145,40 @@ class G {
145
145
  * Execute the action for a binding
146
146
  */
147
147
  executeAction(e) {
148
- var a, c, i, r, l, u, d, g, p, f, h, y, k, b, m, K, D, E, w, S, A, v, P, R, B, L, T, I, U, Z, C, x, z, M, N, H, O, q, W, j;
148
+ var i, s, c, l, o, u, d, g, h, f, p, y, k, b, m, K, D, w, E, A, S, B, L, v, P, R, T, x, U, C, Z, I, z, M, N, H, O, q, W, j;
149
149
  const { action: n, handler: t } = e;
150
150
  switch (n) {
151
151
  case "resetZoom":
152
- return (c = (a = this.callbacks).onResetZoom) == null || c.call(a), !0;
152
+ return (s = (i = this.callbacks).onResetZoom) == null || s.call(i), !0;
153
153
  case "autoScale":
154
- return (r = (i = this.callbacks).onAutoScale) == null || r.call(i), !0;
154
+ return (l = (c = this.callbacks).onAutoScale) == null || l.call(c), !0;
155
155
  case "zoomIn":
156
- return (u = (l = this.callbacks).onZoomIn) == null || u.call(l), !0;
156
+ return (u = (o = this.callbacks).onZoomIn) == null || u.call(o), !0;
157
157
  case "zoomOut":
158
158
  return (g = (d = this.callbacks).onZoomOut) == null || g.call(d), !0;
159
159
  case "panLeft":
160
- return (f = (p = this.callbacks).onPanLeft) == null || f.call(p), !0;
160
+ return (f = (h = this.callbacks).onPanLeft) == null || f.call(h), !0;
161
161
  case "panRight":
162
- return (y = (h = this.callbacks).onPanRight) == null || y.call(h), !0;
162
+ return (y = (p = this.callbacks).onPanRight) == null || y.call(p), !0;
163
163
  case "panUp":
164
164
  return (b = (k = this.callbacks).onPanUp) == null || b.call(k), !0;
165
165
  case "panDown":
166
166
  return (K = (m = this.callbacks).onPanDown) == null || K.call(m), !0;
167
167
  case "togglePan":
168
- return (E = (D = this.callbacks).onTogglePan) == null || E.call(D), !0;
168
+ return (w = (D = this.callbacks).onTogglePan) == null || w.call(D), !0;
169
169
  case "toggleSelect":
170
- return (S = (w = this.callbacks).onToggleSelect) == null || S.call(w), !0;
170
+ return (A = (E = this.callbacks).onToggleSelect) == null || A.call(E), !0;
171
171
  case "clearSelection":
172
172
  case "escape":
173
- return (v = (A = this.callbacks).onEscape) == null || v.call(A), (R = (P = this.callbacks).onClearSelection) == null || R.call(P), !0;
173
+ return (B = (S = this.callbacks).onEscape) == null || B.call(S), (v = (L = this.callbacks).onClearSelection) == null || v.call(L), !0;
174
174
  case "deleteSelected":
175
- return (L = (B = this.callbacks).onDeleteSelected) == null || L.call(B), !0;
175
+ return (R = (P = this.callbacks).onDeleteSelected) == null || R.call(P), !0;
176
176
  case "selectAll":
177
- return (I = (T = this.callbacks).onSelectAll) == null || I.call(T), !0;
177
+ return (x = (T = this.callbacks).onSelectAll) == null || x.call(T), !0;
178
178
  case "copy":
179
- return (Z = (U = this.callbacks).onCopy) == null || Z.call(U), !0;
179
+ return (C = (U = this.callbacks).onCopy) == null || C.call(U), !0;
180
180
  case "exportImage":
181
- return (x = (C = this.callbacks).onExportImage) == null || x.call(C), !0;
181
+ return (I = (Z = this.callbacks).onExportImage) == null || I.call(Z), !0;
182
182
  case "toggleLegend":
183
183
  return (M = (z = this.callbacks).onToggleLegend) == null || M.call(z), !0;
184
184
  case "toggleDebug":
@@ -200,15 +200,15 @@ class G {
200
200
  this.detach(), this.bindings = [];
201
201
  }
202
202
  }
203
- function Q(s, e, n) {
203
+ function J(a, e, n) {
204
204
  return {
205
- key: s,
205
+ key: a,
206
206
  action: e,
207
207
  ...n
208
208
  };
209
209
  }
210
- function V(s, e) {
211
- const n = s.split("+").map((a) => a.trim().toLowerCase()), t = {
210
+ function Q(a, e) {
211
+ const n = a.split("+").map((i) => i.trim().toLowerCase()), t = {
212
212
  key: "",
213
213
  action: e,
214
214
  ctrl: !1,
@@ -216,8 +216,8 @@ function V(s, e) {
216
216
  alt: !1,
217
217
  meta: !1
218
218
  };
219
- for (const a of n)
220
- switch (a) {
219
+ for (const i of n)
220
+ switch (i) {
221
221
  case "ctrl":
222
222
  case "control":
223
223
  t.ctrl = !0;
@@ -234,10 +234,10 @@ function V(s, e) {
234
234
  t.meta = !0;
235
235
  break;
236
236
  default:
237
- if (a.length === 1)
238
- /[a-z]/i.test(a) ? t.key = "Key" + a.toUpperCase() : /[0-9]/.test(a) ? t.key = "Digit" + a : a === "+" ? t.key = "Equal" : a === "-" && (t.key = "Minus");
237
+ if (i.length === 1)
238
+ /[a-z]/i.test(i) ? t.key = "Key" + i.toUpperCase() : /[0-9]/.test(i) ? t.key = "Digit" + i : i === "+" ? t.key = "Equal" : i === "-" && (t.key = "Minus");
239
239
  else {
240
- const c = {
240
+ const s = {
241
241
  escape: "Escape",
242
242
  esc: "Escape",
243
243
  enter: "Enter",
@@ -251,75 +251,15 @@ function V(s, e) {
251
251
  up: "ArrowUp",
252
252
  down: "ArrowDown"
253
253
  };
254
- t.key = c[a] || a;
254
+ t.key = s[i] || i;
255
255
  }
256
256
  }
257
257
  return t;
258
258
  }
259
- const X = {
260
- name: "velo-plot-keyboard",
261
- version: "1.0.0",
262
- description: "Keyboard shortcut management for velo-plot",
263
- provides: ["interaction"],
264
- tags: ["keyboard", "shortcuts", "interaction", "accessibility"]
265
- };
266
- function $(s = {}) {
267
- let e = null;
268
- return {
269
- manifest: X,
270
- onInit(n) {
271
- var c;
272
- const t = n.chart, a = (c = n.getPlugin) == null ? void 0 : c.call(n, "velo-plot-drawing-tools");
273
- e = new G({
274
- target: n.ui.container,
275
- bindings: [...s.bindings ?? [], ...s.extraShortcuts ?? []],
276
- replaceDefaults: s.replaceDefaults,
277
- callbacks: {
278
- onResetZoom: () => {
279
- var i;
280
- return (i = t.resetZoom) == null ? void 0 : i.call(t);
281
- },
282
- onAutoScale: () => {
283
- var i;
284
- return (i = t.autoScale) == null ? void 0 : i.call(t, !1);
285
- },
286
- onEscape: () => {
287
- var i;
288
- return (i = t.clearSelection) == null ? void 0 : i.call(t);
289
- },
290
- onExportImage: () => {
291
- var i;
292
- try {
293
- const r = (i = t.exportImage) == null ? void 0 : i.call(t, "png");
294
- if (r) {
295
- const l = document.createElement("a");
296
- l.href = r, l.download = "chart.png", l.click();
297
- }
298
- } catch {
299
- }
300
- },
301
- onUndo: () => {
302
- var i, r;
303
- return (r = (i = a == null ? void 0 : a.api) == null ? void 0 : i.undo) == null ? void 0 : r.call(i);
304
- },
305
- onRedo: () => {
306
- var i, r;
307
- return (r = (i = a == null ? void 0 : a.api) == null ? void 0 : i.redo) == null ? void 0 : r.call(i);
308
- },
309
- ...s.callbacks
310
- }
311
- });
312
- },
313
- onDestroy() {
314
- e == null || e.destroy(), e = null;
315
- }
316
- };
317
- }
318
259
  export {
319
260
  F as D,
320
- G as K,
321
- $ as P,
322
- Q as c,
323
- V as p
261
+ X as K,
262
+ J as c,
263
+ Q as p
324
264
  };
325
- //# sourceMappingURL=index-DoYxf1cV.js.map
265
+ //# sourceMappingURL=index-CWxIHdwX.js.map