velo-plot 2.20.0 → 3.1.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 (287) hide show
  1. package/README.md +26 -12
  2. package/dist/ChartCore-AnR_3Xkb.js +7338 -0
  3. package/dist/ChartCore-AnR_3Xkb.js.map +1 -0
  4. package/dist/GpuChartRenderer-Dxc0hrQA.js +75 -0
  5. package/dist/GpuChartRenderer-Dxc0hrQA.js.map +1 -0
  6. package/dist/{index.core-COREBDNq.js → PluginRegistry-CzMHebYP.js} +24 -38
  7. package/dist/PluginRegistry-CzMHebYP.js.map +1 -0
  8. package/dist/a11y-Bw6urYpr.js +105 -0
  9. package/dist/a11y-Bw6urYpr.js.map +1 -0
  10. package/dist/angular/hooks-entry.d.ts +1 -0
  11. package/dist/angular/hooks.d.ts +26 -0
  12. package/dist/angular/index.d.ts +8 -0
  13. package/dist/angular/velo-plot.component.d.ts +46 -0
  14. package/dist/angular-hooks.d.ts +1 -0
  15. package/dist/angular-hooks.js +9 -0
  16. package/dist/angular-hooks.js.map +1 -0
  17. package/dist/angular.d.ts +1 -0
  18. package/dist/angular.js +166 -0
  19. package/dist/angular.js.map +1 -0
  20. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
  21. package/dist/astro/StackedPlot.astro +19 -0
  22. package/dist/astro/VeloPlot.astro +23 -0
  23. package/dist/{axisFormat-CzumxpCL.js → axisFormat-Sz4WIJfQ.js} +2 -2
  24. package/dist/{axisFormat-CzumxpCL.js.map → axisFormat-Sz4WIJfQ.js.map} +1 -1
  25. package/dist/bindings/shared/a11y.d.ts +26 -0
  26. package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
  27. package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
  28. package/dist/bindings/shared/dimensions.d.ts +1 -0
  29. package/dist/bindings/shared/index.d.ts +9 -0
  30. package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
  31. package/dist/bindings/shared/optionsSync.d.ts +7 -0
  32. package/dist/bindings/shared/seriesDiff.d.ts +8 -0
  33. package/dist/bindings/shared/stackedSync.d.ts +9 -0
  34. package/dist/bindings/shared/types.d.ts +46 -0
  35. package/dist/bindings/test-utils/index.d.ts +35 -0
  36. package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
  37. package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
  38. package/dist/chartSyncBridge-D_rCtbFq.js +58 -0
  39. package/dist/chartSyncBridge-D_rCtbFq.js.map +1 -0
  40. package/dist/core/Chart.d.ts +1 -1
  41. package/dist/core/ChartStatistics.d.ts +1 -1
  42. package/dist/core/InteractionManager.d.ts +7 -1
  43. package/dist/core/OverlayRenderer.d.ts +5 -0
  44. package/dist/core/annotations/types.d.ts +1 -1
  45. package/dist/core/chart/ChartCore.d.ts +14 -19
  46. package/dist/core/chart/ChartFeatureHooks.d.ts +7 -0
  47. package/dist/core/chart/chartExportPatch.d.ts +2 -0
  48. package/dist/core/chart/overlaySeriesRegistry.d.ts +7 -0
  49. package/dist/core/chart/series/SeriesActions.d.ts +1 -0
  50. package/dist/core/chart/series/SeriesBufferLite.d.ts +13 -0
  51. package/dist/core/chart/series/seriesOptionsRegistry.d.ts +8 -0
  52. package/dist/core/chart/series/seriesTypeRegistry.d.ts +5 -0
  53. package/dist/core/chart/types.d.ts +1 -1
  54. package/dist/core/clipboard/index.d.ts +1 -1
  55. package/dist/core/debug/index.d.ts +1 -1
  56. package/dist/core/keybindings/index.d.ts +1 -1
  57. package/dist/core/loading/index.d.ts +1 -1
  58. package/dist/core/locale/index.d.ts +1 -1
  59. package/dist/core/stacked/paneResize.d.ts +3 -0
  60. package/dist/core/stacked/types.d.ts +10 -0
  61. package/dist/core/theme-editor/index.d.ts +1 -1
  62. package/dist/createStackedChart-DqcLCFGS.js +1338 -0
  63. package/dist/createStackedChart-DqcLCFGS.js.map +1 -0
  64. package/dist/examples/PluginDemonstration.d.ts +1 -1
  65. package/dist/hooks-DH-3bewj.js +69 -0
  66. package/dist/hooks-DH-3bewj.js.map +1 -0
  67. package/dist/{index-BBpJwOct.js → index-0InEyj0q.js} +119 -121
  68. package/dist/index-0InEyj0q.js.map +1 -0
  69. package/dist/{index-qunX30Xu.js → index-B7PTX94B.js} +2133 -2133
  70. package/dist/index-B7PTX94B.js.map +1 -0
  71. package/dist/{index-BMiZoKmm.js → index-BgrvqltV.js} +67 -67
  72. package/dist/index-BgrvqltV.js.map +1 -0
  73. package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
  74. package/dist/index-CWxIHdwX.js.map +1 -0
  75. package/dist/index-CaXWSOTk.js.map +1 -1
  76. package/dist/{mockDatafeed-927foCM4.js → index-Cv6ZDLWf.js} +227 -217
  77. package/dist/index-Cv6ZDLWf.js.map +1 -0
  78. package/dist/index-Dag88bW4.js.map +1 -1
  79. package/dist/index-qhscKTDy.js.map +1 -1
  80. package/dist/index.core.d.ts +9 -7
  81. package/dist/index.d.ts +2 -15
  82. package/dist/indicators--eJGmVox.js.map +1 -1
  83. package/dist/optionsSync-QUiN4Inw.js +119 -0
  84. package/dist/optionsSync-QUiN4Inw.js.map +1 -0
  85. package/dist/plugins/3d/index.d.ts +2 -2
  86. package/dist/plugins/3d.d.ts +2 -2
  87. package/dist/plugins/3d.js +3 -1
  88. package/dist/plugins/3d.js.map +1 -1
  89. package/dist/plugins/analysis/index.d.ts +1 -1
  90. package/dist/plugins/analysis/indicators.d.ts +1 -1
  91. package/dist/plugins/analysis.d.ts +2 -2
  92. package/dist/plugins/analysis.js +2 -2
  93. package/dist/plugins/analysis.js.map +1 -1
  94. package/dist/plugins/annotations/index.d.ts +1 -1
  95. package/dist/plugins/annotations.d.ts +2 -2
  96. package/dist/plugins/annotations.js.map +1 -1
  97. package/dist/plugins/anomaly-detection.js +1 -1
  98. package/dist/plugins/anomaly-detection.js.map +1 -1
  99. package/dist/plugins/broken-axis.d.ts +2 -2
  100. package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
  101. package/dist/plugins/builtins/index.d.ts +1 -1
  102. package/dist/plugins/caching.d.ts +2 -2
  103. package/dist/plugins/clipboard/index.d.ts +2 -2
  104. package/dist/plugins/clipboard.d.ts +2 -2
  105. package/dist/plugins/clipboard.js.map +1 -1
  106. package/dist/plugins/context-menu/index.d.ts +1 -1
  107. package/dist/plugins/context-menu.d.ts +2 -2
  108. package/dist/plugins/context-menu.js +1 -1
  109. package/dist/plugins/context-menu.js.map +1 -1
  110. package/dist/plugins/createPlugin.d.ts +8 -0
  111. package/dist/plugins/data-export/index.d.ts +1 -1
  112. package/dist/plugins/data-export.d.ts +2 -2
  113. package/dist/plugins/data-export.js +2 -2
  114. package/dist/plugins/data-export.js.map +1 -1
  115. package/dist/plugins/data-transform.d.ts +2 -2
  116. package/dist/plugins/data-transform.js +19 -19
  117. package/dist/plugins/data-transform.js.map +1 -1
  118. package/dist/plugins/debug/index.d.ts +2 -2
  119. package/dist/plugins/debug.d.ts +2 -2
  120. package/dist/plugins/debug.js +33 -33
  121. package/dist/plugins/debug.js.map +1 -1
  122. package/dist/plugins/forecasting/index.d.ts +1 -1
  123. package/dist/plugins/forecasting.js.map +1 -1
  124. package/dist/plugins/gpu/index.d.ts +2 -2
  125. package/dist/plugins/gpu.d.ts +2 -2
  126. package/dist/plugins/gpu.js +2033 -209
  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 +286 -23
  131. package/dist/plugins/i18n.js.map +1 -1
  132. package/dist/plugins/index.d.ts +1 -1
  133. package/dist/plugins/keyboard.d.ts +2 -2
  134. package/dist/plugins/keyboard.js +65 -5
  135. package/dist/plugins/keyboard.js.map +1 -1
  136. package/dist/plugins/latex.js +766 -207
  137. package/dist/plugins/latex.js.map +1 -1
  138. package/dist/plugins/lazy-load.d.ts +2 -2
  139. package/dist/plugins/loading/index.d.ts +2 -3
  140. package/dist/plugins/loading.d.ts +2 -2
  141. package/dist/plugins/loading.js +3 -4
  142. package/dist/plugins/ml-integration.d.ts +2 -2
  143. package/dist/plugins/ml-integration.js +5 -5
  144. package/dist/plugins/ml-integration.js.map +1 -1
  145. package/dist/plugins/offscreen.d.ts +2 -2
  146. package/dist/plugins/offscreen.js +11 -10
  147. package/dist/plugins/offscreen.js.map +1 -1
  148. package/dist/plugins/pattern-recognition.d.ts +2 -2
  149. package/dist/plugins/pattern-recognition.js +1 -1
  150. package/dist/plugins/pattern-recognition.js.map +1 -1
  151. package/dist/plugins/radar.d.ts +2 -2
  152. package/dist/plugins/regression.d.ts +2 -2
  153. package/dist/plugins/regression.js +255 -257
  154. package/dist/plugins/regression.js.map +1 -1
  155. package/dist/plugins/roi.js +9 -9
  156. package/dist/plugins/roi.js.map +1 -1
  157. package/dist/plugins/snapshot/index.d.ts +1 -1
  158. package/dist/plugins/snapshot/types.d.ts +1 -1
  159. package/dist/plugins/snapshot.d.ts +2 -2
  160. package/dist/plugins/snapshot.js.map +1 -1
  161. package/dist/plugins/streaming/index.d.ts +2 -2
  162. package/dist/plugins/streaming.d.ts +2 -2
  163. package/dist/plugins/streaming.js +1 -1
  164. package/dist/plugins/sync/index.d.ts +3 -2
  165. package/dist/plugins/sync.d.ts +2 -2
  166. package/dist/plugins/sync.js.map +1 -1
  167. package/dist/plugins/theme-editor/index.d.ts +1 -1
  168. package/dist/plugins/theme-editor.d.ts +2 -2
  169. package/dist/plugins/tools/index.d.ts +1 -1
  170. package/dist/plugins/tools/tooltip/index.d.ts +1 -1
  171. package/dist/plugins/tools.d.ts +2 -2
  172. package/dist/plugins/tools.js +1 -1
  173. package/dist/plugins/types.d.ts +1 -1
  174. package/dist/plugins/video-recorder.d.ts +2 -2
  175. package/dist/plugins/virtualization.d.ts +2 -2
  176. package/dist/plugins/virtualization.js +1 -1
  177. package/dist/pool-DZ8shSqv.js +109 -0
  178. package/dist/pool-DZ8shSqv.js.map +1 -0
  179. package/dist/react/StackedPlot.d.ts +31 -0
  180. package/dist/react/VeloPlot.d.ts +29 -0
  181. package/dist/react/index.d.ts +25 -3
  182. package/dist/react/useChartSync.d.ts +8 -0
  183. package/dist/react/useIndicator.d.ts +12 -0
  184. package/dist/react/useVeloPlot.d.ts +19 -0
  185. package/dist/react.js +325 -24
  186. package/dist/react.js.map +1 -1
  187. package/dist/renderer/NativeWebGLRenderer.d.ts +2 -1
  188. package/dist/renderer/native/NativeWebGLRenderer.d.ts +5 -1
  189. package/dist/renderer/native/draw.d.ts +2 -47
  190. package/dist/renderer/native/drawCore.d.ts +27 -0
  191. package/dist/renderer/native/drawExtended.d.ts +29 -0
  192. package/dist/renderer/native/frameRenderExtended.d.ts +1 -0
  193. package/dist/renderer/native/frameRenderRegistry.d.ts +27 -0
  194. package/dist/renderer/native/programFactoryCore.d.ts +6 -0
  195. package/dist/renderer/native/programFactoryExtended.d.ts +4 -0
  196. package/dist/renderer/native/utils.d.ts +3 -29
  197. package/dist/renderer/native/utilsCore.d.ts +14 -0
  198. package/dist/renderer/native/utilsExtended.d.ts +17 -0
  199. package/dist/renderer/overlaySeriesExtended.d.ts +1 -0
  200. package/dist/renderer/registerExtendedSeries.d.ts +1 -0
  201. package/dist/renderer/registerWebGPU.d.ts +2 -0
  202. package/dist/renderer/seriesBufferExtended.d.ts +4 -0
  203. package/dist/scientific/index.d.ts +44 -0
  204. package/dist/scientific/registerScientific.d.ts +1 -0
  205. package/dist/scientific.d.ts +1 -0
  206. package/dist/scientific.js +91 -0
  207. package/dist/scientific.js.map +1 -0
  208. package/dist/solid/VeloPlot.d.ts +16 -0
  209. package/dist/solid/index.d.ts +13 -0
  210. package/dist/solid/useChartSync.d.ts +6 -0
  211. package/dist/solid/useIndicator.d.ts +11 -0
  212. package/dist/solid/useStackedPlot.d.ts +14 -0
  213. package/dist/solid/useVeloPlot.d.ts +18 -0
  214. package/dist/solid.d.ts +1 -0
  215. package/dist/solid.js +169 -0
  216. package/dist/solid.js.map +1 -0
  217. package/dist/stackedSync-tnrunZMt.js +100 -0
  218. package/dist/stackedSync-tnrunZMt.js.map +1 -0
  219. package/dist/svelte/StackedPlot.svelte +29 -0
  220. package/dist/svelte/StackedPlot.test.ts +114 -0
  221. package/dist/svelte/VeloPlot.svelte +44 -0
  222. package/dist/svelte/VeloPlot.test.ts +105 -0
  223. package/dist/svelte/index.d.ts +11 -0
  224. package/dist/svelte/index.test.ts +20 -0
  225. package/dist/svelte/index.ts +15 -0
  226. package/dist/svelte/useChartSync.d.ts +8 -0
  227. package/dist/svelte/useChartSync.test.ts +49 -0
  228. package/dist/svelte/useChartSync.ts +29 -0
  229. package/dist/svelte/useIndicator.d.ts +13 -0
  230. package/dist/svelte/useIndicator.test.ts +67 -0
  231. package/dist/svelte/useIndicator.ts +43 -0
  232. package/dist/svelte/useStackedPlot.d.ts +16 -0
  233. package/dist/svelte/useStackedPlot.test.ts +76 -0
  234. package/dist/svelte/useStackedPlot.ts +54 -0
  235. package/dist/svelte/useVeloPlot.d.ts +21 -0
  236. package/dist/svelte/useVeloPlot.test.ts +100 -0
  237. package/dist/svelte/useVeloPlot.ts +81 -0
  238. package/dist/svelte.d.ts +1 -0
  239. package/dist/svelte.js +140 -0
  240. package/dist/svelte.js.map +1 -0
  241. package/dist/testing/index.d.ts +1 -1
  242. package/dist/theme/index.d.ts +2 -1
  243. package/dist/trading/index.d.ts +1 -4
  244. package/dist/trading/registerTrading.d.ts +3 -0
  245. package/dist/trading.js +42 -42
  246. package/dist/types.d.ts +4 -4
  247. package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
  248. package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
  249. package/dist/velo-plot.full.js +2216 -1346
  250. package/dist/velo-plot.full.js.map +1 -1
  251. package/dist/velo-plot.js +33 -28
  252. package/dist/velo-plot.js.map +1 -1
  253. package/dist/vue/StackedPlot.vue.d.ts +48 -0
  254. package/dist/vue/VeloPlot.vue.d.ts +64 -0
  255. package/dist/vue/index.d.ts +250 -0
  256. package/dist/vue/useChartSync.d.ts +52 -0
  257. package/dist/vue/useIndicator.d.ts +23 -0
  258. package/dist/vue/useStackedPlot.d.ts +15 -0
  259. package/dist/vue/useVeloPlot.d.ts +20 -0
  260. package/dist/vue.d.ts +1 -0
  261. package/dist/vue.js +309 -0
  262. package/dist/vue.js.map +1 -0
  263. package/dist/workers/indicatorsAsync.d.ts +2 -0
  264. package/dist/workers/pool.d.ts +9 -0
  265. package/package.json +96 -10
  266. package/dist/ChartCore-ivzLqxVb.js +0 -8350
  267. package/dist/ChartCore-ivzLqxVb.js.map +0 -1
  268. package/dist/SciPlot-CEU4ApgD.js +0 -463
  269. package/dist/SciPlot-CEU4ApgD.js.map +0 -1
  270. package/dist/createStackedChart-DxNW0VkF.js +0 -705
  271. package/dist/createStackedChart-DxNW0VkF.js.map +0 -1
  272. package/dist/gpuRenderer-BpaMYz-k.js +0 -1848
  273. package/dist/gpuRenderer-BpaMYz-k.js.map +0 -1
  274. package/dist/index-BBpJwOct.js.map +0 -1
  275. package/dist/index-BMiZoKmm.js.map +0 -1
  276. package/dist/index-DoYxf1cV.js.map +0 -1
  277. package/dist/index-qunX30Xu.js.map +0 -1
  278. package/dist/index-x4stH3jD.js +0 -282
  279. package/dist/index-x4stH3jD.js.map +0 -1
  280. package/dist/index.core-COREBDNq.js.map +0 -1
  281. package/dist/mockDatafeed-927foCM4.js.map +0 -1
  282. package/dist/pool-15HMCNv8.js +0 -88
  283. package/dist/pool-15HMCNv8.js.map +0 -1
  284. package/dist/react/SciPlot.d.ts +0 -60
  285. package/dist/react/useSciPlot.d.ts +0 -56
  286. package/dist/symbols-DT0eLlpW.js +0 -568
  287. package/dist/symbols-DT0eLlpW.js.map +0 -1
@@ -137,7 +137,63 @@ function J(r) {
137
137
  getStats: () => ({ ...v, connectionUptime: T ? Date.now() - T : 0 })
138
138
  };
139
139
  }
140
- class I {
140
+ function X(r) {
141
+ const { interval: e = 100, generatePoint: s = I } = r;
142
+ let t = null, n = !1;
143
+ const i = /* @__PURE__ */ new Map(), a = {
144
+ messagesReceived: 0,
145
+ pointsProcessed: 0,
146
+ reconnectCount: 0,
147
+ lastMessageTime: null,
148
+ connectionUptime: 0,
149
+ bufferSize: 0
150
+ };
151
+ let l = null;
152
+ function f() {
153
+ t || (l = Date.now(), t = setInterval(() => {
154
+ const g = s();
155
+ a.messagesReceived++, a.pointsProcessed++, a.lastMessageTime = Date.now();
156
+ const u = g.seriesId || "default", d = i.get(u);
157
+ if (d)
158
+ for (const b of d)
159
+ b([g]);
160
+ }, e));
161
+ }
162
+ function c() {
163
+ t && (clearInterval(t), t = null), l = null;
164
+ }
165
+ return {
166
+ connect: () => {
167
+ n = !0, f();
168
+ },
169
+ disconnect: () => {
170
+ n = !1, c();
171
+ },
172
+ isConnected: () => n,
173
+ getState: () => n ? "connected" : "disconnected",
174
+ subscribe: (g, u) => (i.has(g) || i.set(g, /* @__PURE__ */ new Set()), i.get(g).add(u), () => {
175
+ var d;
176
+ (d = i.get(g)) == null || d.delete(u);
177
+ }),
178
+ unsubscribeAll: () => i.clear(),
179
+ send: () => {
180
+ },
181
+ getStats: () => ({
182
+ ...a,
183
+ connectionUptime: l ? Date.now() - l : 0
184
+ }),
185
+ start: f,
186
+ stop: c
187
+ };
188
+ }
189
+ let z = 0;
190
+ function I() {
191
+ return {
192
+ x: z++,
193
+ y: Math.sin(z * 0.1) + Math.random() * 0.2
194
+ };
195
+ }
196
+ class W {
141
197
  constructor(e) {
142
198
  h(this, "buffer");
143
199
  h(this, "head", 0);
@@ -260,7 +316,7 @@ class x {
260
316
  */
261
317
  push(e, s) {
262
318
  var l, f;
263
- this.buffers.has(e) || (this.buffers.set(e, new I(this.config.maxBuffer)), this.stats.set(e, { dropped: 0, sampled: 0, lastIncoming: 0, lastOutgoing: 0 }));
319
+ this.buffers.has(e) || (this.buffers.set(e, new W(this.config.maxBuffer)), this.stats.set(e, { dropped: 0, sampled: 0, lastIncoming: 0, lastOutgoing: 0 }));
264
320
  const t = this.buffers.get(e), n = this.stats.get(e);
265
321
  let i = 0, a = 0;
266
322
  for (const c of s)
@@ -430,10 +486,10 @@ class x {
430
486
  return e.length === 0 ? 0 : e.reduce((s, t) => s + t, 0) / e.length;
431
487
  }
432
488
  }
433
- function X(r = 1e4, e = "drop-oldest") {
489
+ function $(r = 1e4, e = "drop-oldest") {
434
490
  return new x({ maxBuffer: r, strategy: e });
435
491
  }
436
- function $(r = 5e4) {
492
+ function q(r = 5e4) {
437
493
  return new x({
438
494
  maxBuffer: r,
439
495
  strategy: "drop-oldest",
@@ -441,7 +497,7 @@ function $(r = 5e4) {
441
497
  criticalThreshold: 0.95
442
498
  });
443
499
  }
444
- function q(r = 1e5) {
500
+ function K(r = 1e5) {
445
501
  return new x({
446
502
  maxBuffer: r,
447
503
  strategy: "pause",
@@ -449,62 +505,6 @@ function q(r = 1e5) {
449
505
  criticalThreshold: 0.8
450
506
  });
451
507
  }
452
- function K(r) {
453
- const { interval: e = 100, generatePoint: s = W } = r;
454
- let t = null, n = !1;
455
- const i = /* @__PURE__ */ new Map(), a = {
456
- messagesReceived: 0,
457
- pointsProcessed: 0,
458
- reconnectCount: 0,
459
- lastMessageTime: null,
460
- connectionUptime: 0,
461
- bufferSize: 0
462
- };
463
- let l = null;
464
- function f() {
465
- t || (l = Date.now(), t = setInterval(() => {
466
- const g = s();
467
- a.messagesReceived++, a.pointsProcessed++, a.lastMessageTime = Date.now();
468
- const u = g.seriesId || "default", d = i.get(u);
469
- if (d)
470
- for (const b of d)
471
- b([g]);
472
- }, e));
473
- }
474
- function c() {
475
- t && (clearInterval(t), t = null), l = null;
476
- }
477
- return {
478
- connect: () => {
479
- n = !0, f();
480
- },
481
- disconnect: () => {
482
- n = !1, c();
483
- },
484
- isConnected: () => n,
485
- getState: () => n ? "connected" : "disconnected",
486
- subscribe: (g, u) => (i.has(g) || i.set(g, /* @__PURE__ */ new Set()), i.get(g).add(u), () => {
487
- var d;
488
- (d = i.get(g)) == null || d.delete(u);
489
- }),
490
- unsubscribeAll: () => i.clear(),
491
- send: () => {
492
- },
493
- getStats: () => ({
494
- ...a,
495
- connectionUptime: l ? Date.now() - l : 0
496
- }),
497
- start: f,
498
- stop: c
499
- };
500
- }
501
- let z = 0;
502
- function W() {
503
- return {
504
- x: z++,
505
- y: Math.sin(z * 0.1) + Math.random() * 0.2
506
- };
507
- }
508
508
  const G = {
509
509
  name: "velo-plot-streaming",
510
510
  version: "1.0.0",
@@ -523,14 +523,14 @@ function Q(r = {}) {
523
523
  }
524
524
  export {
525
525
  x as B,
526
- I as C,
526
+ W as C,
527
527
  Q as P,
528
528
  E as a,
529
529
  _ as b,
530
530
  J as c,
531
- K as d,
532
- X as e,
533
- $ as f,
534
- q as g
531
+ X as d,
532
+ $ as e,
533
+ q as f,
534
+ K as g
535
535
  };
536
- //# sourceMappingURL=index-BMiZoKmm.js.map
536
+ //# sourceMappingURL=index-BgrvqltV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BgrvqltV.js","sources":["../src/streaming/utils.ts","../src/streaming/websocket.ts","../src/streaming/mock.ts","../src/streaming/backpressure.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 * 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 - 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 * 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","createMockStream","interval","generatePoint","defaultGenerator","intervalId","connected","startTime","start","stop","_a","mockX","CircularBuffer","capacity","__publicField","overwritten","n","result","toRemove","i","current","BackpressureManager","_b","added","dropped","count","toConsume","fillLevel","totalSize","totalDropped","totalSampled","maxTotal","recommendations","score","dropRate","status","now","history","a","createBackpressureManager","maxBuffer","strategy","createRealtimeBackpressure","createLosslessBackpressure","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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CWxIHdwX.js","sources":["../src/core/keybindings/index.ts"],"sourcesContent":["/**\n * Velo Plot - Keyboard Shortcuts Module\n * \n * Provides customizable keyboard shortcuts for chart interactions.\n * Supports key combinations, custom actions, and enable/disable per key.\n * \n * @module keybindings\n */\n\n// ============================================\n// Types\n// ============================================\n\n/** Available built-in actions */\nexport type KeyAction =\n | 'resetZoom'\n | 'autoScale'\n | 'zoomIn'\n | 'zoomOut'\n | 'panLeft'\n | 'panRight'\n | 'panUp'\n | 'panDown'\n | 'togglePan'\n | 'toggleSelect'\n | 'clearSelection'\n | 'deleteSelected'\n | 'selectAll'\n | 'copy'\n | 'exportImage'\n | 'toggleLegend'\n | 'toggleDebug'\n | 'escape'\n | 'undo'\n | 'redo'\n | 'custom';\n\n/** Key binding configuration */\nexport interface KeyBinding {\n /** The key code (e.g., 'KeyR', 'Escape', 'ArrowLeft') */\n key: string;\n /** Action to perform */\n action: KeyAction;\n /** Require Ctrl/Cmd key */\n ctrl?: boolean;\n /** Require Shift key */\n shift?: boolean;\n /** Require Alt key */\n alt?: boolean;\n /** Require Meta key (Cmd on Mac) */\n meta?: boolean;\n /** Custom handler function (required if action is 'custom') */\n handler?: () => void;\n /** Whether this binding is enabled (default: true) */\n enabled?: boolean;\n /** Description for help/UI display */\n description?: string;\n}\n\n/** Callbacks for keyboard actions */\nexport interface KeyBindingCallbacks {\n onResetZoom?: () => void;\n onAutoScale?: () => void;\n onZoomIn?: () => void;\n onZoomOut?: () => void;\n onPanLeft?: () => void;\n onPanRight?: () => void;\n onPanUp?: () => void;\n onPanDown?: () => void;\n onTogglePan?: () => void;\n onToggleSelect?: () => void;\n onClearSelection?: () => void;\n onDeleteSelected?: () => void;\n onSelectAll?: () => void;\n onCopy?: () => void;\n onExportImage?: () => void;\n onToggleLegend?: () => void;\n onToggleDebug?: () => void;\n onEscape?: () => void;\n onUndo?: () => void;\n onRedo?: () => void;\n}\n\nexport interface KeyBindingManagerOptions {\n /** Enable keyboard shortcuts (default: true) */\n enabled?: boolean;\n /** Custom key bindings (merged with defaults) */\n bindings?: KeyBinding[];\n /** Override all default bindings (replace instead of merge) */\n replaceDefaults?: boolean;\n /** Callbacks for built-in actions */\n callbacks: KeyBindingCallbacks;\n /** Target element for keyboard events (default: document) */\n target?: HTMLElement | Document;\n /** Prevent default browser behavior for matched keys (default: true) */\n preventDefault?: boolean;\n}\n\n// ============================================\n// Default Key Bindings\n// ============================================\n\nexport const DEFAULT_KEY_BINDINGS: KeyBinding[] = [\n // Zoom/Scale\n { key: 'KeyR', action: 'resetZoom', description: 'Reset zoom to fit data' },\n { key: 'KeyH', action: 'autoScale', description: 'Auto-scale axes' },\n { key: 'Equal', action: 'zoomIn', ctrl: true, description: 'Zoom in' },\n { key: 'Minus', action: 'zoomOut', ctrl: true, description: 'Zoom out' },\n { key: 'Digit0', action: 'resetZoom', ctrl: true, description: 'Reset zoom' },\n \n // Pan (Arrow keys)\n { key: 'ArrowLeft', action: 'panLeft', description: 'Pan left' },\n { key: 'ArrowRight', action: 'panRight', description: 'Pan right' },\n { key: 'ArrowUp', action: 'panUp', description: 'Pan up' },\n { key: 'ArrowDown', action: 'panDown', description: 'Pan down' },\n \n // Mode toggles\n { key: 'KeyP', action: 'togglePan', description: 'Toggle pan mode' },\n { key: 'KeyS', action: 'toggleSelect', description: 'Toggle select mode' },\n \n // Selection\n { key: 'Escape', action: 'escape', description: 'Clear selection / Cancel' },\n { key: 'Delete', action: 'deleteSelected', description: 'Delete selected points' },\n { key: 'Backspace', action: 'deleteSelected', description: 'Delete selected points' },\n { key: 'KeyA', action: 'selectAll', ctrl: true, description: 'Select all points' },\n \n // Clipboard\n { key: 'KeyC', action: 'copy', ctrl: true, description: 'Copy selected to clipboard' },\n \n // Export\n { key: 'KeyE', action: 'exportImage', ctrl: true, description: 'Export chart as image' },\n \n // UI toggles\n { key: 'KeyL', action: 'toggleLegend', description: 'Toggle legend visibility' },\n { key: 'KeyD', action: 'toggleDebug', ctrl: true, shift: true, description: 'Toggle debug overlay' },\n \n // Undo/Redo\n { key: 'KeyZ', action: 'undo', ctrl: true, description: 'Undo' },\n { key: 'KeyZ', action: 'redo', ctrl: true, shift: true, description: 'Redo' },\n { key: 'KeyY', action: 'redo', ctrl: true, description: 'Redo' },\n];\n\n// ============================================\n// Key Binding Manager\n// ============================================\n\nexport class KeyBindingManager {\n private bindings: KeyBinding[] = [];\n private callbacks: KeyBindingCallbacks;\n private target: HTMLElement | Document;\n private enabled: boolean = true;\n private preventDefault: boolean = true;\n private boundHandler: (e: KeyboardEvent) => void;\n\n constructor(options: KeyBindingManagerOptions) {\n this.callbacks = options.callbacks;\n this.target = options.target || document;\n this.enabled = options.enabled !== false;\n this.preventDefault = options.preventDefault !== false;\n\n // Merge or replace bindings\n if (options.replaceDefaults) {\n this.bindings = [...(options.bindings || [])];\n } else {\n this.bindings = [...DEFAULT_KEY_BINDINGS, ...(options.bindings || [])];\n }\n\n // Bind handler\n this.boundHandler = this.handleKeyDown.bind(this);\n this.attach();\n }\n\n /**\n * Attach keyboard event listeners\n */\n attach(): void {\n this.target.addEventListener('keydown', this.boundHandler as EventListener);\n }\n\n /**\n * Detach keyboard event listeners\n */\n detach(): void {\n this.target.removeEventListener('keydown', this.boundHandler as EventListener);\n }\n\n /**\n * Enable/disable all keyboard shortcuts\n */\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /**\n * Check if keyboard shortcuts are enabled\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Add a custom key binding\n */\n addBinding(binding: KeyBinding): void {\n this.bindings.push(binding);\n }\n\n /**\n * Remove a key binding by key code\n */\n removeBinding(key: string, modifiers?: { ctrl?: boolean; shift?: boolean; alt?: boolean }): void {\n this.bindings = this.bindings.filter(b => {\n if (b.key !== key) return true;\n if (modifiers) {\n if (modifiers.ctrl !== undefined && b.ctrl !== modifiers.ctrl) return true;\n if (modifiers.shift !== undefined && b.shift !== modifiers.shift) return true;\n if (modifiers.alt !== undefined && b.alt !== modifiers.alt) return true;\n }\n return false;\n });\n }\n\n /**\n * Update an existing binding\n */\n updateBinding(key: string, updates: Partial<KeyBinding>): void {\n const binding = this.bindings.find(b => b.key === key);\n if (binding) {\n Object.assign(binding, updates);\n }\n }\n\n /**\n * Enable/disable a specific binding\n */\n setBindingEnabled(key: string, enabled: boolean): void {\n const binding = this.bindings.find(b => b.key === key);\n if (binding) {\n binding.enabled = enabled;\n }\n }\n\n /**\n * Get all current bindings\n */\n getBindings(): KeyBinding[] {\n return [...this.bindings];\n }\n\n /**\n * Get binding for a specific key\n */\n getBinding(key: string): KeyBinding | undefined {\n return this.bindings.find(b => b.key === key);\n }\n\n /**\n * Get a formatted list of all shortcuts (for help display)\n */\n getShortcutList(): { key: string; description: string }[] {\n return this.bindings\n .filter(b => b.enabled !== false && b.description)\n .map(b => ({\n key: this.formatKeyBinding(b),\n description: b.description || b.action,\n }));\n }\n\n /**\n * Format a key binding for display\n */\n formatKeyBinding(binding: KeyBinding): string {\n const parts: string[] = [];\n if (binding.ctrl) parts.push('Ctrl');\n if (binding.alt) parts.push('Alt');\n if (binding.shift) parts.push('Shift');\n if (binding.meta) parts.push('⌘');\n \n // Convert key code to display name\n let keyName = binding.key;\n if (keyName.startsWith('Key')) {\n keyName = keyName.slice(3);\n } else if (keyName.startsWith('Digit')) {\n keyName = keyName.slice(5);\n } else if (keyName === 'Equal') {\n keyName = '+';\n } else if (keyName === 'Minus') {\n keyName = '-';\n } else if (keyName.startsWith('Arrow')) {\n keyName = '←→↑↓'['LeftRightUpDown'.indexOf(keyName.slice(5)) / 5 | 0] || keyName;\n }\n \n parts.push(keyName);\n return parts.join('+');\n }\n\n /**\n * Handle keydown events\n */\n private handleKeyDown(e: KeyboardEvent): void {\n if (!this.enabled) return;\n\n // Skip if typing in an input element\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n // Find matching binding\n const binding = this.findMatchingBinding(e);\n if (!binding || binding.enabled === false) return;\n\n // Execute action\n const executed = this.executeAction(binding);\n \n if (executed && this.preventDefault) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n /**\n * Find a binding that matches the current key event\n */\n private findMatchingBinding(e: KeyboardEvent): KeyBinding | undefined {\n return this.bindings.find(b => {\n if (b.key !== e.code) return false;\n if (b.ctrl && !e.ctrlKey && !e.metaKey) return false;\n if (b.shift && !e.shiftKey) return false;\n if (b.alt && !e.altKey) return false;\n if (b.meta && !e.metaKey) return false;\n \n // Also check that extra modifiers aren't pressed\n if (!b.ctrl && (e.ctrlKey || e.metaKey)) return false;\n if (!b.shift && e.shiftKey) return false;\n if (!b.alt && e.altKey) return false;\n \n return true;\n });\n }\n\n /**\n * Execute the action for a binding\n */\n private executeAction(binding: KeyBinding): boolean {\n const { action, handler } = binding;\n\n switch (action) {\n case 'resetZoom':\n this.callbacks.onResetZoom?.();\n return true;\n case 'autoScale':\n this.callbacks.onAutoScale?.();\n return true;\n case 'zoomIn':\n this.callbacks.onZoomIn?.();\n return true;\n case 'zoomOut':\n this.callbacks.onZoomOut?.();\n return true;\n case 'panLeft':\n this.callbacks.onPanLeft?.();\n return true;\n case 'panRight':\n this.callbacks.onPanRight?.();\n return true;\n case 'panUp':\n this.callbacks.onPanUp?.();\n return true;\n case 'panDown':\n this.callbacks.onPanDown?.();\n return true;\n case 'togglePan':\n this.callbacks.onTogglePan?.();\n return true;\n case 'toggleSelect':\n this.callbacks.onToggleSelect?.();\n return true;\n case 'clearSelection':\n case 'escape':\n this.callbacks.onEscape?.();\n this.callbacks.onClearSelection?.();\n return true;\n case 'deleteSelected':\n this.callbacks.onDeleteSelected?.();\n return true;\n case 'selectAll':\n this.callbacks.onSelectAll?.();\n return true;\n case 'copy':\n this.callbacks.onCopy?.();\n return true;\n case 'exportImage':\n this.callbacks.onExportImage?.();\n return true;\n case 'toggleLegend':\n this.callbacks.onToggleLegend?.();\n return true;\n case 'toggleDebug':\n this.callbacks.onToggleDebug?.();\n return true;\n case 'undo':\n this.callbacks.onUndo?.();\n return true;\n case 'redo':\n this.callbacks.onRedo?.();\n return true;\n case 'custom':\n handler?.();\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Destroy the manager and cleanup\n */\n destroy(): void {\n this.detach();\n this.bindings = [];\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a simple key binding configuration\n */\nexport function createKeyBinding(\n key: string,\n action: KeyAction,\n options?: Partial<KeyBinding>\n): KeyBinding {\n return {\n key,\n action,\n ...options,\n };\n}\n\n/**\n * Parse a shortcut string (e.g., \"Ctrl+R\") into a KeyBinding\n */\nexport function parseShortcut(shortcut: string, action: KeyAction): KeyBinding {\n const parts = shortcut.split('+').map(p => p.trim().toLowerCase());\n const binding: KeyBinding = {\n key: '',\n action,\n ctrl: false,\n shift: false,\n alt: false,\n meta: false,\n };\n\n for (const part of parts) {\n switch (part) {\n case 'ctrl':\n case 'control':\n binding.ctrl = true;\n break;\n case 'shift':\n binding.shift = true;\n break;\n case 'alt':\n binding.alt = true;\n break;\n case 'meta':\n case 'cmd':\n case 'command':\n binding.meta = true;\n break;\n default:\n // Convert to key code\n if (part.length === 1) {\n if (/[a-z]/i.test(part)) {\n binding.key = 'Key' + part.toUpperCase();\n } else if (/[0-9]/.test(part)) {\n binding.key = 'Digit' + part;\n } else if (part === '+') {\n binding.key = 'Equal';\n } else if (part === '-') {\n binding.key = 'Minus';\n }\n } else {\n // Handle special keys\n const specialKeys: Record<string, string> = {\n 'escape': 'Escape',\n 'esc': 'Escape',\n 'enter': 'Enter',\n 'return': 'Enter',\n 'space': 'Space',\n 'tab': 'Tab',\n 'delete': 'Delete',\n 'backspace': 'Backspace',\n 'left': 'ArrowLeft',\n 'right': 'ArrowRight',\n 'up': 'ArrowUp',\n 'down': 'ArrowDown',\n };\n binding.key = specialKeys[part] || part;\n }\n }\n }\n\n return binding;\n}\n"],"names":["DEFAULT_KEY_BINDINGS","KeyBindingManager","options","__publicField","enabled","binding","key","modifiers","b","updates","parts","keyName","target","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z","_A","_B","_C","_D","_E","_F","_G","_H","_I","_J","_K","_L","_M","_N","action","handler","createKeyBinding","parseShortcut","shortcut","p","part","specialKeys"],"mappings":"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"}