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.
- package/README.md +26 -12
- package/dist/ChartCore-AnR_3Xkb.js +7338 -0
- package/dist/ChartCore-AnR_3Xkb.js.map +1 -0
- package/dist/GpuChartRenderer-Dxc0hrQA.js +75 -0
- package/dist/GpuChartRenderer-Dxc0hrQA.js.map +1 -0
- package/dist/{index.core-COREBDNq.js → PluginRegistry-CzMHebYP.js} +24 -38
- package/dist/PluginRegistry-CzMHebYP.js.map +1 -0
- package/dist/a11y-Bw6urYpr.js +105 -0
- package/dist/a11y-Bw6urYpr.js.map +1 -0
- package/dist/angular/hooks-entry.d.ts +1 -0
- package/dist/angular/hooks.d.ts +26 -0
- package/dist/angular/index.d.ts +8 -0
- package/dist/angular/velo-plot.component.d.ts +46 -0
- package/dist/angular-hooks.d.ts +1 -0
- package/dist/angular-hooks.js +9 -0
- package/dist/angular-hooks.js.map +1 -0
- package/dist/angular.d.ts +1 -0
- package/dist/angular.js +166 -0
- package/dist/angular.js.map +1 -0
- package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
- package/dist/astro/StackedPlot.astro +19 -0
- package/dist/astro/VeloPlot.astro +23 -0
- package/dist/{axisFormat-CzumxpCL.js → axisFormat-Sz4WIJfQ.js} +2 -2
- package/dist/{axisFormat-CzumxpCL.js.map → axisFormat-Sz4WIJfQ.js.map} +1 -1
- package/dist/bindings/shared/a11y.d.ts +26 -0
- package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
- package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
- package/dist/bindings/shared/dimensions.d.ts +1 -0
- package/dist/bindings/shared/index.d.ts +9 -0
- package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
- package/dist/bindings/shared/optionsSync.d.ts +7 -0
- package/dist/bindings/shared/seriesDiff.d.ts +8 -0
- package/dist/bindings/shared/stackedSync.d.ts +9 -0
- package/dist/bindings/shared/types.d.ts +46 -0
- package/dist/bindings/test-utils/index.d.ts +35 -0
- package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
- package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
- package/dist/chartSyncBridge-D_rCtbFq.js +58 -0
- package/dist/chartSyncBridge-D_rCtbFq.js.map +1 -0
- package/dist/core/Chart.d.ts +1 -1
- package/dist/core/ChartStatistics.d.ts +1 -1
- package/dist/core/InteractionManager.d.ts +7 -1
- package/dist/core/OverlayRenderer.d.ts +5 -0
- package/dist/core/annotations/types.d.ts +1 -1
- package/dist/core/chart/ChartCore.d.ts +14 -19
- package/dist/core/chart/ChartFeatureHooks.d.ts +7 -0
- package/dist/core/chart/chartExportPatch.d.ts +2 -0
- package/dist/core/chart/overlaySeriesRegistry.d.ts +7 -0
- package/dist/core/chart/series/SeriesActions.d.ts +1 -0
- package/dist/core/chart/series/SeriesBufferLite.d.ts +13 -0
- package/dist/core/chart/series/seriesOptionsRegistry.d.ts +8 -0
- package/dist/core/chart/series/seriesTypeRegistry.d.ts +5 -0
- package/dist/core/chart/types.d.ts +1 -1
- package/dist/core/clipboard/index.d.ts +1 -1
- package/dist/core/debug/index.d.ts +1 -1
- package/dist/core/keybindings/index.d.ts +1 -1
- package/dist/core/loading/index.d.ts +1 -1
- package/dist/core/locale/index.d.ts +1 -1
- package/dist/core/stacked/paneResize.d.ts +3 -0
- package/dist/core/stacked/types.d.ts +10 -0
- package/dist/core/theme-editor/index.d.ts +1 -1
- package/dist/createStackedChart-DqcLCFGS.js +1338 -0
- package/dist/createStackedChart-DqcLCFGS.js.map +1 -0
- package/dist/examples/PluginDemonstration.d.ts +1 -1
- package/dist/hooks-DH-3bewj.js +69 -0
- package/dist/hooks-DH-3bewj.js.map +1 -0
- package/dist/{index-BBpJwOct.js → index-0InEyj0q.js} +119 -121
- package/dist/index-0InEyj0q.js.map +1 -0
- package/dist/{index-qunX30Xu.js → index-B7PTX94B.js} +2133 -2133
- package/dist/index-B7PTX94B.js.map +1 -0
- package/dist/{index-BMiZoKmm.js → index-BgrvqltV.js} +67 -67
- package/dist/index-BgrvqltV.js.map +1 -0
- package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
- package/dist/index-CWxIHdwX.js.map +1 -0
- package/dist/index-CaXWSOTk.js.map +1 -1
- package/dist/{mockDatafeed-927foCM4.js → index-Cv6ZDLWf.js} +227 -217
- package/dist/index-Cv6ZDLWf.js.map +1 -0
- package/dist/index-Dag88bW4.js.map +1 -1
- package/dist/index-qhscKTDy.js.map +1 -1
- package/dist/index.core.d.ts +9 -7
- package/dist/index.d.ts +2 -15
- package/dist/indicators--eJGmVox.js.map +1 -1
- package/dist/optionsSync-QUiN4Inw.js +119 -0
- package/dist/optionsSync-QUiN4Inw.js.map +1 -0
- package/dist/plugins/3d/index.d.ts +2 -2
- package/dist/plugins/3d.d.ts +2 -2
- package/dist/plugins/3d.js +3 -1
- package/dist/plugins/3d.js.map +1 -1
- package/dist/plugins/analysis/index.d.ts +1 -1
- package/dist/plugins/analysis/indicators.d.ts +1 -1
- package/dist/plugins/analysis.d.ts +2 -2
- package/dist/plugins/analysis.js +2 -2
- package/dist/plugins/analysis.js.map +1 -1
- package/dist/plugins/annotations/index.d.ts +1 -1
- package/dist/plugins/annotations.d.ts +2 -2
- package/dist/plugins/annotations.js.map +1 -1
- package/dist/plugins/anomaly-detection.js +1 -1
- package/dist/plugins/anomaly-detection.js.map +1 -1
- package/dist/plugins/broken-axis.d.ts +2 -2
- package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
- package/dist/plugins/builtins/index.d.ts +1 -1
- package/dist/plugins/caching.d.ts +2 -2
- package/dist/plugins/clipboard/index.d.ts +2 -2
- package/dist/plugins/clipboard.d.ts +2 -2
- package/dist/plugins/clipboard.js.map +1 -1
- package/dist/plugins/context-menu/index.d.ts +1 -1
- package/dist/plugins/context-menu.d.ts +2 -2
- package/dist/plugins/context-menu.js +1 -1
- package/dist/plugins/context-menu.js.map +1 -1
- package/dist/plugins/createPlugin.d.ts +8 -0
- package/dist/plugins/data-export/index.d.ts +1 -1
- package/dist/plugins/data-export.d.ts +2 -2
- package/dist/plugins/data-export.js +2 -2
- package/dist/plugins/data-export.js.map +1 -1
- package/dist/plugins/data-transform.d.ts +2 -2
- package/dist/plugins/data-transform.js +19 -19
- package/dist/plugins/data-transform.js.map +1 -1
- package/dist/plugins/debug/index.d.ts +2 -2
- package/dist/plugins/debug.d.ts +2 -2
- package/dist/plugins/debug.js +33 -33
- package/dist/plugins/debug.js.map +1 -1
- package/dist/plugins/forecasting/index.d.ts +1 -1
- package/dist/plugins/forecasting.js.map +1 -1
- package/dist/plugins/gpu/index.d.ts +2 -2
- package/dist/plugins/gpu.d.ts +2 -2
- package/dist/plugins/gpu.js +2033 -209
- package/dist/plugins/gpu.js.map +1 -1
- package/dist/plugins/i18n/index.d.ts +2 -2
- package/dist/plugins/i18n.d.ts +2 -2
- package/dist/plugins/i18n.js +286 -23
- package/dist/plugins/i18n.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/keyboard.d.ts +2 -2
- package/dist/plugins/keyboard.js +65 -5
- package/dist/plugins/keyboard.js.map +1 -1
- package/dist/plugins/latex.js +766 -207
- package/dist/plugins/latex.js.map +1 -1
- package/dist/plugins/lazy-load.d.ts +2 -2
- package/dist/plugins/loading/index.d.ts +2 -3
- package/dist/plugins/loading.d.ts +2 -2
- package/dist/plugins/loading.js +3 -4
- package/dist/plugins/ml-integration.d.ts +2 -2
- package/dist/plugins/ml-integration.js +5 -5
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/offscreen.d.ts +2 -2
- package/dist/plugins/offscreen.js +11 -10
- package/dist/plugins/offscreen.js.map +1 -1
- package/dist/plugins/pattern-recognition.d.ts +2 -2
- package/dist/plugins/pattern-recognition.js +1 -1
- package/dist/plugins/pattern-recognition.js.map +1 -1
- package/dist/plugins/radar.d.ts +2 -2
- package/dist/plugins/regression.d.ts +2 -2
- package/dist/plugins/regression.js +255 -257
- package/dist/plugins/regression.js.map +1 -1
- package/dist/plugins/roi.js +9 -9
- package/dist/plugins/roi.js.map +1 -1
- package/dist/plugins/snapshot/index.d.ts +1 -1
- package/dist/plugins/snapshot/types.d.ts +1 -1
- package/dist/plugins/snapshot.d.ts +2 -2
- package/dist/plugins/snapshot.js.map +1 -1
- package/dist/plugins/streaming/index.d.ts +2 -2
- package/dist/plugins/streaming.d.ts +2 -2
- package/dist/plugins/streaming.js +1 -1
- package/dist/plugins/sync/index.d.ts +3 -2
- package/dist/plugins/sync.d.ts +2 -2
- package/dist/plugins/sync.js.map +1 -1
- package/dist/plugins/theme-editor/index.d.ts +1 -1
- package/dist/plugins/theme-editor.d.ts +2 -2
- package/dist/plugins/tools/index.d.ts +1 -1
- package/dist/plugins/tools/tooltip/index.d.ts +1 -1
- package/dist/plugins/tools.d.ts +2 -2
- package/dist/plugins/tools.js +1 -1
- package/dist/plugins/types.d.ts +1 -1
- package/dist/plugins/video-recorder.d.ts +2 -2
- package/dist/plugins/virtualization.d.ts +2 -2
- package/dist/plugins/virtualization.js +1 -1
- package/dist/pool-DZ8shSqv.js +109 -0
- package/dist/pool-DZ8shSqv.js.map +1 -0
- package/dist/react/StackedPlot.d.ts +31 -0
- package/dist/react/VeloPlot.d.ts +29 -0
- package/dist/react/index.d.ts +25 -3
- package/dist/react/useChartSync.d.ts +8 -0
- package/dist/react/useIndicator.d.ts +12 -0
- package/dist/react/useVeloPlot.d.ts +19 -0
- package/dist/react.js +325 -24
- package/dist/react.js.map +1 -1
- package/dist/renderer/NativeWebGLRenderer.d.ts +2 -1
- package/dist/renderer/native/NativeWebGLRenderer.d.ts +5 -1
- package/dist/renderer/native/draw.d.ts +2 -47
- package/dist/renderer/native/drawCore.d.ts +27 -0
- package/dist/renderer/native/drawExtended.d.ts +29 -0
- package/dist/renderer/native/frameRenderExtended.d.ts +1 -0
- package/dist/renderer/native/frameRenderRegistry.d.ts +27 -0
- package/dist/renderer/native/programFactoryCore.d.ts +6 -0
- package/dist/renderer/native/programFactoryExtended.d.ts +4 -0
- package/dist/renderer/native/utils.d.ts +3 -29
- package/dist/renderer/native/utilsCore.d.ts +14 -0
- package/dist/renderer/native/utilsExtended.d.ts +17 -0
- package/dist/renderer/overlaySeriesExtended.d.ts +1 -0
- package/dist/renderer/registerExtendedSeries.d.ts +1 -0
- package/dist/renderer/registerWebGPU.d.ts +2 -0
- package/dist/renderer/seriesBufferExtended.d.ts +4 -0
- package/dist/scientific/index.d.ts +44 -0
- package/dist/scientific/registerScientific.d.ts +1 -0
- package/dist/scientific.d.ts +1 -0
- package/dist/scientific.js +91 -0
- package/dist/scientific.js.map +1 -0
- package/dist/solid/VeloPlot.d.ts +16 -0
- package/dist/solid/index.d.ts +13 -0
- package/dist/solid/useChartSync.d.ts +6 -0
- package/dist/solid/useIndicator.d.ts +11 -0
- package/dist/solid/useStackedPlot.d.ts +14 -0
- package/dist/solid/useVeloPlot.d.ts +18 -0
- package/dist/solid.d.ts +1 -0
- package/dist/solid.js +169 -0
- package/dist/solid.js.map +1 -0
- package/dist/stackedSync-tnrunZMt.js +100 -0
- package/dist/stackedSync-tnrunZMt.js.map +1 -0
- package/dist/svelte/StackedPlot.svelte +29 -0
- package/dist/svelte/StackedPlot.test.ts +114 -0
- package/dist/svelte/VeloPlot.svelte +44 -0
- package/dist/svelte/VeloPlot.test.ts +105 -0
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.test.ts +20 -0
- package/dist/svelte/index.ts +15 -0
- package/dist/svelte/useChartSync.d.ts +8 -0
- package/dist/svelte/useChartSync.test.ts +49 -0
- package/dist/svelte/useChartSync.ts +29 -0
- package/dist/svelte/useIndicator.d.ts +13 -0
- package/dist/svelte/useIndicator.test.ts +67 -0
- package/dist/svelte/useIndicator.ts +43 -0
- package/dist/svelte/useStackedPlot.d.ts +16 -0
- package/dist/svelte/useStackedPlot.test.ts +76 -0
- package/dist/svelte/useStackedPlot.ts +54 -0
- package/dist/svelte/useVeloPlot.d.ts +21 -0
- package/dist/svelte/useVeloPlot.test.ts +100 -0
- package/dist/svelte/useVeloPlot.ts +81 -0
- package/dist/svelte.d.ts +1 -0
- package/dist/svelte.js +140 -0
- package/dist/svelte.js.map +1 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/theme/index.d.ts +2 -1
- package/dist/trading/index.d.ts +1 -4
- package/dist/trading/registerTrading.d.ts +3 -0
- package/dist/trading.js +42 -42
- package/dist/types.d.ts +4 -4
- package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
- package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
- package/dist/velo-plot.full.js +2216 -1346
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +33 -28
- package/dist/velo-plot.js.map +1 -1
- package/dist/vue/StackedPlot.vue.d.ts +48 -0
- package/dist/vue/VeloPlot.vue.d.ts +64 -0
- package/dist/vue/index.d.ts +250 -0
- package/dist/vue/useChartSync.d.ts +52 -0
- package/dist/vue/useIndicator.d.ts +23 -0
- package/dist/vue/useStackedPlot.d.ts +15 -0
- package/dist/vue/useVeloPlot.d.ts +20 -0
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +309 -0
- package/dist/vue.js.map +1 -0
- package/dist/workers/indicatorsAsync.d.ts +2 -0
- package/dist/workers/pool.d.ts +9 -0
- package/package.json +96 -10
- package/dist/ChartCore-ivzLqxVb.js +0 -8350
- package/dist/ChartCore-ivzLqxVb.js.map +0 -1
- package/dist/SciPlot-CEU4ApgD.js +0 -463
- package/dist/SciPlot-CEU4ApgD.js.map +0 -1
- package/dist/createStackedChart-DxNW0VkF.js +0 -705
- package/dist/createStackedChart-DxNW0VkF.js.map +0 -1
- package/dist/gpuRenderer-BpaMYz-k.js +0 -1848
- package/dist/gpuRenderer-BpaMYz-k.js.map +0 -1
- package/dist/index-BBpJwOct.js.map +0 -1
- package/dist/index-BMiZoKmm.js.map +0 -1
- package/dist/index-DoYxf1cV.js.map +0 -1
- package/dist/index-qunX30Xu.js.map +0 -1
- package/dist/index-x4stH3jD.js +0 -282
- package/dist/index-x4stH3jD.js.map +0 -1
- package/dist/index.core-COREBDNq.js.map +0 -1
- package/dist/mockDatafeed-927foCM4.js.map +0 -1
- package/dist/pool-15HMCNv8.js +0 -88
- package/dist/pool-15HMCNv8.js.map +0 -1
- package/dist/react/SciPlot.d.ts +0 -60
- package/dist/react/useSciPlot.d.ts +0 -56
- package/dist/symbols-DT0eLlpW.js +0 -568
- 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
|
-
|
|
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
|
|
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
|
|
489
|
+
function $(r = 1e4, e = "drop-oldest") {
|
|
434
490
|
return new x({ maxBuffer: r, strategy: e });
|
|
435
491
|
}
|
|
436
|
-
function
|
|
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
|
|
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
|
-
|
|
526
|
+
W as C,
|
|
527
527
|
Q as P,
|
|
528
528
|
E as a,
|
|
529
529
|
_ as b,
|
|
530
530
|
J as c,
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
531
|
+
X as d,
|
|
532
|
+
$ as e,
|
|
533
|
+
q as f,
|
|
534
|
+
K as g
|
|
535
535
|
};
|
|
536
|
-
//# sourceMappingURL=index-
|
|
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 _ = (
|
|
3
|
-
var
|
|
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
|
|
36
|
+
class X {
|
|
37
37
|
constructor(e) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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((
|
|
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((
|
|
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
|
|
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 (
|
|
152
|
+
return (s = (i = this.callbacks).onResetZoom) == null || s.call(i), !0;
|
|
153
153
|
case "autoScale":
|
|
154
|
-
return (
|
|
154
|
+
return (l = (c = this.callbacks).onAutoScale) == null || l.call(c), !0;
|
|
155
155
|
case "zoomIn":
|
|
156
|
-
return (u = (
|
|
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 = (
|
|
160
|
+
return (f = (h = this.callbacks).onPanLeft) == null || f.call(h), !0;
|
|
161
161
|
case "panRight":
|
|
162
|
-
return (y = (
|
|
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 (
|
|
168
|
+
return (w = (D = this.callbacks).onTogglePan) == null || w.call(D), !0;
|
|
169
169
|
case "toggleSelect":
|
|
170
|
-
return (
|
|
170
|
+
return (A = (E = this.callbacks).onToggleSelect) == null || A.call(E), !0;
|
|
171
171
|
case "clearSelection":
|
|
172
172
|
case "escape":
|
|
173
|
-
return (
|
|
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 (
|
|
175
|
+
return (R = (P = this.callbacks).onDeleteSelected) == null || R.call(P), !0;
|
|
176
176
|
case "selectAll":
|
|
177
|
-
return (
|
|
177
|
+
return (x = (T = this.callbacks).onSelectAll) == null || x.call(T), !0;
|
|
178
178
|
case "copy":
|
|
179
|
-
return (
|
|
179
|
+
return (C = (U = this.callbacks).onCopy) == null || C.call(U), !0;
|
|
180
180
|
case "exportImage":
|
|
181
|
-
return (
|
|
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
|
|
203
|
+
function J(a, e, n) {
|
|
204
204
|
return {
|
|
205
|
-
key:
|
|
205
|
+
key: a,
|
|
206
206
|
action: e,
|
|
207
207
|
...n
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
|
-
function
|
|
211
|
-
const n =
|
|
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
|
|
220
|
-
switch (
|
|
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 (
|
|
238
|
-
/[a-z]/i.test(
|
|
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
|
|
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 =
|
|
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
|
-
|
|
321
|
-
|
|
322
|
-
Q as
|
|
323
|
-
V as p
|
|
261
|
+
X as K,
|
|
262
|
+
J as c,
|
|
263
|
+
Q as p
|
|
324
264
|
};
|
|
325
|
-
//# sourceMappingURL=index-
|
|
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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"}
|