velo-plot 1.15.0 → 1.19.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 (80) hide show
  1. package/dist/{ChartCore-BimVvUEg.js → ChartCore-DQ691eXH.js} +1523 -996
  2. package/dist/ChartCore-DQ691eXH.js.map +1 -0
  3. package/dist/assets/downsample.worker-C70QJ04y.js +2 -0
  4. package/dist/assets/downsample.worker-C70QJ04y.js.map +1 -0
  5. package/dist/assets/indicator.worker-bv0zC4EX.js +2 -0
  6. package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -0
  7. package/dist/core/OverlayRenderer.d.ts +2 -0
  8. package/dist/core/chart/ChartAlerts.d.ts +42 -0
  9. package/dist/core/chart/ChartCore.d.ts +19 -1
  10. package/dist/core/chart/ChartRenderLoop.d.ts +4 -2
  11. package/dist/core/chart/ChartRenderer.d.ts +3 -2
  12. package/dist/core/chart/candlestickMarkers.d.ts +23 -0
  13. package/dist/core/chart/heikinAshi.d.ts +10 -0
  14. package/dist/core/chart/series/types.d.ts +2 -2
  15. package/dist/core/chart/types.d.ts +7 -0
  16. package/dist/core/indicator/addIndicator.d.ts +36 -0
  17. package/dist/core/indicator/index.d.ts +2 -0
  18. package/dist/core/indicator/indicatorPresets.d.ts +37 -0
  19. package/dist/core/series/Series.d.ts +3 -0
  20. package/dist/core/stacked/types.d.ts +8 -0
  21. package/dist/core/time/TimeScale.d.ts +31 -0
  22. package/dist/createStackedChart-BPooTQ9z.js +1164 -0
  23. package/dist/createStackedChart-BPooTQ9z.js.map +1 -0
  24. package/dist/gpu/adapter/gpuRenderer.d.ts +21 -0
  25. package/dist/gpu/backends/webgpu/WebGPUBackend.d.ts +2 -1
  26. package/dist/gpuRenderer-BpaMYz-k.js +1848 -0
  27. package/dist/gpuRenderer-BpaMYz-k.js.map +1 -0
  28. package/dist/index-D7dTq6VB.js +503 -0
  29. package/dist/index-D7dTq6VB.js.map +1 -0
  30. package/dist/{index-Ce2JgkH_.js → index-DoYxf1cV.js} +86 -43
  31. package/dist/{index-Ce2JgkH_.js.map → index-DoYxf1cV.js.map} +1 -1
  32. package/dist/{index.core-C_-CFftD.js → index.core-BtGFYMOu.js} +2 -2
  33. package/dist/{index.core-C_-CFftD.js.map → index.core-BtGFYMOu.js.map} +1 -1
  34. package/dist/index.d.ts +12 -4
  35. package/dist/indicators--eJGmVox.js +302 -0
  36. package/dist/indicators--eJGmVox.js.map +1 -0
  37. package/dist/plugins/analysis.js +530 -807
  38. package/dist/plugins/analysis.js.map +1 -1
  39. package/dist/plugins/caching.js +26 -21
  40. package/dist/plugins/caching.js.map +1 -1
  41. package/dist/plugins/drawing-tools/index.d.ts +16 -0
  42. package/dist/plugins/gpu.js +202 -1895
  43. package/dist/plugins/gpu.js.map +1 -1
  44. package/dist/plugins/index.d.ts +2 -0
  45. package/dist/plugins/keyboard/index.d.ts +1 -7
  46. package/dist/plugins/keyboard.js +1 -1
  47. package/dist/plugins/lazy-load/types.d.ts +7 -0
  48. package/dist/plugins/lazy-load.js +131 -108
  49. package/dist/plugins/lazy-load.js.map +1 -1
  50. package/dist/plugins/replay/index.d.ts +19 -0
  51. package/dist/plugins/virtualization/types.d.ts +12 -0
  52. package/dist/plugins/virtualization.js +1 -1
  53. package/dist/pool-15HMCNv8.js +88 -0
  54. package/dist/pool-15HMCNv8.js.map +1 -0
  55. package/dist/react.js +2 -2
  56. package/dist/renderer/CandlestickRenderer.d.ts +1 -1
  57. package/dist/renderer/ChartSeriesRenderer.d.ts +6 -0
  58. package/dist/renderer/GpuChartRenderer.d.ts +23 -0
  59. package/dist/renderer/index.d.ts +3 -0
  60. package/dist/renderer/spike/WebGLGridSpike.d.ts +40 -0
  61. package/dist/testing/baselines/v1.15.0.json.d.ts +51 -0
  62. package/dist/testing/gridSpikeBenchmark.d.ts +49 -0
  63. package/dist/testing/index.d.ts +5 -0
  64. package/dist/testing/rendererBenchmark.d.ts +13 -0
  65. package/dist/testing/stage1BrowserBench.d.ts +42 -0
  66. package/dist/types.d.ts +21 -1
  67. package/dist/velo-plot.full.js +1322 -789
  68. package/dist/velo-plot.full.js.map +1 -1
  69. package/dist/velo-plot.js +20 -20
  70. package/dist/workers/downsample.d.ts +38 -0
  71. package/dist/workers/downsampleAsync.d.ts +6 -0
  72. package/dist/workers/indicator.worker.d.ts +32 -0
  73. package/dist/workers/indicatorsAsync.d.ts +26 -0
  74. package/dist/workers/pool.d.ts +36 -0
  75. package/package.json +11 -1
  76. package/dist/ChartCore-BimVvUEg.js.map +0 -1
  77. package/dist/createStackedChart-CjsKcOvX.js +0 -1088
  78. package/dist/createStackedChart-CjsKcOvX.js.map +0 -1
  79. package/dist/index-ChgIdk3N.js +0 -229
  80. package/dist/index-ChgIdk3N.js.map +0 -1
@@ -51,6 +51,8 @@ export { PluginBrokenAxis, type PluginBrokenAxisConfig, type BrokenAxisAPI, type
51
51
  export { PluginVideoRecorder, type PluginVideoRecorderConfig, type VideoRecorderAPI, type VideoRecorderOptions } from './video-recorder';
52
52
  export { PluginOffscreen, type PluginOffscreenConfig, type OffscreenAPI, type OffscreenStats, type OffscreenMode, type OffscreenTransferMode, type OffscreenFallbackMode } from './offscreen';
53
53
  export { PluginVirtualization, type PluginVirtualizationConfig, type VirtualizationAPI, type VirtualizationStats, type VirtualizationMode, type VirtualizationStrategy } from './virtualization';
54
+ export { PluginDrawingTools, type PluginDrawingToolsConfig, type DrawingToolsAPI, type DrawingMode } from './drawing-tools';
55
+ export { PluginReplay, type PluginReplayConfig, type ReplayAPI } from './replay';
54
56
  export { PluginROI, type PluginROIConfig, type RoiAPI, type RoiRegion, type RoiPoint, type RoiMaskResult, type RoiTool, type RoiEvent, type RoiSelectedEvent } from './roi';
55
57
  /**
56
58
  * Helper function to create a plugin with proper typing
@@ -2,14 +2,8 @@ import { KeyBindingManager, DEFAULT_KEY_BINDINGS, KeyBinding, KeyBindingManagerO
2
2
  import { ChartPlugin } from '../types';
3
3
 
4
4
  export interface PluginKeyboardConfig extends Partial<KeyBindingManagerOptions> {
5
- /** Additional shortcuts to register */
6
5
  extraShortcuts?: KeyBinding[];
7
6
  }
8
- /**
9
- * SciPlot Keyboard Plugin
10
- *
11
- * Adds support for keyboard shortcuts and hotkeys.
12
- */
13
- export declare function PluginKeyboard(_config?: PluginKeyboardConfig): ChartPlugin<PluginKeyboardConfig>;
7
+ export declare function PluginKeyboard(config?: PluginKeyboardConfig): ChartPlugin<PluginKeyboardConfig>;
14
8
  export { KeyBindingManager, DEFAULT_KEY_BINDINGS };
15
9
  export default PluginKeyboard;
@@ -1,4 +1,4 @@
1
- import { D as n, K as r, P as s, P as K } from "../index-Ce2JgkH_.js";
1
+ import { D as n, K as r, P as s, P as K } from "../index-DoYxf1cV.js";
2
2
  export {
3
3
  n as DEFAULT_KEY_BINDINGS,
4
4
  r as KeyBindingManager,
@@ -107,6 +107,13 @@ export interface LazyLoadAPI {
107
107
  loadVisible(): Promise<void>;
108
108
  /** Unload distant chunks */
109
109
  unloadDistant(): number;
110
+ /** Load only a visible data window (+ buffer) */
111
+ setDataWindow(opts: {
112
+ from: number;
113
+ to: number;
114
+ buffer?: number;
115
+ seriesId?: string;
116
+ }): Promise<void>;
110
117
  /** Get loading status */
111
118
  getLoadingStatus(seriesId: string): {
112
119
  loadedPoints: number;
@@ -1,10 +1,10 @@
1
- const w = {
1
+ const D = {
2
2
  name: "velo-plot-lazy-load",
3
3
  version: "1.0.0",
4
4
  description: "Lazy loading for large datasets with viewport-based chunking",
5
5
  provides: ["lazy-load", "data-streaming"],
6
6
  tags: ["performance", "data", "optimization"]
7
- }, v = {
7
+ }, T = {
8
8
  enabled: !0,
9
9
  chunkSize: 1e4,
10
10
  viewportBuffer: 2,
@@ -23,167 +23,190 @@ const w = {
23
23
  },
24
24
  debug: !1
25
25
  };
26
- function A(p = {}) {
27
- const n = { ...v, ...p };
28
- let u = null;
29
- const c = /* @__PURE__ */ new Map();
30
- function x(t) {
31
- return Math.floor(t / n.chunkSize);
26
+ function B(w = {}) {
27
+ const a = { ...T, ...w };
28
+ let l = null;
29
+ const h = /* @__PURE__ */ new Map();
30
+ function L(t) {
31
+ return Math.floor(t / a.chunkSize);
32
32
  }
33
- function z() {
34
- if (!u) return null;
35
- const t = u.data.getViewBounds();
33
+ function m() {
34
+ if (!l) return null;
35
+ const t = l.data.getViewBounds();
36
36
  return t ? { xMin: t.xMin, xMax: t.xMax } : null;
37
37
  }
38
- async function k(t, o) {
39
- if (!(t.chunks.has(o) || t.loading.has(o))) {
40
- t.loading.add(o);
38
+ async function M(t, n) {
39
+ if (!(t.chunks.has(n) || t.loading.has(n))) {
40
+ t.loading.add(n);
41
41
  try {
42
- const a = o * n.chunkSize, r = Math.min(
43
- a + n.chunkSize,
42
+ const o = n * a.chunkSize, r = Math.min(
43
+ o + a.chunkSize,
44
44
  t.totalPoints
45
45
  );
46
- n.debug && console.log(`[LazyLoad] Loading chunk ${o} for ${t.id} (${a}-${r})`);
47
- const e = await t.provider.loadChunk(a, r);
48
- t.chunks.set(o, e), t.loading.delete(o), await C(t);
49
- const i = Array.from(t.chunks.values()).reduce(
50
- (l, f) => l + (f.endIndex - f.startIndex),
46
+ a.debug && console.log(`[LazyLoad] Loading chunk ${n} for ${t.id} (${o}-${r})`);
47
+ const e = await t.provider.loadChunk(o, r);
48
+ t.chunks.set(n, e), t.loading.delete(n), await z(t);
49
+ const s = Array.from(t.chunks.values()).reduce(
50
+ (c, f) => c + (f.endIndex - f.startIndex),
51
51
  0
52
- ), s = Math.ceil(t.totalPoints / n.chunkSize), h = {
52
+ ), i = Math.ceil(t.totalPoints / a.chunkSize), u = {
53
53
  seriesId: t.id,
54
- loadedPoints: i,
54
+ loadedPoints: s,
55
55
  totalPoints: t.totalPoints,
56
- progress: i / t.totalPoints,
57
- currentChunk: o,
58
- totalChunks: s
56
+ progress: s / t.totalPoints,
57
+ currentChunk: n,
58
+ totalChunks: i
59
59
  };
60
- i === t.totalPoints ? n.onLoadComplete(h) : n.onLoadProgress(h);
61
- } catch (a) {
62
- t.loading.delete(o), n.onLoadError(a, t.id), n.debug && console.error(`[LazyLoad] Error loading chunk ${o}:`, a);
60
+ s === t.totalPoints ? a.onLoadComplete(u) : a.onLoadProgress(u);
61
+ } catch (o) {
62
+ t.loading.delete(n), a.onLoadError(o, t.id), a.debug && console.error(`[LazyLoad] Error loading chunk ${n}:`, o);
63
63
  }
64
64
  }
65
65
  }
66
- async function C(t) {
67
- var s, h;
68
- if (!u) return;
69
- const o = Array.from(t.chunks.entries()).sort((l, f) => l[0] - f[0]);
70
- if (o.length === 0) return;
71
- let a = 0;
72
- for (const [, l] of o)
73
- a += l.x.length;
74
- const r = new Float32Array(a), e = new Float32Array(a);
75
- let i = 0;
76
- for (const [, l] of o)
77
- r.set(l.x, i), e.set(l.y, i), i += l.x.length;
78
- (h = (s = u.chart).updateSeries) == null || h.call(s, t.id, { x: r, y: e });
66
+ async function z(t) {
67
+ var i, u;
68
+ if (!l) return;
69
+ const n = Array.from(t.chunks.entries()).sort((c, f) => c[0] - f[0]);
70
+ if (n.length === 0) return;
71
+ let o = 0;
72
+ for (const [, c] of n)
73
+ o += c.x.length;
74
+ const r = new Float32Array(o), e = new Float32Array(o);
75
+ let s = 0;
76
+ for (const [, c] of n)
77
+ r.set(c.x, s), e.set(c.y, s), s += c.x.length;
78
+ (u = (i = l.chart).updateSeries) == null || u.call(i, t.id, { x: r, y: e });
79
79
  }
80
80
  async function g() {
81
- if (!n.enabled || !u) return;
82
- const t = z();
81
+ if (!a.enabled || !l) return;
82
+ const t = m();
83
83
  if (!t) return;
84
- const o = n.viewportBuffer, a = t.xMax - t.xMin, r = {
85
- xMin: t.xMin - a * o,
86
- xMax: t.xMax + a * o
84
+ const n = a.viewportBuffer, o = t.xMax - t.xMin, r = {
85
+ xMin: t.xMin - o * n,
86
+ xMax: t.xMax + o * n
87
87
  };
88
- for (const [, e] of c) {
89
- const i = [], s = Math.ceil(e.totalPoints / n.chunkSize), h = Math.max(0, Math.floor(r.xMin / n.chunkSize)), l = Math.min(s - 1, Math.floor(r.xMax / n.chunkSize));
90
- for (let d = h; d <= l; d++)
91
- !e.chunks.has(d) && !e.loading.has(d) && i.push(d);
92
- const f = Math.min(i.length, 10);
88
+ for (const [, e] of h) {
89
+ const s = [], i = Math.ceil(e.totalPoints / a.chunkSize), u = Math.max(0, Math.floor(r.xMin / a.chunkSize)), c = Math.min(i - 1, Math.floor(r.xMax / a.chunkSize));
90
+ for (let d = u; d <= c; d++)
91
+ !e.chunks.has(d) && !e.loading.has(d) && s.push(d);
92
+ const f = Math.min(s.length, 10);
93
93
  for (let d = 0; d < f; d++)
94
- await k(e, i[d]);
95
- if (n.preloadAdjacent && l + 1 < s) {
96
- const d = l + 1;
97
- !e.chunks.has(d) && !e.loading.has(d) && k(e, d);
94
+ await M(e, s[d]);
95
+ if (a.preloadAdjacent && c + 1 < i) {
96
+ const d = c + 1;
97
+ !e.chunks.has(d) && !e.loading.has(d) && M(e, d);
98
98
  }
99
99
  }
100
100
  }
101
- function L() {
102
- if (!n.autoUnload || !u || !z()) return 0;
103
- let o = 0;
104
- for (const [, a] of c)
105
- if (a.chunks.size > n.maxLoadedChunks) {
106
- const r = Array.from(a.chunks.entries()).sort(
107
- (i, s) => i[1].loadedAt - s[1].loadedAt
108
- ), e = a.chunks.size - n.maxLoadedChunks;
109
- for (let i = 0; i < e; i++)
110
- a.chunks.delete(r[i][0]), o++;
101
+ function b(t, n) {
102
+ const o = a.viewportBuffer, r = n.xMax - n.xMin, e = {
103
+ xMin: n.xMin - r * o,
104
+ xMax: n.xMax + r * o
105
+ }, s = Math.ceil(t.totalPoints / a.chunkSize), i = Math.max(0, Math.floor(e.xMin / a.chunkSize)), u = Math.min(s - 1, Math.floor(e.xMax / a.chunkSize));
106
+ return { startChunk: i, endChunk: u };
107
+ }
108
+ function x() {
109
+ if (!a.autoUnload || !l) return 0;
110
+ const t = m();
111
+ if (!t) return 0;
112
+ let n = 0;
113
+ for (const [, o] of h) {
114
+ let r = 0;
115
+ const { startChunk: e, endChunk: s } = b(o, t), i = Math.max(1, s - e + 1), u = Math.ceil(a.unloadThreshold * i), c = Math.max(0, e - u), f = s + u;
116
+ for (const d of Array.from(o.chunks.keys()))
117
+ (d < c || d > f) && (o.chunks.delete(d), r++);
118
+ if (o.chunks.size > a.maxLoadedChunks) {
119
+ const d = Array.from(o.chunks.entries()).sort(
120
+ (k, $) => k[1].loadedAt - $[1].loadedAt
121
+ ), U = o.chunks.size - a.maxLoadedChunks;
122
+ for (let k = 0; k < U; k++)
123
+ o.chunks.delete(d[k][0]), r++;
111
124
  }
112
- return n.debug && o > 0 && console.log(`[LazyLoad] Unloaded ${o} chunks`), o;
125
+ r > 0 && (z(o), n += r);
126
+ }
127
+ return a.debug && n > 0 && console.log(`[LazyLoad] Unloaded ${n} chunks`), n;
113
128
  }
114
- function m(t, o) {
115
- const a = o.getTotalCount();
116
- c.set(t, {
129
+ function P(t, n) {
130
+ const o = n.getTotalCount();
131
+ h.set(t, {
117
132
  id: t,
118
- provider: o,
133
+ provider: n,
119
134
  chunks: /* @__PURE__ */ new Map(),
120
135
  loading: /* @__PURE__ */ new Set(),
121
- totalPoints: a
122
- }), n.debug && console.log(`[LazyLoad] Registered series ${t} with ${a} points`), n.onLoadStart({
136
+ totalPoints: o
137
+ }), a.debug && console.log(`[LazyLoad] Registered series ${t} with ${o} points`), a.onLoadStart({
123
138
  seriesId: t,
124
139
  loadedPoints: 0,
125
- totalPoints: a,
140
+ totalPoints: o,
126
141
  progress: 0,
127
142
  currentChunk: 0,
128
- totalChunks: Math.ceil(a / n.chunkSize)
129
- }), n.autoLoad && g();
143
+ totalChunks: Math.ceil(o / a.chunkSize)
144
+ }), a.autoLoad && g();
130
145
  }
131
- function S(t) {
132
- c.delete(t), n.debug && console.log(`[LazyLoad] Unregistered series ${t}`);
146
+ function v(t) {
147
+ h.delete(t), a.debug && console.log(`[LazyLoad] Unregistered series ${t}`);
133
148
  }
134
- async function b(t, o, a) {
135
- const r = c.get(t);
149
+ async function C(t, n, o) {
150
+ const r = h.get(t);
136
151
  if (!r) return;
137
- const e = x(o), i = x(a);
138
- for (let s = e; s <= i; s++)
139
- await k(r, s);
152
+ const e = L(n), s = L(o);
153
+ for (let i = e; i <= s; i++)
154
+ await M(r, i);
140
155
  }
141
- function P(t) {
142
- const o = c.get(t);
143
- return o ? {
144
- loadedPoints: Array.from(o.chunks.values()).reduce(
156
+ function A(t) {
157
+ const n = h.get(t);
158
+ return n ? {
159
+ loadedPoints: Array.from(n.chunks.values()).reduce(
145
160
  (r, e) => r + (e.endIndex - e.startIndex),
146
161
  0
147
162
  ),
148
- totalPoints: o.totalPoints,
149
- loadedChunks: o.chunks.size,
150
- totalChunks: Math.ceil(o.totalPoints / n.chunkSize)
163
+ totalPoints: n.totalPoints,
164
+ loadedChunks: n.chunks.size,
165
+ totalChunks: Math.ceil(n.totalPoints / a.chunkSize)
151
166
  } : null;
152
167
  }
153
168
  function y() {
154
- for (const [, t] of c)
169
+ for (const [, t] of h)
155
170
  t.chunks.clear(), t.loading.clear();
156
171
  }
157
- const M = {
158
- registerSeries: m,
159
- unregisterSeries: S,
160
- loadRange: b,
172
+ async function p(t) {
173
+ if (!l || !a.enabled) return;
174
+ const n = t.buffer ?? a.viewportBuffer, o = t.to - t.from, r = Math.max(0, Math.floor(t.from - o * n)), e = Math.ceil(t.to + o * n), s = t.seriesId ? [[t.seriesId, h.get(t.seriesId)]] : Array.from(h.entries()).map(([i, u]) => [i, u]);
175
+ for (const [i, u] of s)
176
+ u && await C(i, r, e);
177
+ a.autoUnload && x();
178
+ }
179
+ const S = {
180
+ registerSeries: P,
181
+ unregisterSeries: v,
182
+ loadRange: C,
161
183
  loadVisible: g,
162
- unloadDistant: L,
163
- getLoadingStatus: P,
184
+ unloadDistant: x,
185
+ setDataWindow: p,
186
+ getLoadingStatus: A,
164
187
  clear: y,
165
188
  updateConfig(t) {
166
- Object.assign(n, t);
189
+ Object.assign(a, t);
167
190
  }
168
191
  };
169
192
  return {
170
- manifest: w,
193
+ manifest: D,
171
194
  onInit(t) {
172
- var o, a, r, e;
173
- u = t, u.chart.lazyLoad = M, n.autoLoad && ((a = (o = u.chart).on) == null || a.call(o, "zoom", () => {
174
- g(), n.autoUnload && L();
175
- }), (e = (r = u.chart).on) == null || e.call(r, "pan", () => {
176
- g(), n.autoUnload && L();
195
+ var n, o, r, e;
196
+ l = t, l.chart.lazyLoad = S, l.chart.setDataWindow = (s) => p(s), a.autoLoad && ((o = (n = l.chart).on) == null || o.call(n, "zoom", () => {
197
+ g(), a.autoUnload && x();
198
+ }), (e = (r = l.chart).on) == null || e.call(r, "pan", () => {
199
+ g(), a.autoUnload && x();
177
200
  }));
178
201
  },
179
202
  onDestroy(t) {
180
- y(), delete t.chart.lazyLoad, u = null;
203
+ y(), delete t.chart.lazyLoad, delete t.chart.setDataWindow, l = null;
181
204
  },
182
- api: M
205
+ api: S
183
206
  };
184
207
  }
185
208
  export {
186
- A as PluginLazyLoad,
187
- A as default
209
+ B as PluginLazyLoad,
210
+ B as default
188
211
  };
189
212
  //# sourceMappingURL=lazy-load.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-load.js","sources":["../../src/plugins/lazy-load/index.ts"],"sourcesContent":["/**\n * @fileoverview Lazy loading plugin for large datasets\n * @module plugins/lazy-load\n */\n\nimport type {\n PluginLazyLoadConfig,\n LazyLoadAPI,\n DataProvider,\n LazyLoadedSeries,\n LoadProgressEvent,\n} from './types';\nimport type {\n ChartPlugin,\n PluginContext,\n PluginManifest,\n} from '../types';\n\nconst manifest: PluginManifest = {\n name: 'velo-plot-lazy-load',\n version: '1.0.0',\n description: 'Lazy loading for large datasets with viewport-based chunking',\n provides: ['lazy-load', 'data-streaming'],\n tags: ['performance', 'data', 'optimization'],\n};\n\nconst DEFAULT_CONFIG: Required<PluginLazyLoadConfig> = {\n enabled: true,\n chunkSize: 10000,\n viewportBuffer: 2,\n autoLoad: true,\n autoUnload: true,\n unloadThreshold: 5,\n preloadAdjacent: true,\n maxLoadedChunks: 100,\n onLoadStart: () => {},\n onLoadProgress: () => {},\n onLoadComplete: () => {},\n onLoadError: () => {},\n debug: false,\n};\n\nexport function PluginLazyLoad(\n userConfig: Partial<PluginLazyLoadConfig> = {}\n): ChartPlugin<PluginLazyLoadConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n\n // Registered series\n const series = new Map<string, LazyLoadedSeries>();\n\n /**\n * Calculate chunk index from point index\n */\n function getChunkIndex(pointIndex: number): number {\n return Math.floor(pointIndex / config.chunkSize);\n }\n\n /**\n * Get visible range from chart\n */\n function getVisibleRange(): { xMin: number; xMax: number } | null {\n if (!ctx) return null;\n \n // Get current view bounds from data context\n const bounds = ctx.data.getViewBounds();\n if (bounds) {\n return { xMin: bounds.xMin, xMax: bounds.xMax };\n }\n \n return null;\n }\n\n /**\n * Load a specific chunk\n */\n async function loadChunk(\n seriesInfo: LazyLoadedSeries,\n chunkIndex: number\n ): Promise<void> {\n // Already loaded or loading\n if (seriesInfo.chunks.has(chunkIndex) || seriesInfo.loading.has(chunkIndex)) {\n return;\n }\n\n seriesInfo.loading.add(chunkIndex);\n\n try {\n const startIndex = chunkIndex * config.chunkSize;\n const endIndex = Math.min(\n startIndex + config.chunkSize,\n seriesInfo.totalPoints\n );\n\n if (config.debug) {\n console.log(`[LazyLoad] Loading chunk ${chunkIndex} for ${seriesInfo.id} (${startIndex}-${endIndex})`);\n }\n\n const chunk = await seriesInfo.provider.loadChunk(startIndex, endIndex);\n \n seriesInfo.chunks.set(chunkIndex, chunk);\n seriesInfo.loading.delete(chunkIndex);\n\n // Update chart data\n await updateSeriesData(seriesInfo);\n\n // Fire progress event\n const loadedPoints = Array.from(seriesInfo.chunks.values()).reduce(\n (sum, c) => sum + (c.endIndex - c.startIndex),\n 0\n );\n\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n \n const event: LoadProgressEvent = {\n seriesId: seriesInfo.id,\n loadedPoints,\n totalPoints: seriesInfo.totalPoints,\n progress: loadedPoints / seriesInfo.totalPoints,\n currentChunk: chunkIndex,\n totalChunks,\n };\n\n if (loadedPoints === seriesInfo.totalPoints) {\n config.onLoadComplete(event);\n } else {\n config.onLoadProgress(event);\n }\n\n } catch (error) {\n seriesInfo.loading.delete(chunkIndex);\n config.onLoadError(error as Error, seriesInfo.id);\n \n if (config.debug) {\n console.error(`[LazyLoad] Error loading chunk ${chunkIndex}:`, error);\n }\n }\n }\n\n /**\n * Update series data from loaded chunks\n */\n async function updateSeriesData(seriesInfo: LazyLoadedSeries): Promise<void> {\n if (!ctx) return;\n\n // Merge all loaded chunks\n const sortedChunks = Array.from(seriesInfo.chunks.entries()).sort((a, b) => a[0] - b[0]);\n \n if (sortedChunks.length === 0) return;\n\n // Calculate total size\n let totalSize = 0;\n for (const [, chunk] of sortedChunks) {\n totalSize += chunk.x.length;\n }\n\n // Allocate arrays\n const x = new Float32Array(totalSize);\n const y = new Float32Array(totalSize);\n\n // Copy data\n let offset = 0;\n for (const [, chunk] of sortedChunks) {\n x.set(chunk.x, offset);\n y.set(chunk.y, offset);\n offset += chunk.x.length;\n }\n\n // Update series\n (ctx.chart as any).updateSeries?.(seriesInfo.id, { x, y });\n }\n\n /**\n * Load visible data\n */\n async function loadVisible(): Promise<void> {\n if (!config.enabled || !ctx) return;\n\n const visibleRange = getVisibleRange();\n if (!visibleRange) return;\n\n const buffer = config.viewportBuffer;\n const rangeWidth = visibleRange.xMax - visibleRange.xMin;\n const buffered = {\n xMin: visibleRange.xMin - rangeWidth * buffer,\n xMax: visibleRange.xMax + rangeWidth * buffer,\n };\n\n for (const [, seriesInfo] of series) {\n const chunksToLoad: number[] = [];\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n\n // Identify chunks within the buffered viewport\n const startIdx = Math.max(0, Math.floor(buffered.xMin / config.chunkSize));\n const endIdx = Math.min(totalChunks - 1, Math.floor(buffered.xMax / config.chunkSize));\n\n for (let i = startIdx; i <= endIdx; i++) {\n if (!seriesInfo.chunks.has(i) && !seriesInfo.loading.has(i)) {\n chunksToLoad.push(i);\n }\n }\n\n // Load chunks sequentially (limit to avoid flood)\n const maxToLoad = Math.min(chunksToLoad.length, 10);\n for (let i = 0; i < maxToLoad; i++) {\n await loadChunk(seriesInfo, chunksToLoad[i]);\n }\n\n // Preload next adjacent chunk if enabled\n if (config.preloadAdjacent && endIdx + 1 < totalChunks) {\n const nextChunk = endIdx + 1;\n if (!seriesInfo.chunks.has(nextChunk) && !seriesInfo.loading.has(nextChunk)) {\n loadChunk(seriesInfo, nextChunk); // Fire and forget\n }\n }\n }\n }\n\n /**\n * Unload distant chunks\n */\n function unloadDistant(): number {\n if (!config.autoUnload || !ctx) return 0;\n\n const visibleRange = getVisibleRange();\n if (!visibleRange) return 0;\n\n let unloadedCount = 0;\n\n for (const [, seriesInfo] of series) {\n // TODO: Implement distance-based unloading logic\n // For now, only maxLoadedChunks handles eviction\n\n // Enforce max chunks limit\n if (seriesInfo.chunks.size > config.maxLoadedChunks) {\n const sortedChunks = Array.from(seriesInfo.chunks.entries()).sort(\n (a, b) => a[1].loadedAt - b[1].loadedAt\n );\n \n const toRemove = seriesInfo.chunks.size - config.maxLoadedChunks;\n for (let i = 0; i < toRemove; i++) {\n seriesInfo.chunks.delete(sortedChunks[i][0]);\n unloadedCount++;\n }\n }\n }\n\n if (config.debug && unloadedCount > 0) {\n console.log(`[LazyLoad] Unloaded ${unloadedCount} chunks`);\n }\n\n return unloadedCount;\n }\n\n /**\n * Register a series\n */\n function registerSeries(seriesId: string, provider: DataProvider): void {\n const totalPoints = provider.getTotalCount();\n \n series.set(seriesId, {\n id: seriesId,\n provider,\n chunks: new Map(),\n loading: new Set(),\n totalPoints,\n });\n\n if (config.debug) {\n console.log(`[LazyLoad] Registered series ${seriesId} with ${totalPoints} points`);\n }\n\n // Fire load start event\n config.onLoadStart({\n seriesId,\n loadedPoints: 0,\n totalPoints,\n progress: 0,\n currentChunk: 0,\n totalChunks: Math.ceil(totalPoints / config.chunkSize),\n });\n\n // Auto-load if enabled\n if (config.autoLoad) {\n loadVisible();\n }\n }\n\n /**\n * Unregister a series\n */\n function unregisterSeries(seriesId: string): void {\n series.delete(seriesId);\n \n if (config.debug) {\n console.log(`[LazyLoad] Unregistered series ${seriesId}`);\n }\n }\n\n /**\n * Load specific range\n */\n async function loadRange(\n seriesId: string,\n startIndex: number,\n endIndex: number\n ): Promise<void> {\n const seriesInfo = series.get(seriesId);\n if (!seriesInfo) return;\n\n const startChunk = getChunkIndex(startIndex);\n const endChunk = getChunkIndex(endIndex);\n\n for (let i = startChunk; i <= endChunk; i++) {\n await loadChunk(seriesInfo, i);\n }\n }\n\n /**\n * Get loading status\n */\n function getLoadingStatus(seriesId: string) {\n const seriesInfo = series.get(seriesId);\n if (!seriesInfo) return null;\n\n const loadedPoints = Array.from(seriesInfo.chunks.values()).reduce(\n (sum, c) => sum + (c.endIndex - c.startIndex),\n 0\n );\n\n return {\n loadedPoints,\n totalPoints: seriesInfo.totalPoints,\n loadedChunks: seriesInfo.chunks.size,\n totalChunks: Math.ceil(seriesInfo.totalPoints / config.chunkSize),\n };\n }\n\n /**\n * Clear all data\n */\n function clear(): void {\n for (const [, seriesInfo] of series) {\n seriesInfo.chunks.clear();\n seriesInfo.loading.clear();\n }\n }\n\n // API implementation\n const api: LazyLoadAPI & Record<string, unknown> = {\n registerSeries,\n unregisterSeries,\n loadRange,\n loadVisible,\n unloadDistant,\n getLoadingStatus,\n clear,\n updateConfig(newConfig: Partial<PluginLazyLoadConfig>) {\n Object.assign(config, newConfig);\n },\n };\n\n return {\n manifest,\n\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n\n // Attach to chart API\n (ctx.chart as any).lazyLoad = api;\n\n // Listen for zoom/pan if auto-load enabled\n if (config.autoLoad) {\n ctx.chart.on?.('zoom', () => {\n loadVisible();\n if (config.autoUnload) {\n unloadDistant();\n }\n });\n\n ctx.chart.on?.('pan', () => {\n loadVisible();\n if (config.autoUnload) {\n unloadDistant();\n }\n });\n }\n },\n\n onDestroy(pluginCtx: PluginContext) {\n // Clear all data\n clear();\n\n // Remove from chart API\n delete (pluginCtx.chart as any).lazyLoad;\n\n ctx = null;\n },\n\n api,\n };\n}\n\nexport default PluginLazyLoad;\n\n// Type exports\nexport type {\n PluginLazyLoadConfig,\n LazyLoadAPI,\n DataProvider,\n DataChunk,\n LoadProgressEvent,\n} from './types';\n"],"names":["manifest","DEFAULT_CONFIG","PluginLazyLoad","userConfig","config","ctx","series","getChunkIndex","pointIndex","getVisibleRange","bounds","loadChunk","seriesInfo","chunkIndex","startIndex","endIndex","chunk","updateSeriesData","loadedPoints","sum","c","totalChunks","event","error","_a","_b","sortedChunks","a","b","totalSize","x","y","offset","loadVisible","visibleRange","buffer","rangeWidth","buffered","chunksToLoad","startIdx","endIdx","i","maxToLoad","nextChunk","unloadDistant","unloadedCount","toRemove","registerSeries","seriesId","provider","totalPoints","unregisterSeries","loadRange","startChunk","endChunk","getLoadingStatus","clear","api","newConfig","pluginCtx","_c","_d"],"mappings":"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"}
1
+ {"version":3,"file":"lazy-load.js","sources":["../../src/plugins/lazy-load/index.ts"],"sourcesContent":["/**\n * @fileoverview Lazy loading plugin for large datasets\n * @module plugins/lazy-load\n */\n\nimport type {\n PluginLazyLoadConfig,\n LazyLoadAPI,\n DataProvider,\n LazyLoadedSeries,\n LoadProgressEvent,\n} from './types';\nimport type {\n ChartPlugin,\n PluginContext,\n PluginManifest,\n} from '../types';\n\nconst manifest: PluginManifest = {\n name: 'velo-plot-lazy-load',\n version: '1.0.0',\n description: 'Lazy loading for large datasets with viewport-based chunking',\n provides: ['lazy-load', 'data-streaming'],\n tags: ['performance', 'data', 'optimization'],\n};\n\nconst DEFAULT_CONFIG: Required<PluginLazyLoadConfig> = {\n enabled: true,\n chunkSize: 10000,\n viewportBuffer: 2,\n autoLoad: true,\n autoUnload: true,\n unloadThreshold: 5,\n preloadAdjacent: true,\n maxLoadedChunks: 100,\n onLoadStart: () => {},\n onLoadProgress: () => {},\n onLoadComplete: () => {},\n onLoadError: () => {},\n debug: false,\n};\n\nexport function PluginLazyLoad(\n userConfig: Partial<PluginLazyLoadConfig> = {}\n): ChartPlugin<PluginLazyLoadConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n\n // Registered series\n const series = new Map<string, LazyLoadedSeries>();\n\n /**\n * Calculate chunk index from point index\n */\n function getChunkIndex(pointIndex: number): number {\n return Math.floor(pointIndex / config.chunkSize);\n }\n\n /**\n * Get visible range from chart\n */\n function getVisibleRange(): { xMin: number; xMax: number } | null {\n if (!ctx) return null;\n \n // Get current view bounds from data context\n const bounds = ctx.data.getViewBounds();\n if (bounds) {\n return { xMin: bounds.xMin, xMax: bounds.xMax };\n }\n \n return null;\n }\n\n /**\n * Load a specific chunk\n */\n async function loadChunk(\n seriesInfo: LazyLoadedSeries,\n chunkIndex: number\n ): Promise<void> {\n // Already loaded or loading\n if (seriesInfo.chunks.has(chunkIndex) || seriesInfo.loading.has(chunkIndex)) {\n return;\n }\n\n seriesInfo.loading.add(chunkIndex);\n\n try {\n const startIndex = chunkIndex * config.chunkSize;\n const endIndex = Math.min(\n startIndex + config.chunkSize,\n seriesInfo.totalPoints\n );\n\n if (config.debug) {\n console.log(`[LazyLoad] Loading chunk ${chunkIndex} for ${seriesInfo.id} (${startIndex}-${endIndex})`);\n }\n\n const chunk = await seriesInfo.provider.loadChunk(startIndex, endIndex);\n \n seriesInfo.chunks.set(chunkIndex, chunk);\n seriesInfo.loading.delete(chunkIndex);\n\n // Update chart data\n await updateSeriesData(seriesInfo);\n\n // Fire progress event\n const loadedPoints = Array.from(seriesInfo.chunks.values()).reduce(\n (sum, c) => sum + (c.endIndex - c.startIndex),\n 0\n );\n\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n \n const event: LoadProgressEvent = {\n seriesId: seriesInfo.id,\n loadedPoints,\n totalPoints: seriesInfo.totalPoints,\n progress: loadedPoints / seriesInfo.totalPoints,\n currentChunk: chunkIndex,\n totalChunks,\n };\n\n if (loadedPoints === seriesInfo.totalPoints) {\n config.onLoadComplete(event);\n } else {\n config.onLoadProgress(event);\n }\n\n } catch (error) {\n seriesInfo.loading.delete(chunkIndex);\n config.onLoadError(error as Error, seriesInfo.id);\n \n if (config.debug) {\n console.error(`[LazyLoad] Error loading chunk ${chunkIndex}:`, error);\n }\n }\n }\n\n /**\n * Update series data from loaded chunks\n */\n async function updateSeriesData(seriesInfo: LazyLoadedSeries): Promise<void> {\n if (!ctx) return;\n\n // Merge all loaded chunks\n const sortedChunks = Array.from(seriesInfo.chunks.entries()).sort((a, b) => a[0] - b[0]);\n \n if (sortedChunks.length === 0) return;\n\n // Calculate total size\n let totalSize = 0;\n for (const [, chunk] of sortedChunks) {\n totalSize += chunk.x.length;\n }\n\n // Allocate arrays\n const x = new Float32Array(totalSize);\n const y = new Float32Array(totalSize);\n\n // Copy data\n let offset = 0;\n for (const [, chunk] of sortedChunks) {\n x.set(chunk.x, offset);\n y.set(chunk.y, offset);\n offset += chunk.x.length;\n }\n\n // Update series\n (ctx.chart as any).updateSeries?.(seriesInfo.id, { x, y });\n }\n\n /**\n * Load visible data\n */\n async function loadVisible(): Promise<void> {\n if (!config.enabled || !ctx) return;\n\n const visibleRange = getVisibleRange();\n if (!visibleRange) return;\n\n const buffer = config.viewportBuffer;\n const rangeWidth = visibleRange.xMax - visibleRange.xMin;\n const buffered = {\n xMin: visibleRange.xMin - rangeWidth * buffer,\n xMax: visibleRange.xMax + rangeWidth * buffer,\n };\n\n for (const [, seriesInfo] of series) {\n const chunksToLoad: number[] = [];\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n\n // Identify chunks within the buffered viewport\n const startIdx = Math.max(0, Math.floor(buffered.xMin / config.chunkSize));\n const endIdx = Math.min(totalChunks - 1, Math.floor(buffered.xMax / config.chunkSize));\n\n for (let i = startIdx; i <= endIdx; i++) {\n if (!seriesInfo.chunks.has(i) && !seriesInfo.loading.has(i)) {\n chunksToLoad.push(i);\n }\n }\n\n // Load chunks sequentially (limit to avoid flood)\n const maxToLoad = Math.min(chunksToLoad.length, 10);\n for (let i = 0; i < maxToLoad; i++) {\n await loadChunk(seriesInfo, chunksToLoad[i]);\n }\n\n // Preload next adjacent chunk if enabled\n if (config.preloadAdjacent && endIdx + 1 < totalChunks) {\n const nextChunk = endIdx + 1;\n if (!seriesInfo.chunks.has(nextChunk) && !seriesInfo.loading.has(nextChunk)) {\n loadChunk(seriesInfo, nextChunk); // Fire and forget\n }\n }\n }\n }\n\n /**\n * Chunk index range that should stay loaded for the current viewport.\n */\n function getKeepChunkRange(\n seriesInfo: LazyLoadedSeries,\n visibleRange: { xMin: number; xMax: number },\n ): { startChunk: number; endChunk: number } {\n const buffer = config.viewportBuffer;\n const rangeWidth = visibleRange.xMax - visibleRange.xMin;\n const buffered = {\n xMin: visibleRange.xMin - rangeWidth * buffer,\n xMax: visibleRange.xMax + rangeWidth * buffer,\n };\n const totalChunks = Math.ceil(seriesInfo.totalPoints / config.chunkSize);\n const startChunk = Math.max(0, Math.floor(buffered.xMin / config.chunkSize));\n const endChunk = Math.min(totalChunks - 1, Math.floor(buffered.xMax / config.chunkSize));\n return { startChunk, endChunk };\n }\n\n /**\n * Unload distant chunks\n */\n function unloadDistant(): number {\n if (!config.autoUnload || !ctx) return 0;\n\n const visibleRange = getVisibleRange();\n if (!visibleRange) return 0;\n\n let unloadedCount = 0;\n\n for (const [, seriesInfo] of series) {\n let seriesUnloaded = 0;\n const { startChunk, endChunk } = getKeepChunkRange(seriesInfo, visibleRange);\n const visibleSpan = Math.max(1, endChunk - startChunk + 1);\n const thresholdChunks = Math.ceil(config.unloadThreshold * visibleSpan);\n const keepStart = Math.max(0, startChunk - thresholdChunks);\n const keepEnd = endChunk + thresholdChunks;\n\n for (const chunkIndex of Array.from(seriesInfo.chunks.keys())) {\n if (chunkIndex < keepStart || chunkIndex > keepEnd) {\n seriesInfo.chunks.delete(chunkIndex);\n seriesUnloaded++;\n }\n }\n\n // Enforce max chunks limit (LRU eviction)\n if (seriesInfo.chunks.size > config.maxLoadedChunks) {\n const sortedChunks = Array.from(seriesInfo.chunks.entries()).sort(\n (a, b) => a[1].loadedAt - b[1].loadedAt,\n );\n\n const toRemove = seriesInfo.chunks.size - config.maxLoadedChunks;\n for (let i = 0; i < toRemove; i++) {\n seriesInfo.chunks.delete(sortedChunks[i][0]);\n seriesUnloaded++;\n }\n }\n\n if (seriesUnloaded > 0) {\n void updateSeriesData(seriesInfo);\n unloadedCount += seriesUnloaded;\n }\n }\n\n if (config.debug && unloadedCount > 0) {\n console.log(`[LazyLoad] Unloaded ${unloadedCount} chunks`);\n }\n\n return unloadedCount;\n }\n\n /**\n * Register a series\n */\n function registerSeries(seriesId: string, provider: DataProvider): void {\n const totalPoints = provider.getTotalCount();\n \n series.set(seriesId, {\n id: seriesId,\n provider,\n chunks: new Map(),\n loading: new Set(),\n totalPoints,\n });\n\n if (config.debug) {\n console.log(`[LazyLoad] Registered series ${seriesId} with ${totalPoints} points`);\n }\n\n // Fire load start event\n config.onLoadStart({\n seriesId,\n loadedPoints: 0,\n totalPoints,\n progress: 0,\n currentChunk: 0,\n totalChunks: Math.ceil(totalPoints / config.chunkSize),\n });\n\n // Auto-load if enabled\n if (config.autoLoad) {\n loadVisible();\n }\n }\n\n /**\n * Unregister a series\n */\n function unregisterSeries(seriesId: string): void {\n series.delete(seriesId);\n \n if (config.debug) {\n console.log(`[LazyLoad] Unregistered series ${seriesId}`);\n }\n }\n\n /**\n * Load specific range\n */\n async function loadRange(\n seriesId: string,\n startIndex: number,\n endIndex: number\n ): Promise<void> {\n const seriesInfo = series.get(seriesId);\n if (!seriesInfo) return;\n\n const startChunk = getChunkIndex(startIndex);\n const endChunk = getChunkIndex(endIndex);\n\n for (let i = startChunk; i <= endChunk; i++) {\n await loadChunk(seriesInfo, i);\n }\n }\n\n /**\n * Get loading status\n */\n function getLoadingStatus(seriesId: string) {\n const seriesInfo = series.get(seriesId);\n if (!seriesInfo) return null;\n\n const loadedPoints = Array.from(seriesInfo.chunks.values()).reduce(\n (sum, c) => sum + (c.endIndex - c.startIndex),\n 0\n );\n\n return {\n loadedPoints,\n totalPoints: seriesInfo.totalPoints,\n loadedChunks: seriesInfo.chunks.size,\n totalChunks: Math.ceil(seriesInfo.totalPoints / config.chunkSize),\n };\n }\n\n /**\n * Clear all data\n */\n function clear(): void {\n for (const [, seriesInfo] of series) {\n seriesInfo.chunks.clear();\n seriesInfo.loading.clear();\n }\n }\n\n /**\n * Load a data window with optional buffer (viewport-aware windowing API).\n */\n async function setDataWindow(opts: {\n from: number;\n to: number;\n buffer?: number;\n seriesId?: string;\n }): Promise<void> {\n if (!ctx || !config.enabled) return;\n\n const buffer = opts.buffer ?? config.viewportBuffer;\n const span = opts.to - opts.from;\n const startIndex = Math.max(0, Math.floor(opts.from - span * buffer));\n const endIndex = Math.ceil(opts.to + span * buffer);\n\n const targets = opts.seriesId\n ? [[opts.seriesId, series.get(opts.seriesId)] as const]\n : Array.from(series.entries()).map(([id, info]) => [id, info] as const);\n\n for (const [seriesId, seriesInfo] of targets) {\n if (!seriesInfo) continue;\n await loadRange(seriesId, startIndex, endIndex);\n }\n\n if (config.autoUnload) {\n unloadDistant();\n }\n }\n\n // API implementation\n const api: LazyLoadAPI & Record<string, unknown> = {\n registerSeries,\n unregisterSeries,\n loadRange,\n loadVisible,\n unloadDistant,\n setDataWindow,\n getLoadingStatus,\n clear,\n updateConfig(newConfig: Partial<PluginLazyLoadConfig>) {\n Object.assign(config, newConfig);\n },\n };\n\n return {\n manifest,\n\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n\n // Attach to chart API\n (ctx.chart as any).lazyLoad = api;\n (ctx.chart as any).setDataWindow = (opts: {\n from: number;\n to: number;\n buffer?: number;\n seriesId?: string;\n }) => setDataWindow(opts);\n\n // Listen for zoom/pan if auto-load enabled\n if (config.autoLoad) {\n ctx.chart.on?.('zoom', () => {\n loadVisible();\n if (config.autoUnload) {\n unloadDistant();\n }\n });\n\n ctx.chart.on?.('pan', () => {\n loadVisible();\n if (config.autoUnload) {\n unloadDistant();\n }\n });\n }\n },\n\n onDestroy(pluginCtx: PluginContext) {\n // Clear all data\n clear();\n\n // Remove from chart API\n delete (pluginCtx.chart as any).lazyLoad;\n delete (pluginCtx.chart as any).setDataWindow;\n\n ctx = null;\n },\n\n api,\n };\n}\n\nexport default PluginLazyLoad;\n\n// Type exports\nexport type {\n PluginLazyLoadConfig,\n LazyLoadAPI,\n DataProvider,\n DataChunk,\n LoadProgressEvent,\n} from './types';\n"],"names":["manifest","DEFAULT_CONFIG","PluginLazyLoad","userConfig","config","ctx","series","getChunkIndex","pointIndex","getVisibleRange","bounds","loadChunk","seriesInfo","chunkIndex","startIndex","endIndex","chunk","updateSeriesData","loadedPoints","sum","c","totalChunks","event","error","_a","_b","sortedChunks","a","b","totalSize","x","y","offset","loadVisible","visibleRange","buffer","rangeWidth","buffered","chunksToLoad","startIdx","endIdx","i","maxToLoad","nextChunk","getKeepChunkRange","startChunk","endChunk","unloadDistant","unloadedCount","seriesUnloaded","visibleSpan","thresholdChunks","keepStart","keepEnd","toRemove","registerSeries","seriesId","provider","totalPoints","unregisterSeries","loadRange","getLoadingStatus","clear","setDataWindow","opts","span","targets","id","info","api","newConfig","pluginCtx","_c","_d"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { ChartPlugin } from '../types';
2
+
3
+ export interface PluginReplayConfig {
4
+ /** Series id to replay */
5
+ seriesId: string;
6
+ /** Milliseconds between frames at 1x speed */
7
+ frameMs?: number;
8
+ }
9
+ export interface ReplayAPI {
10
+ play(speed?: number): void;
11
+ pause(): void;
12
+ step(count?: number): void;
13
+ seek(index: number): void;
14
+ getIndex(): number;
15
+ getLength(): number;
16
+ isPlaying(): boolean;
17
+ }
18
+ export declare function PluginReplay(config: PluginReplayConfig): ChartPlugin<PluginReplayConfig>;
19
+ export default PluginReplay;
@@ -7,6 +7,12 @@ export type VirtualizationStrategy = "lttb" | "minmax";
7
7
  export interface PluginVirtualizationConfig {
8
8
  /** Enable virtualization (default: true) */
9
9
  enabled?: boolean;
10
+ /**
11
+ * Data fidelity mode (default: `'lod'`).
12
+ * - `'lod'`: downsample to canvas budget (recommended for large datasets).
13
+ * - `'full'`: skip downsampling and send all points to the GPU (opt-out for fidelity-critical views).
14
+ */
15
+ precision?: "lod" | "full";
10
16
  /** Virtualization mode (default: 'lod') */
11
17
  mode?: VirtualizationMode;
12
18
  /** Target points or 'auto' (default: 'auto') */
@@ -27,6 +33,12 @@ export interface PluginVirtualizationConfig {
27
33
  excludeSeries?: string[];
28
34
  /** Debug logging (default: false) */
29
35
  debug?: boolean;
36
+ /** Viewport buffer as fraction of visible x-range when slicing before downsample (default: 0.5) */
37
+ viewportBuffer?: number;
38
+ /** Downsample off main thread when Workers are available (default: true) */
39
+ useWorker?: boolean;
40
+ /** Point count threshold before using worker path (default: 250000) */
41
+ workerThreshold?: number;
30
42
  }
31
43
  export interface VirtualizationStats {
32
44
  seriesId: string;
@@ -1,4 +1,4 @@
1
- import { P as t, P as l } from "../index-ChgIdk3N.js";
1
+ import { P as t, P as l } from "../index-D7dTq6VB.js";
2
2
  export {
3
3
  t as PluginVirtualization,
4
4
  l as default
@@ -0,0 +1,88 @@
1
+ var c = Object.defineProperty;
2
+ var l = (o, e, r) => e in o ? c(o, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : o[e] = r;
3
+ var n = (o, e, r) => l(o, typeof e != "symbol" ? e + "" : e, r);
4
+ class d {
5
+ constructor(e, r = {}) {
6
+ n(this, "workers", []);
7
+ n(this, "pending", /* @__PURE__ */ new Map());
8
+ n(this, "nextWorker", 0);
9
+ n(this, "poolSize");
10
+ n(this, "syncFallback");
11
+ n(this, "workerFactory");
12
+ n(this, "syncHandler");
13
+ n(this, "destroyed", !1);
14
+ if (this.workerFactory = e, this.poolSize = r.poolSize ?? 2, this.syncFallback = r.syncFallback ?? !0, this.syncHandler = r.syncHandler, typeof Worker < "u")
15
+ for (let s = 0; s < this.poolSize; s++)
16
+ this.spawnWorker();
17
+ }
18
+ removeWorker(e) {
19
+ const r = this.workers.indexOf(e);
20
+ r >= 0 && this.workers.splice(r, 1), e.terminate();
21
+ }
22
+ workerErrorMessage(e) {
23
+ const r = e;
24
+ return typeof r.message == "string" && r.message ? r.message : "Worker error";
25
+ }
26
+ rejectPendingWithSyncFallback(e, r) {
27
+ this.removeWorker(e);
28
+ const s = this.workerErrorMessage(r), t = [...this.pending.entries()];
29
+ this.pending.clear();
30
+ for (const [, i] of t) {
31
+ if (this.syncFallback && this.syncHandler) {
32
+ Promise.resolve(this.syncHandler(i.task)).then(i.resolve).catch(i.reject);
33
+ continue;
34
+ }
35
+ i.reject(new Error(s));
36
+ }
37
+ }
38
+ spawnWorker() {
39
+ const e = this.workerFactory();
40
+ e.onmessage = (r) => {
41
+ const s = r.data;
42
+ if (!(s != null && s.id)) return;
43
+ const t = this.pending.get(s.id);
44
+ if (t) {
45
+ if (this.pending.delete(s.id), s.type === "error" || s.error) {
46
+ if (this.syncFallback && this.syncHandler) {
47
+ Promise.resolve(this.syncHandler(t.task)).then(t.resolve).catch(t.reject);
48
+ return;
49
+ }
50
+ t.reject(new Error(s.error ?? "Worker task failed"));
51
+ return;
52
+ }
53
+ t.resolve(s);
54
+ }
55
+ }, e.onerror = (r) => {
56
+ this.rejectPendingWithSyncFallback(e, r);
57
+ }, this.workers.push(e);
58
+ }
59
+ /** Dispatch a task to the pool. Falls back to syncHandler when no workers exist. */
60
+ run(e) {
61
+ return this.destroyed ? Promise.reject(new Error("WorkerPool destroyed")) : this.workers.length === 0 ? this.syncFallback && this.syncHandler ? Promise.resolve(this.syncHandler(e)) : Promise.reject(new Error("No workers available and sync fallback disabled")) : new Promise((r, s) => {
62
+ this.pending.set(e.id, { resolve: r, reject: s, task: e });
63
+ const t = this.nextWorker;
64
+ this.nextWorker = (this.nextWorker + 1) % this.workers.length, this.workers[t].postMessage(e);
65
+ });
66
+ }
67
+ size() {
68
+ return this.workers.length;
69
+ }
70
+ pendingCount() {
71
+ return this.pending.size;
72
+ }
73
+ destroy() {
74
+ this.destroyed = !0;
75
+ for (const e of this.workers)
76
+ e.terminate();
77
+ this.workers = [], this.pending.clear();
78
+ }
79
+ }
80
+ let a = 0;
81
+ function k(o = "task") {
82
+ return a += 1, `${o}-${a}-${Date.now()}`;
83
+ }
84
+ export {
85
+ d as W,
86
+ k as n
87
+ };
88
+ //# sourceMappingURL=pool-15HMCNv8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool-15HMCNv8.js","sources":["../src/workers/pool.ts"],"sourcesContent":["/**\n * Generic worker pool with round-robin dispatch and sync fallback.\n * @module workers/pool\n */\n\nexport interface WorkerPoolOptions {\n /** Number of workers (default: 2) */\n poolSize?: number;\n /** Run tasks on main thread when Worker is unavailable */\n syncFallback?: boolean;\n}\n\nexport class WorkerPool<TMessage extends { id: string }, TResult = unknown> {\n private workers: Worker[] = [];\n private pending = new Map<\n string,\n {\n resolve: (value: TResult) => void;\n reject: (error: Error) => void;\n task: TMessage;\n }\n >();\n private nextWorker = 0;\n private readonly poolSize: number;\n private readonly syncFallback: boolean;\n private readonly workerFactory: () => Worker;\n private readonly syncHandler?: (task: TMessage) => TResult | Promise<TResult>;\n private destroyed = false;\n\n constructor(\n workerFactory: () => Worker,\n options: WorkerPoolOptions & {\n syncHandler?: (task: TMessage) => TResult | Promise<TResult>;\n } = {},\n ) {\n this.workerFactory = workerFactory;\n this.poolSize = options.poolSize ?? 2;\n this.syncFallback = options.syncFallback ?? true;\n this.syncHandler = options.syncHandler;\n\n if (typeof Worker !== \"undefined\") {\n for (let i = 0; i < this.poolSize; i++) {\n this.spawnWorker();\n }\n }\n }\n\n private removeWorker(worker: Worker): void {\n const index = this.workers.indexOf(worker);\n if (index >= 0) this.workers.splice(index, 1);\n worker.terminate();\n }\n\n private workerErrorMessage(event: Event): string {\n const maybe = event as { message?: string };\n if (typeof maybe.message === \"string\" && maybe.message) return maybe.message;\n return \"Worker error\";\n }\n\n private rejectPendingWithSyncFallback(failedWorker: Worker, event: Event): void {\n this.removeWorker(failedWorker);\n const message = this.workerErrorMessage(event);\n const entries = [...this.pending.entries()];\n this.pending.clear();\n\n for (const [, entry] of entries) {\n if (this.syncFallback && this.syncHandler) {\n Promise.resolve(this.syncHandler(entry.task)).then(entry.resolve).catch(entry.reject);\n continue;\n }\n entry.reject(new Error(message));\n }\n }\n\n private spawnWorker(): void {\n const worker = this.workerFactory();\n worker.onmessage = (event: MessageEvent) => {\n const data = event.data as { id?: string; type?: string; error?: string };\n if (!data?.id) return;\n\n const task = this.pending.get(data.id);\n if (!task) return;\n\n this.pending.delete(data.id);\n\n if (data.type === \"error\" || data.error) {\n if (this.syncFallback && this.syncHandler) {\n Promise.resolve(this.syncHandler(task.task)).then(task.resolve).catch(task.reject);\n return;\n }\n task.reject(new Error(data.error ?? \"Worker task failed\"));\n return;\n }\n\n task.resolve(data as TResult);\n };\n\n worker.onerror = (event) => {\n this.rejectPendingWithSyncFallback(worker, event);\n };\n\n this.workers.push(worker);\n }\n\n /** Dispatch a task to the pool. Falls back to syncHandler when no workers exist. */\n run(task: TMessage): Promise<TResult> {\n if (this.destroyed) {\n return Promise.reject(new Error(\"WorkerPool destroyed\"));\n }\n\n if (this.workers.length === 0) {\n if (this.syncFallback && this.syncHandler) {\n return Promise.resolve(this.syncHandler(task));\n }\n return Promise.reject(new Error(\"No workers available and sync fallback disabled\"));\n }\n\n return new Promise((resolve, reject) => {\n this.pending.set(task.id, { resolve, reject, task });\n const workerIndex = this.nextWorker;\n this.nextWorker = (this.nextWorker + 1) % this.workers.length;\n this.workers[workerIndex].postMessage(task);\n });\n }\n\n size(): number {\n return this.workers.length;\n }\n\n pendingCount(): number {\n return this.pending.size;\n }\n\n destroy(): void {\n this.destroyed = true;\n for (const worker of this.workers) {\n worker.terminate();\n }\n this.workers = [];\n this.pending.clear();\n }\n}\n\nlet taskCounter = 0;\n\n/** Generate a unique task id */\nexport function nextTaskId(prefix = \"task\"): string {\n taskCounter += 1;\n return `${prefix}-${taskCounter}-${Date.now()}`;\n}\n"],"names":["WorkerPool","workerFactory","options","__publicField","i","worker","index","event","maybe","failedWorker","message","entries","entry","data","task","resolve","reject","workerIndex","taskCounter","nextTaskId","prefix"],"mappings":"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"}
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
- import { c as k } from "./createStackedChart-CjsKcOvX.js";
2
- import { S as x, u as C } from "./createStackedChart-CjsKcOvX.js";
1
+ import { c as k } from "./createStackedChart-BPooTQ9z.js";
2
+ import { S as x, u as C } from "./createStackedChart-BPooTQ9z.js";
3
3
  import { useRef as n, useState as a, useEffect as m, useCallback as f } from "react";
4
4
  function A(c) {
5
5
  const s = n(null), r = n(null), [i, l] = a(null), [d, u] = a(!1), o = n(c);
@@ -6,7 +6,7 @@
6
6
  * Each candle is represented by a body (box) and a wick (line/thin box)
7
7
  * Returns a Float32Array of interleaved [x, y] coordinates for TRIANGLES
8
8
  */
9
- export declare function interleaveCandlestickData(x: Float32Array | Float64Array, open: Float32Array | Float64Array, high: Float32Array | Float64Array, low: Float32Array | Float64Array, close: Float32Array | Float64Array, width: number): {
9
+ export declare function interleaveCandlestickData(x: Float32Array | Float64Array, open: Float32Array | Float64Array, high: Float32Array | Float64Array, low: Float32Array | Float64Array, close: Float32Array | Float64Array, width: number, hollow?: boolean): {
10
10
  bullish: Float32Array;
11
11
  bearish: Float32Array;
12
12
  };