@chartgpu/chartgpu 0.2.5
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/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/ChartGPU.d.ts +146 -0
- package/dist/ChartGPU.d.ts.map +1 -0
- package/dist/components/createAnnotationConfigDialog.d.ts +24 -0
- package/dist/components/createAnnotationConfigDialog.d.ts.map +1 -0
- package/dist/components/createDataZoomSlider.d.ts +14 -0
- package/dist/components/createDataZoomSlider.d.ts.map +1 -0
- package/dist/components/createLegend.d.ts +9 -0
- package/dist/components/createLegend.d.ts.map +1 -0
- package/dist/components/createTextOverlay.d.ts +17 -0
- package/dist/components/createTextOverlay.d.ts.map +1 -0
- package/dist/components/createTooltip.d.ts +12 -0
- package/dist/components/createTooltip.d.ts.map +1 -0
- package/dist/components/formatTooltip.d.ts +19 -0
- package/dist/components/formatTooltip.d.ts.map +1 -0
- package/dist/config/OptionResolver.d.ts +137 -0
- package/dist/config/OptionResolver.d.ts.map +1 -0
- package/dist/config/defaults.d.ts +56 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/types.d.ts +553 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/core/GPUContext.d.ts +242 -0
- package/dist/core/GPUContext.d.ts.map +1 -0
- package/dist/core/RenderScheduler.d.ts +174 -0
- package/dist/core/RenderScheduler.d.ts.map +1 -0
- package/dist/core/createAnimationController.d.ts +15 -0
- package/dist/core/createAnimationController.d.ts.map +1 -0
- package/dist/core/createRenderCoordinator.d.ts +78 -0
- package/dist/core/createRenderCoordinator.d.ts.map +1 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts +183 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts +88 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts +91 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts +53 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts.map +1 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts +66 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts.map +1 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts +69 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts.map +1 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts +160 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts +36 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts +40 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts +70 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts +146 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts.map +1 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts +112 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts.map +1 -0
- package/dist/core/renderCoordinator/types.d.ts +19 -0
- package/dist/core/renderCoordinator/types.d.ts.map +1 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts +104 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts +122 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts +69 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts +52 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts +71 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/index.d.ts +12 -0
- package/dist/core/renderCoordinator/utils/index.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts +149 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts +129 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts.map +1 -0
- package/dist/data/cartesianData.d.ts +72 -0
- package/dist/data/cartesianData.d.ts.map +1 -0
- package/dist/data/createDataStore.d.ts +27 -0
- package/dist/data/createDataStore.d.ts.map +1 -0
- package/dist/data/createStreamBuffer.d.ts +20 -0
- package/dist/data/createStreamBuffer.d.ts.map +1 -0
- package/dist/data/lttbSample.d.ts +5 -0
- package/dist/data/lttbSample.d.ts.map +1 -0
- package/dist/data/ohlcSample.d.ts +21 -0
- package/dist/data/ohlcSample.d.ts.map +1 -0
- package/dist/data/packDataPoints.d.ts +65 -0
- package/dist/data/packDataPoints.d.ts.map +1 -0
- package/dist/data/sampleSeries.d.ts +20 -0
- package/dist/data/sampleSeries.d.ts.map +1 -0
- package/dist/esm/ChartGPUWorkerController-B50J-8sx.js +772 -0
- package/dist/esm/ChartGPUWorkerController-B50J-8sx.js.map +1 -0
- package/dist/esm/OptionResolver-R_gJDRSD.js +7150 -0
- package/dist/esm/OptionResolver-R_gJDRSD.js.map +1 -0
- package/dist/esm/assets/worker-entry-Wg897auv.js +779 -0
- package/dist/esm/assets/worker-entry-Wg897auv.js.map +1 -0
- package/dist/esm/createChartInWorker-C4fEeJL8.js +1224 -0
- package/dist/esm/createChartInWorker-C4fEeJL8.js.map +1 -0
- package/dist/esm/index.js +795 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.cjs +1270 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10504 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/createAnnotationAuthoring.d.ts +115 -0
- package/dist/interaction/createAnnotationAuthoring.d.ts.map +1 -0
- package/dist/interaction/createAnnotationDragHandler.d.ts +28 -0
- package/dist/interaction/createAnnotationDragHandler.d.ts.map +1 -0
- package/dist/interaction/createAnnotationHitTester.d.ts +32 -0
- package/dist/interaction/createAnnotationHitTester.d.ts.map +1 -0
- package/dist/interaction/createChartSync.d.ts +27 -0
- package/dist/interaction/createChartSync.d.ts.map +1 -0
- package/dist/interaction/createEventManager.d.ts +24 -0
- package/dist/interaction/createEventManager.d.ts.map +1 -0
- package/dist/interaction/createHoverState.d.ts +20 -0
- package/dist/interaction/createHoverState.d.ts.map +1 -0
- package/dist/interaction/createInsideZoom.d.ts +14 -0
- package/dist/interaction/createInsideZoom.d.ts.map +1 -0
- package/dist/interaction/createZoomState.d.ts +63 -0
- package/dist/interaction/createZoomState.d.ts.map +1 -0
- package/dist/interaction/findCandlestick.d.ts +41 -0
- package/dist/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/interaction/findNearestPoint.d.ts +61 -0
- package/dist/interaction/findNearestPoint.d.ts.map +1 -0
- package/dist/interaction/findPieSlice.d.ts +36 -0
- package/dist/interaction/findPieSlice.d.ts.map +1 -0
- package/dist/interaction/findPointsAtX.d.ts +37 -0
- package/dist/interaction/findPointsAtX.d.ts.map +1 -0
- package/dist/renderers/createAnnotationMarkerRenderer.d.ts +58 -0
- package/dist/renderers/createAnnotationMarkerRenderer.d.ts.map +1 -0
- package/dist/renderers/createAreaRenderer.d.ts +19 -0
- package/dist/renderers/createAreaRenderer.d.ts.map +1 -0
- package/dist/renderers/createAxisRenderer.d.ts +19 -0
- package/dist/renderers/createAxisRenderer.d.ts.map +1 -0
- package/dist/renderers/createBarRenderer.d.ts +20 -0
- package/dist/renderers/createBarRenderer.d.ts.map +1 -0
- package/dist/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/dist/renderers/createCrosshairRenderer.d.ts +43 -0
- package/dist/renderers/createCrosshairRenderer.d.ts.map +1 -0
- package/dist/renderers/createGridRenderer.d.ts +45 -0
- package/dist/renderers/createGridRenderer.d.ts.map +1 -0
- package/dist/renderers/createHighlightRenderer.d.ts +41 -0
- package/dist/renderers/createHighlightRenderer.d.ts.map +1 -0
- package/dist/renderers/createLineRenderer.d.ts +18 -0
- package/dist/renderers/createLineRenderer.d.ts.map +1 -0
- package/dist/renderers/createPieRenderer.d.ts +18 -0
- package/dist/renderers/createPieRenderer.d.ts.map +1 -0
- package/dist/renderers/createReferenceLineRenderer.d.ts +81 -0
- package/dist/renderers/createReferenceLineRenderer.d.ts.map +1 -0
- package/dist/renderers/createScatterDensityRenderer.d.ts +14 -0
- package/dist/renderers/createScatterDensityRenderer.d.ts.map +1 -0
- package/dist/renderers/createScatterRenderer.d.ts +20 -0
- package/dist/renderers/createScatterRenderer.d.ts.map +1 -0
- package/dist/renderers/rendererUtils.d.ts +100 -0
- package/dist/renderers/rendererUtils.d.ts.map +1 -0
- package/dist/themes/darkTheme.d.ts +11 -0
- package/dist/themes/darkTheme.d.ts.map +1 -0
- package/dist/themes/index.d.ts +8 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/lightTheme.d.ts +11 -0
- package/dist/themes/lightTheme.d.ts.map +1 -0
- package/dist/themes/types.d.ts +14 -0
- package/dist/themes/types.d.ts.map +1 -0
- package/dist/types/ChartGPU.d.ts +99 -0
- package/dist/types/ChartGPU.d.ts.map +1 -0
- package/dist/types/components/createDataZoomSlider.d.ts +14 -0
- package/dist/types/components/createDataZoomSlider.d.ts.map +1 -0
- package/dist/types/components/createLegend.d.ts +9 -0
- package/dist/types/components/createLegend.d.ts.map +1 -0
- package/dist/types/components/createTextOverlay.d.ts +17 -0
- package/dist/types/components/createTextOverlay.d.ts.map +1 -0
- package/dist/types/components/createTooltip.d.ts +12 -0
- package/dist/types/components/createTooltip.d.ts.map +1 -0
- package/dist/types/components/formatTooltip.d.ts +19 -0
- package/dist/types/components/formatTooltip.d.ts.map +1 -0
- package/dist/types/config/OptionResolver.d.ts +134 -0
- package/dist/types/config/OptionResolver.d.ts.map +1 -0
- package/dist/types/config/defaults.d.ts +55 -0
- package/dist/types/config/defaults.d.ts.map +1 -0
- package/dist/types/config/types.d.ts +485 -0
- package/dist/types/config/types.d.ts.map +1 -0
- package/dist/types/core/GPUContext.d.ts +242 -0
- package/dist/types/core/GPUContext.d.ts.map +1 -0
- package/dist/types/core/RenderScheduler.d.ts +174 -0
- package/dist/types/core/RenderScheduler.d.ts.map +1 -0
- package/dist/types/core/createAnimationController.d.ts +15 -0
- package/dist/types/core/createAnimationController.d.ts.map +1 -0
- package/dist/types/core/createRenderCoordinator.d.ts +129 -0
- package/dist/types/core/createRenderCoordinator.d.ts.map +1 -0
- package/dist/types/data/createDataStore.d.ts +33 -0
- package/dist/types/data/createDataStore.d.ts.map +1 -0
- package/dist/types/data/createStreamBuffer.d.ts +20 -0
- package/dist/types/data/createStreamBuffer.d.ts.map +1 -0
- package/dist/types/data/lttbSample.d.ts +5 -0
- package/dist/types/data/lttbSample.d.ts.map +1 -0
- package/dist/types/data/ohlcSample.d.ts +21 -0
- package/dist/types/data/ohlcSample.d.ts.map +1 -0
- package/dist/types/data/packDataPoints.d.ts +79 -0
- package/dist/types/data/packDataPoints.d.ts.map +1 -0
- package/dist/types/data/sampleSeries.d.ts +3 -0
- package/dist/types/data/sampleSeries.d.ts.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interaction/createChartSync.d.ts +12 -0
- package/dist/types/interaction/createChartSync.d.ts.map +1 -0
- package/dist/types/interaction/createEventManager.d.ts +24 -0
- package/dist/types/interaction/createEventManager.d.ts.map +1 -0
- package/dist/types/interaction/createHoverState.d.ts +20 -0
- package/dist/types/interaction/createHoverState.d.ts.map +1 -0
- package/dist/types/interaction/createInsideZoom.d.ts +14 -0
- package/dist/types/interaction/createInsideZoom.d.ts.map +1 -0
- package/dist/types/interaction/createZoomState.d.ts +63 -0
- package/dist/types/interaction/createZoomState.d.ts.map +1 -0
- package/dist/types/interaction/findCandlestick.d.ts +41 -0
- package/dist/types/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/types/interaction/findNearestPoint.d.ts +61 -0
- package/dist/types/interaction/findNearestPoint.d.ts.map +1 -0
- package/dist/types/interaction/findPieSlice.d.ts +36 -0
- package/dist/types/interaction/findPieSlice.d.ts.map +1 -0
- package/dist/types/interaction/findPointsAtX.d.ts +37 -0
- package/dist/types/interaction/findPointsAtX.d.ts.map +1 -0
- package/dist/types/renderers/createAreaRenderer.d.ts +18 -0
- package/dist/types/renderers/createAreaRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createAxisRenderer.d.ts +19 -0
- package/dist/types/renderers/createAxisRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createBarRenderer.d.ts +20 -0
- package/dist/types/renderers/createBarRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/types/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createCrosshairRenderer.d.ts +43 -0
- package/dist/types/renderers/createCrosshairRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createGridRenderer.d.ts +45 -0
- package/dist/types/renderers/createGridRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createHighlightRenderer.d.ts +41 -0
- package/dist/types/renderers/createHighlightRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createLineRenderer.d.ts +18 -0
- package/dist/types/renderers/createLineRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createPieRenderer.d.ts +18 -0
- package/dist/types/renderers/createPieRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createScatterDensityRenderer.d.ts +14 -0
- package/dist/types/renderers/createScatterDensityRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createScatterRenderer.d.ts +19 -0
- package/dist/types/renderers/createScatterRenderer.d.ts.map +1 -0
- package/dist/types/renderers/rendererUtils.d.ts +100 -0
- package/dist/types/renderers/rendererUtils.d.ts.map +1 -0
- package/dist/types/themes/darkTheme.d.ts +11 -0
- package/dist/types/themes/darkTheme.d.ts.map +1 -0
- package/dist/types/themes/index.d.ts +8 -0
- package/dist/types/themes/index.d.ts.map +1 -0
- package/dist/types/themes/lightTheme.d.ts +11 -0
- package/dist/types/themes/lightTheme.d.ts.map +1 -0
- package/dist/types/themes/types.d.ts +14 -0
- package/dist/types/themes/types.d.ts.map +1 -0
- package/dist/types/utils/axisLabelStyling.d.ts +27 -0
- package/dist/types/utils/axisLabelStyling.d.ts.map +1 -0
- package/dist/types/utils/checkWebGPU.d.ts +39 -0
- package/dist/types/utils/checkWebGPU.d.ts.map +1 -0
- package/dist/types/utils/colors.d.ts +14 -0
- package/dist/types/utils/colors.d.ts.map +1 -0
- package/dist/types/utils/easing.d.ts +9 -0
- package/dist/types/utils/easing.d.ts.map +1 -0
- package/dist/types/utils/scales.d.ts +79 -0
- package/dist/types/utils/scales.d.ts.map +1 -0
- package/dist/utils/axisLabelStyling.d.ts +20 -0
- package/dist/utils/axisLabelStyling.d.ts.map +1 -0
- package/dist/utils/checkWebGPU.d.ts +39 -0
- package/dist/utils/checkWebGPU.d.ts.map +1 -0
- package/dist/utils/colors.d.ts +14 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/easing.d.ts +9 -0
- package/dist/utils/easing.d.ts.map +1 -0
- package/dist/utils/scales.d.ts +79 -0
- package/dist/utils/scales.d.ts.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
import { o as D, s as $, r as b, c as M, v as k } from "./OptionResolver-R_gJDRSD.js";
|
|
2
|
+
const u = 120, F = 1e3 / 60, O = 1.5;
|
|
3
|
+
function N(d, e) {
|
|
4
|
+
if (!Number.isInteger(d) || d < 0)
|
|
5
|
+
throw new Error(`Invalid seriesIndex ${e}: ${d}. Must be a non-negative integer.`);
|
|
6
|
+
}
|
|
7
|
+
function R(d, e) {
|
|
8
|
+
if (!Number.isInteger(d) || d < 0)
|
|
9
|
+
throw new Error(`Invalid pointCount ${e}: ${d}. Must be a non-negative integer.`);
|
|
10
|
+
}
|
|
11
|
+
function m(d) {
|
|
12
|
+
return d instanceof Error ? [d.message, d.stack] : [String(d), void 0];
|
|
13
|
+
}
|
|
14
|
+
class L {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.charts = /* @__PURE__ */ new Map(), this.messageHandler = null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Registers a message handler to send outbound messages to the main thread.
|
|
20
|
+
*
|
|
21
|
+
* @param handler - Function to call when emitting messages to main thread
|
|
22
|
+
*/
|
|
23
|
+
onMessage(e) {
|
|
24
|
+
this.messageHandler = e;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Main entry point for handling inbound messages from the main thread.
|
|
28
|
+
* Routes messages to appropriate handlers with exhaustive type checking.
|
|
29
|
+
*
|
|
30
|
+
* @param msg - Inbound message from main thread
|
|
31
|
+
*/
|
|
32
|
+
async handleMessage(e) {
|
|
33
|
+
try {
|
|
34
|
+
switch (e.type) {
|
|
35
|
+
case "init":
|
|
36
|
+
await this.initChart(e);
|
|
37
|
+
break;
|
|
38
|
+
case "setOption":
|
|
39
|
+
this.handleSetOption(e.chartId, e.options);
|
|
40
|
+
break;
|
|
41
|
+
case "appendData":
|
|
42
|
+
this.handleAppendData(e.chartId, e.seriesIndex, e.data, e.pointCount, e.stride);
|
|
43
|
+
break;
|
|
44
|
+
case "appendDataBatch":
|
|
45
|
+
this.handleAppendDataBatch(e.chartId, e.items);
|
|
46
|
+
break;
|
|
47
|
+
case "resize":
|
|
48
|
+
this.handleResize(e.chartId, e);
|
|
49
|
+
break;
|
|
50
|
+
case "forwardPointerEvent":
|
|
51
|
+
this.handlePointerEvent(e.chartId, e.event);
|
|
52
|
+
break;
|
|
53
|
+
case "setZoomRange":
|
|
54
|
+
this.handleSetZoomRange(e.chartId, e.start, e.end);
|
|
55
|
+
break;
|
|
56
|
+
case "setInteractionX":
|
|
57
|
+
this.handleSetInteractionX(e.chartId, e.x, e.source);
|
|
58
|
+
break;
|
|
59
|
+
case "setAnimation":
|
|
60
|
+
this.handleSetAnimation(e.chartId, e.enabled, e.config);
|
|
61
|
+
break;
|
|
62
|
+
case "setGPUTiming":
|
|
63
|
+
this.handleSetGPUTiming(e.chartId, e.enabled);
|
|
64
|
+
break;
|
|
65
|
+
case "dispose":
|
|
66
|
+
this.disposeChart(e.chartId);
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
const t = e;
|
|
70
|
+
this.emitError(
|
|
71
|
+
"",
|
|
72
|
+
// No chartId available for unknown message
|
|
73
|
+
"UNKNOWN",
|
|
74
|
+
`Unknown message type: ${t.type}`,
|
|
75
|
+
"handleMessage"
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
} catch (t) {
|
|
79
|
+
const r = "chartId" in e ? e.chartId : "", [a, s] = m(t);
|
|
80
|
+
this.emitError(r, "UNKNOWN", a, "handleMessage", s);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initializes a new chart instance with WebGPU context and render coordinator.
|
|
85
|
+
*
|
|
86
|
+
* @param msg - Init message containing canvas, options, and configuration
|
|
87
|
+
*/
|
|
88
|
+
async initChart(e) {
|
|
89
|
+
var r, a;
|
|
90
|
+
let t = null;
|
|
91
|
+
try {
|
|
92
|
+
if (this.charts.has(e.chartId)) {
|
|
93
|
+
this.emitError(
|
|
94
|
+
e.chartId,
|
|
95
|
+
"UNKNOWN",
|
|
96
|
+
`Chart with ID "${e.chartId}" already exists`,
|
|
97
|
+
"init",
|
|
98
|
+
void 0,
|
|
99
|
+
e.messageId
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (e.devicePixelRatio <= 0)
|
|
104
|
+
throw new Error(`Invalid devicePixelRatio: ${e.devicePixelRatio}. Must be positive.`);
|
|
105
|
+
const s = {
|
|
106
|
+
devicePixelRatio: e.devicePixelRatio,
|
|
107
|
+
powerPreference: (r = e.gpuOptions) == null ? void 0 : r.powerPreference
|
|
108
|
+
}, i = D(e.canvas, s);
|
|
109
|
+
let o = await $(i);
|
|
110
|
+
const c = b(e.options);
|
|
111
|
+
t = new MessageChannel();
|
|
112
|
+
const l = {
|
|
113
|
+
renderPending: !1,
|
|
114
|
+
disposed: !1,
|
|
115
|
+
deviceLost: !1,
|
|
116
|
+
performance: {
|
|
117
|
+
frameTimestamps: new Float64Array(u),
|
|
118
|
+
frameTimestampIndex: 0,
|
|
119
|
+
frameTimestampCount: 0,
|
|
120
|
+
totalFrames: 0,
|
|
121
|
+
totalDroppedFrames: 0,
|
|
122
|
+
consecutiveDroppedFrames: 0,
|
|
123
|
+
lastDropTimestamp: 0,
|
|
124
|
+
startTime: performance.now(),
|
|
125
|
+
lastFrameTime: 0,
|
|
126
|
+
gpuTimingEnabled: !1,
|
|
127
|
+
lastCPUTime: 0,
|
|
128
|
+
lastGPUTime: 0
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
o.device && (o.device.lost.then((n) => {
|
|
132
|
+
l.deviceLost = !0, this.emit({
|
|
133
|
+
type: "deviceLost",
|
|
134
|
+
chartId: e.chartId,
|
|
135
|
+
reason: n.reason === "destroyed" ? "destroyed" : "unknown",
|
|
136
|
+
message: n.message || n.reason || "Device lost during initialization"
|
|
137
|
+
});
|
|
138
|
+
}).catch(() => {
|
|
139
|
+
}), o.device.addEventListener("uncapturederror", (n) => {
|
|
140
|
+
const g = n.error instanceof GPUValidationError ? `WebGPU Validation Error: ${n.error.message}` : n.error instanceof GPUOutOfMemoryError ? `WebGPU Out of Memory: ${n.error.message}` : `WebGPU Error: ${n.error.message}`;
|
|
141
|
+
this.emitError(e.chartId, "RENDER_ERROR", g, "uncaptured_gpu_error");
|
|
142
|
+
}));
|
|
143
|
+
const I = M(
|
|
144
|
+
o,
|
|
145
|
+
c,
|
|
146
|
+
{
|
|
147
|
+
// CRITICAL: Disable DOM overlays for worker mode
|
|
148
|
+
domOverlays: !1,
|
|
149
|
+
// Request render via MessageChannel for efficient scheduling
|
|
150
|
+
// PERFORMANCE: Use closure-captured state instead of Map lookup (critical for 60fps)
|
|
151
|
+
// CRITICAL: Post to port2, listen on port1 (MessageChannel requires opposite ends)
|
|
152
|
+
onRequestRender: () => {
|
|
153
|
+
!l.renderPending && !l.disposed && t && (l.renderPending = !0, t.port2.postMessage(null));
|
|
154
|
+
},
|
|
155
|
+
// Emit tooltip updates to main thread for DOM rendering
|
|
156
|
+
onTooltipUpdate: (n) => {
|
|
157
|
+
if (this.emit({
|
|
158
|
+
type: "tooltipUpdate",
|
|
159
|
+
chartId: e.chartId,
|
|
160
|
+
data: n
|
|
161
|
+
}), n && n.params.length > 0) {
|
|
162
|
+
const g = n.params[0];
|
|
163
|
+
this.emit({
|
|
164
|
+
type: "hoverChange",
|
|
165
|
+
chartId: e.chartId,
|
|
166
|
+
payload: {
|
|
167
|
+
seriesIndex: g.seriesIndex,
|
|
168
|
+
dataIndex: g.dataIndex,
|
|
169
|
+
value: g.value,
|
|
170
|
+
x: n.x,
|
|
171
|
+
y: n.y
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
} else
|
|
175
|
+
this.emit({
|
|
176
|
+
type: "hoverChange",
|
|
177
|
+
chartId: e.chartId,
|
|
178
|
+
payload: null
|
|
179
|
+
});
|
|
180
|
+
},
|
|
181
|
+
// Emit legend updates to main thread
|
|
182
|
+
onLegendUpdate: (n) => {
|
|
183
|
+
this.emit({
|
|
184
|
+
type: "legendUpdate",
|
|
185
|
+
chartId: e.chartId,
|
|
186
|
+
items: n
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
// Emit axis label updates to main thread
|
|
190
|
+
onAxisLabelsUpdate: (n, g) => {
|
|
191
|
+
this.emit({
|
|
192
|
+
type: "axisLabelsUpdate",
|
|
193
|
+
chartId: e.chartId,
|
|
194
|
+
xLabels: n,
|
|
195
|
+
yLabels: g
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
// Emit crosshair position to main thread
|
|
199
|
+
onCrosshairMove: (n) => {
|
|
200
|
+
n !== null && this.emit({
|
|
201
|
+
type: "crosshairMove",
|
|
202
|
+
chartId: e.chartId,
|
|
203
|
+
x: n
|
|
204
|
+
});
|
|
205
|
+
},
|
|
206
|
+
// Emit click events to main thread
|
|
207
|
+
onClickData: (n) => {
|
|
208
|
+
if (!(!n.nearest && !n.pieSlice && !n.candlestick)) {
|
|
209
|
+
if (n.nearest) {
|
|
210
|
+
this.emit({
|
|
211
|
+
type: "click",
|
|
212
|
+
chartId: e.chartId,
|
|
213
|
+
payload: {
|
|
214
|
+
seriesIndex: n.nearest.seriesIndex,
|
|
215
|
+
dataIndex: n.nearest.dataIndex,
|
|
216
|
+
value: n.nearest.point,
|
|
217
|
+
x: n.x,
|
|
218
|
+
y: n.y
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (n.pieSlice) {
|
|
224
|
+
this.emit({
|
|
225
|
+
type: "click",
|
|
226
|
+
chartId: e.chartId,
|
|
227
|
+
payload: {
|
|
228
|
+
seriesIndex: n.pieSlice.seriesIndex,
|
|
229
|
+
dataIndex: n.pieSlice.dataIndex,
|
|
230
|
+
value: [n.pieSlice.slice.value, 0],
|
|
231
|
+
x: n.x,
|
|
232
|
+
y: n.y
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
n.candlestick && this.emit({
|
|
238
|
+
type: "click",
|
|
239
|
+
chartId: e.chartId,
|
|
240
|
+
payload: {
|
|
241
|
+
seriesIndex: n.candlestick.seriesIndex,
|
|
242
|
+
dataIndex: n.candlestick.dataIndex,
|
|
243
|
+
value: n.candlestick.point,
|
|
244
|
+
x: n.x,
|
|
245
|
+
y: n.y
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
// Emit device lost events to main thread
|
|
251
|
+
onDeviceLost: (n) => {
|
|
252
|
+
l.deviceLost = !0, this.emit({
|
|
253
|
+
type: "deviceLost",
|
|
254
|
+
chartId: e.chartId,
|
|
255
|
+
reason: n === "destroyed" ? "destroyed" : "unknown",
|
|
256
|
+
message: n
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
I.onZoomRangeChange((n) => {
|
|
262
|
+
this.emit({
|
|
263
|
+
type: "zoomChange",
|
|
264
|
+
chartId: e.chartId,
|
|
265
|
+
start: n.start,
|
|
266
|
+
end: n.end
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
const w = {
|
|
270
|
+
chartId: e.chartId,
|
|
271
|
+
gpuContext: o,
|
|
272
|
+
coordinator: I,
|
|
273
|
+
canvas: e.canvas,
|
|
274
|
+
renderChannel: t,
|
|
275
|
+
state: l
|
|
276
|
+
// Shared state object (captured in coordinator callbacks)
|
|
277
|
+
};
|
|
278
|
+
this.charts.set(e.chartId, w);
|
|
279
|
+
const f = I.getZoomRange();
|
|
280
|
+
if (t) {
|
|
281
|
+
const n = e.chartId, g = I, x = l;
|
|
282
|
+
t.port1.onmessage = () => {
|
|
283
|
+
if (!x.disposed && !x.deviceLost) {
|
|
284
|
+
x.renderPending = !1;
|
|
285
|
+
const p = x.performance, y = performance.now();
|
|
286
|
+
try {
|
|
287
|
+
p.frameTimestamps[p.frameTimestampIndex] = y, p.frameTimestampIndex = (p.frameTimestampIndex + 1) % u, p.frameTimestampCount < u && p.frameTimestampCount++, p.totalFrames++, p.lastFrameTime > 0 && (y - p.lastFrameTime > F * O ? (p.totalDroppedFrames++, p.consecutiveDroppedFrames++, p.lastDropTimestamp = y) : p.consecutiveDroppedFrames = 0), p.lastFrameTime = y, g.render();
|
|
288
|
+
const P = performance.now() - y;
|
|
289
|
+
p.lastCPUTime = P;
|
|
290
|
+
const T = this.calculatePerformanceMetrics(p);
|
|
291
|
+
this.emit({
|
|
292
|
+
type: "performance-update",
|
|
293
|
+
chartId: n,
|
|
294
|
+
metrics: T
|
|
295
|
+
});
|
|
296
|
+
} catch (C) {
|
|
297
|
+
const [P, T] = m(C);
|
|
298
|
+
this.emitError(n, "RENDER_ERROR", P, "render", T);
|
|
299
|
+
}
|
|
300
|
+
} else x.deviceLost && (x.renderPending = !1);
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const E = o.adapter ? {
|
|
304
|
+
adapter: "WebGPU Adapter",
|
|
305
|
+
features: o.adapter.features ? [...o.adapter.features] : []
|
|
306
|
+
} : void 0, v = {
|
|
307
|
+
gpuTimingSupported: ((a = o.adapter) == null ? void 0 : a.features.has("timestamp-query")) ?? !1,
|
|
308
|
+
highResTimerSupported: typeof performance < "u" && typeof performance.now == "function",
|
|
309
|
+
performanceMetricsSupported: !0
|
|
310
|
+
// Always supported in worker
|
|
311
|
+
};
|
|
312
|
+
this.emit({
|
|
313
|
+
type: "ready",
|
|
314
|
+
chartId: e.chartId,
|
|
315
|
+
messageId: e.messageId,
|
|
316
|
+
capabilities: E,
|
|
317
|
+
performanceCapabilities: v,
|
|
318
|
+
initialZoomRange: f
|
|
319
|
+
}), !l.renderPending && !l.disposed && t && (l.renderPending = !0, t.port2.postMessage(null));
|
|
320
|
+
} catch (s) {
|
|
321
|
+
if (t)
|
|
322
|
+
try {
|
|
323
|
+
t.port1.close(), t.port2.close();
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
const [i, o] = m(s), c = i.includes("WebGPU") ? "WEBGPU_INIT_FAILED" : "UNKNOWN";
|
|
327
|
+
this.emitError(e.chartId, c, i, "init", o, e.messageId);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Updates chart options for an existing instance.
|
|
332
|
+
*
|
|
333
|
+
* @param chartId - Chart instance identifier
|
|
334
|
+
* @param options - New chart options to apply
|
|
335
|
+
*/
|
|
336
|
+
handleSetOption(e, t) {
|
|
337
|
+
try {
|
|
338
|
+
const r = this.getChartInstance(e, "setOption"), a = b(t);
|
|
339
|
+
r.coordinator.setOptions(a);
|
|
340
|
+
} catch (r) {
|
|
341
|
+
const [a, s] = m(r);
|
|
342
|
+
this.emitError(e, "UNKNOWN", a, "setOption", s);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Appends data points to a specific series.
|
|
347
|
+
*
|
|
348
|
+
* Performance: Uses shared validation helpers to reduce code size and improve performance.
|
|
349
|
+
*
|
|
350
|
+
* @param chartId - Chart instance identifier
|
|
351
|
+
* @param seriesIndex - Index of the series to append to
|
|
352
|
+
* @param data - ArrayBuffer containing interleaved Float32 point data
|
|
353
|
+
* @param pointCount - Number of points in the buffer
|
|
354
|
+
* @param stride - Bytes per point (8 for DataPoint, 20 for OHLCDataPoint)
|
|
355
|
+
*/
|
|
356
|
+
handleAppendData(e, t, r, a, s) {
|
|
357
|
+
try {
|
|
358
|
+
N(t, "in appendData"), R(a, "in appendData");
|
|
359
|
+
const i = this.getChartInstance(e, "appendData"), o = U(r, a, s);
|
|
360
|
+
i.coordinator.appendData(t, o);
|
|
361
|
+
} catch (i) {
|
|
362
|
+
const [o, c] = m(i);
|
|
363
|
+
this.emitError(e, "DATA_ERROR", o, "appendData", c);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Batch appends data to multiple series in a single operation.
|
|
368
|
+
*
|
|
369
|
+
* Performance optimizations:
|
|
370
|
+
* - Validates all items upfront before processing (fail fast)
|
|
371
|
+
* - Caches instance lookup outside loop
|
|
372
|
+
* - Uses shared validation helpers
|
|
373
|
+
* - Defers render request until all appends complete (batching)
|
|
374
|
+
*
|
|
375
|
+
* @param chartId - Chart instance identifier
|
|
376
|
+
* @param items - Array of append operations to perform
|
|
377
|
+
*/
|
|
378
|
+
handleAppendDataBatch(e, t) {
|
|
379
|
+
try {
|
|
380
|
+
const r = this.getChartInstance(e, "appendDataBatch"), a = t.length;
|
|
381
|
+
for (let s = 0; s < a; s++) {
|
|
382
|
+
const i = t[s];
|
|
383
|
+
N(i.seriesIndex, `at batch index ${s}`), R(i.pointCount, `at batch index ${s}`);
|
|
384
|
+
}
|
|
385
|
+
for (let s = 0; s < a; s++) {
|
|
386
|
+
const i = t[s], o = U(i.data, i.pointCount, i.stride);
|
|
387
|
+
r.coordinator.appendData(i.seriesIndex, o);
|
|
388
|
+
}
|
|
389
|
+
} catch (r) {
|
|
390
|
+
const [a, s] = m(r);
|
|
391
|
+
this.emitError(e, "DATA_ERROR", a, "appendDataBatch", s);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Handles canvas resize events.
|
|
396
|
+
*
|
|
397
|
+
* @param chartId - Chart instance identifier
|
|
398
|
+
* @param msg - Resize message with new dimensions
|
|
399
|
+
*/
|
|
400
|
+
handleResize(e, t) {
|
|
401
|
+
try {
|
|
402
|
+
const r = this.getChartInstance(e, "resize");
|
|
403
|
+
if (r.state.deviceLost)
|
|
404
|
+
throw new Error("Cannot resize: GPU device is lost");
|
|
405
|
+
const { width: a, height: s, devicePixelRatio: i } = t;
|
|
406
|
+
if (a <= 0 || s <= 0)
|
|
407
|
+
throw new Error(`Invalid dimensions: width=${a}, height=${s}. Must be positive.`);
|
|
408
|
+
if (i <= 0)
|
|
409
|
+
throw new Error(`Invalid devicePixelRatio: ${i}. Must be positive.`);
|
|
410
|
+
const o = Math.floor(a * i), c = Math.floor(s * i);
|
|
411
|
+
if (o === 0 || c === 0)
|
|
412
|
+
throw new Error(
|
|
413
|
+
`Computed canvas dimensions are zero: ${o}x${c}. CSS dimensions (${a}x${s}px) are too small for device pixel ratio ${i}. Minimum canvas size is 1px in CSS space.`
|
|
414
|
+
);
|
|
415
|
+
const h = r.gpuContext.device;
|
|
416
|
+
if (!h)
|
|
417
|
+
throw new Error("GPU device is not available");
|
|
418
|
+
const l = h.limits.maxTextureDimension2D, I = Math.max(1, Math.min(o, l)), w = Math.max(1, Math.min(c, l));
|
|
419
|
+
r.canvas.width = I, r.canvas.height = w;
|
|
420
|
+
const f = r.gpuContext.canvasContext, E = r.gpuContext.preferredFormat;
|
|
421
|
+
if (!f)
|
|
422
|
+
throw new Error("Canvas context is not available");
|
|
423
|
+
if (!E)
|
|
424
|
+
throw new Error("Preferred texture format is not available");
|
|
425
|
+
try {
|
|
426
|
+
f.configure({
|
|
427
|
+
device: h,
|
|
428
|
+
format: E,
|
|
429
|
+
alphaMode: r.gpuContext.alphaMode
|
|
430
|
+
});
|
|
431
|
+
} catch (v) {
|
|
432
|
+
throw new Error(
|
|
433
|
+
`Failed to reconfigure canvas context: ${v instanceof Error ? v.message : String(v)}`
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
t.requestRender && !r.state.renderPending && !r.state.disposed && (r.state.renderPending = !0, r.renderChannel.port2.postMessage(null));
|
|
437
|
+
} catch (r) {
|
|
438
|
+
const [a, s] = m(r);
|
|
439
|
+
this.emitError(e, "RENDER_ERROR", a, "resize", s);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Forwards a pointer event to the coordinator for interaction handling.
|
|
444
|
+
*
|
|
445
|
+
* @param chartId - Chart instance identifier
|
|
446
|
+
* @param event - Pre-computed pointer event data from main thread
|
|
447
|
+
*/
|
|
448
|
+
handlePointerEvent(e, t) {
|
|
449
|
+
try {
|
|
450
|
+
console.log("[ChartGPUWorkerController] Received pointer event:", {
|
|
451
|
+
type: t.type,
|
|
452
|
+
gridX: t.gridX,
|
|
453
|
+
gridY: t.gridY,
|
|
454
|
+
isInGrid: t.isInGrid
|
|
455
|
+
}), this.getChartInstance(e, "forwardPointerEvent").coordinator.handlePointerEvent(t);
|
|
456
|
+
} catch (r) {
|
|
457
|
+
const [a, s] = m(r);
|
|
458
|
+
this.emitError(e, "UNKNOWN", a, "forwardPointerEvent", s);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Sets the zoom range programmatically.
|
|
463
|
+
*
|
|
464
|
+
* @param chartId - Chart instance identifier
|
|
465
|
+
* @param start - Start position in percent space [0, 100]
|
|
466
|
+
* @param end - End position in percent space [0, 100]
|
|
467
|
+
*/
|
|
468
|
+
handleSetZoomRange(e, t, r) {
|
|
469
|
+
try {
|
|
470
|
+
if (t < 0 || t > 100 || r < 0 || r > 100)
|
|
471
|
+
throw new Error(`Invalid zoom range: [${t}, ${r}]. Values must be in [0, 100] (percent space).`);
|
|
472
|
+
if (t >= r)
|
|
473
|
+
throw new Error(`Invalid zoom range: start (${t}) must be less than end (${r}).`);
|
|
474
|
+
this.getChartInstance(e, "setZoomRange").coordinator.setZoomRange(t, r);
|
|
475
|
+
} catch (a) {
|
|
476
|
+
const [s, i] = m(a);
|
|
477
|
+
this.emitError(e, "UNKNOWN", s, "setZoomRange", i);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Sets the interaction X coordinate for synchronized crosshair display.
|
|
482
|
+
*
|
|
483
|
+
* @param chartId - Chart instance identifier
|
|
484
|
+
* @param x - X coordinate in CSS pixels, or null to clear
|
|
485
|
+
* @param source - Optional source identifier to prevent echo
|
|
486
|
+
*/
|
|
487
|
+
handleSetInteractionX(e, t, r) {
|
|
488
|
+
try {
|
|
489
|
+
this.getChartInstance(e, "setInteractionX").coordinator.setInteractionX(t, r);
|
|
490
|
+
} catch (a) {
|
|
491
|
+
const [s, i] = m(a);
|
|
492
|
+
this.emitError(e, "UNKNOWN", s, "setInteractionX", i);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Enables or disables animation, optionally updating animation configuration.
|
|
497
|
+
*
|
|
498
|
+
* @param chartId - Chart instance identifier
|
|
499
|
+
* @param enabled - Whether animation should be enabled
|
|
500
|
+
* @param config - Optional animation configuration
|
|
501
|
+
*/
|
|
502
|
+
handleSetAnimation(e, t, r) {
|
|
503
|
+
try {
|
|
504
|
+
const a = this.getChartInstance(e, "setAnimation");
|
|
505
|
+
t && !a.state.renderPending && !a.state.disposed && (a.state.renderPending = !0, a.renderChannel.port2.postMessage(null));
|
|
506
|
+
} catch (a) {
|
|
507
|
+
const [s, i] = m(a);
|
|
508
|
+
this.emitError(e, "UNKNOWN", s, "setAnimation", i);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Enables or disables GPU timing for performance metrics.
|
|
513
|
+
*
|
|
514
|
+
* @param chartId - Chart instance identifier
|
|
515
|
+
* @param enabled - Whether GPU timing should be enabled
|
|
516
|
+
*/
|
|
517
|
+
handleSetGPUTiming(e, t) {
|
|
518
|
+
try {
|
|
519
|
+
const r = this.getChartInstance(e, "setGPUTiming");
|
|
520
|
+
r.state.performance.gpuTimingEnabled = t;
|
|
521
|
+
} catch (r) {
|
|
522
|
+
const [a, s] = m(r);
|
|
523
|
+
this.emitError(e, "UNKNOWN", a, "setGPUTiming", s);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Calculates performance metrics from performance tracking state.
|
|
528
|
+
*
|
|
529
|
+
* @param perfState - Performance tracking state
|
|
530
|
+
* @returns Complete performance metrics
|
|
531
|
+
*/
|
|
532
|
+
calculatePerformanceMetrics(e) {
|
|
533
|
+
const t = this.calculateExactFPS(e), r = this.calculateFrameTimeStats(e), a = {
|
|
534
|
+
enabled: e.gpuTimingEnabled,
|
|
535
|
+
cpuTime: e.lastCPUTime,
|
|
536
|
+
gpuTime: e.lastGPUTime
|
|
537
|
+
}, s = {
|
|
538
|
+
used: 0,
|
|
539
|
+
peak: 0,
|
|
540
|
+
allocated: 0
|
|
541
|
+
}, i = {
|
|
542
|
+
totalDrops: e.totalDroppedFrames,
|
|
543
|
+
consecutiveDrops: e.consecutiveDroppedFrames,
|
|
544
|
+
lastDropTimestamp: e.lastDropTimestamp
|
|
545
|
+
}, o = performance.now() - e.startTime;
|
|
546
|
+
return {
|
|
547
|
+
fps: t,
|
|
548
|
+
frameTimeStats: r,
|
|
549
|
+
gpuTiming: a,
|
|
550
|
+
memory: s,
|
|
551
|
+
frameDrops: i,
|
|
552
|
+
totalFrames: e.totalFrames,
|
|
553
|
+
elapsedTime: o
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Calculates exact FPS from frame timestamp deltas.
|
|
558
|
+
*
|
|
559
|
+
* @param perfState - Performance tracking state
|
|
560
|
+
* @returns Exact FPS measurement
|
|
561
|
+
*/
|
|
562
|
+
calculateExactFPS(e) {
|
|
563
|
+
const t = e.frameTimestampCount;
|
|
564
|
+
if (t < 2)
|
|
565
|
+
return 0;
|
|
566
|
+
const r = e.frameTimestamps, a = (e.frameTimestampIndex - t + u) % u;
|
|
567
|
+
let s = 0;
|
|
568
|
+
for (let c = 1; c < t; c++) {
|
|
569
|
+
const h = (a + c - 1) % u, l = (a + c) % u, I = r[l] - r[h];
|
|
570
|
+
s += I;
|
|
571
|
+
}
|
|
572
|
+
const i = s / (t - 1);
|
|
573
|
+
return i > 0 ? 1e3 / i : 0;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Calculates frame time statistics.
|
|
577
|
+
*
|
|
578
|
+
* @param perfState - Performance tracking state
|
|
579
|
+
* @returns Frame time statistics
|
|
580
|
+
*/
|
|
581
|
+
calculateFrameTimeStats(e) {
|
|
582
|
+
const t = e.frameTimestampCount;
|
|
583
|
+
if (t < 2)
|
|
584
|
+
return {
|
|
585
|
+
min: 0,
|
|
586
|
+
max: 0,
|
|
587
|
+
avg: 0,
|
|
588
|
+
p50: 0,
|
|
589
|
+
p95: 0,
|
|
590
|
+
p99: 0
|
|
591
|
+
};
|
|
592
|
+
const r = e.frameTimestamps, a = (e.frameTimestampIndex - t + u) % u, s = new Array(t - 1);
|
|
593
|
+
let i = Number.POSITIVE_INFINITY, o = Number.NEGATIVE_INFINITY, c = 0;
|
|
594
|
+
for (let f = 1; f < t; f++) {
|
|
595
|
+
const E = (a + f - 1) % u, v = (a + f) % u, n = r[v] - r[E];
|
|
596
|
+
s[f - 1] = n, n < i && (i = n), n > o && (o = n), c += n;
|
|
597
|
+
}
|
|
598
|
+
const h = c / s.length;
|
|
599
|
+
s.sort((f, E) => f - E);
|
|
600
|
+
const l = Math.floor(s.length * 0.5), I = Math.floor(s.length * 0.95), w = Math.floor(s.length * 0.99);
|
|
601
|
+
return {
|
|
602
|
+
min: i,
|
|
603
|
+
max: o,
|
|
604
|
+
avg: h,
|
|
605
|
+
p50: s[l],
|
|
606
|
+
p95: s[I],
|
|
607
|
+
p99: s[w]
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Disposes a chart instance and cleans up all resources.
|
|
612
|
+
*
|
|
613
|
+
* @param chartId - Chart instance identifier
|
|
614
|
+
*/
|
|
615
|
+
disposeChart(e) {
|
|
616
|
+
const t = [];
|
|
617
|
+
try {
|
|
618
|
+
const r = this.charts.get(e);
|
|
619
|
+
if (!r) {
|
|
620
|
+
this.emitError(e, "UNKNOWN", `Chart "${e}" not found`, "dispose");
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if (r.state.disposed) {
|
|
624
|
+
this.emitError(e, "UNKNOWN", `Chart "${e}" is already disposed`, "dispose");
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
r.state.disposed = !0;
|
|
628
|
+
try {
|
|
629
|
+
r.renderChannel.port1.close(), r.renderChannel.port2.close();
|
|
630
|
+
} catch (a) {
|
|
631
|
+
t.push(`Failed to close render channel: ${a}`);
|
|
632
|
+
}
|
|
633
|
+
try {
|
|
634
|
+
r.coordinator.dispose();
|
|
635
|
+
} catch (a) {
|
|
636
|
+
t.push(`Failed to dispose coordinator: ${a}`);
|
|
637
|
+
}
|
|
638
|
+
try {
|
|
639
|
+
r.gpuContext = k(r.gpuContext);
|
|
640
|
+
} catch (a) {
|
|
641
|
+
t.push(`Failed to destroy GPU context: ${a}`);
|
|
642
|
+
}
|
|
643
|
+
this.charts.delete(e), this.emit({
|
|
644
|
+
type: "disposed",
|
|
645
|
+
chartId: e,
|
|
646
|
+
cleanupErrors: t.length > 0 ? t : void 0
|
|
647
|
+
});
|
|
648
|
+
} catch (r) {
|
|
649
|
+
const [a, s] = m(r);
|
|
650
|
+
this.emitError(e, "UNKNOWN", a, "dispose", s);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Disposes all chart instances and cleans up controller resources.
|
|
655
|
+
* Should be called when the worker is being terminated.
|
|
656
|
+
*
|
|
657
|
+
* Performance: Uses spread operator instead of Array.from() for slight efficiency gain.
|
|
658
|
+
*/
|
|
659
|
+
dispose() {
|
|
660
|
+
const e = [...this.charts.keys()];
|
|
661
|
+
for (const t of e)
|
|
662
|
+
this.disposeChart(t);
|
|
663
|
+
this.messageHandler = null;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Gets a chart instance by ID, throwing if not found, disposed, or device lost.
|
|
667
|
+
*
|
|
668
|
+
* @param chartId - Chart instance identifier
|
|
669
|
+
* @param operation - Operation name for error reporting
|
|
670
|
+
* @returns Chart instance
|
|
671
|
+
* @throws {Error} If chart not found, disposed, or device lost
|
|
672
|
+
*/
|
|
673
|
+
getChartInstance(e, t) {
|
|
674
|
+
const r = this.charts.get(e);
|
|
675
|
+
if (!r)
|
|
676
|
+
throw new Error(`Chart "${e}" not found for operation "${t}"`);
|
|
677
|
+
if (r.state.disposed)
|
|
678
|
+
throw new Error(`Chart "${e}" is disposed and cannot perform "${t}"`);
|
|
679
|
+
if (r.state.deviceLost)
|
|
680
|
+
throw new Error(`Chart "${e}" GPU device is lost and cannot perform "${t}". Re-initialize the chart.`);
|
|
681
|
+
return r;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Emits an outbound message to the main thread.
|
|
685
|
+
*
|
|
686
|
+
* @param msg - Outbound message to send
|
|
687
|
+
*/
|
|
688
|
+
emit(e) {
|
|
689
|
+
this.messageHandler ? this.messageHandler(e) : console.warn("No message handler registered, dropping message:", e);
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Emits an error message to the main thread.
|
|
693
|
+
*
|
|
694
|
+
* @param chartId - Chart instance identifier
|
|
695
|
+
* @param code - Error code for categorization
|
|
696
|
+
* @param message - Error message
|
|
697
|
+
* @param operation - Operation that failed
|
|
698
|
+
* @param stack - Optional stack trace
|
|
699
|
+
* @param messageId - Optional message ID for correlation
|
|
700
|
+
*/
|
|
701
|
+
emitError(e, t, r, a, s, i) {
|
|
702
|
+
const o = {
|
|
703
|
+
type: "error",
|
|
704
|
+
chartId: e,
|
|
705
|
+
code: t,
|
|
706
|
+
message: r,
|
|
707
|
+
operation: a,
|
|
708
|
+
stack: s,
|
|
709
|
+
messageId: i
|
|
710
|
+
};
|
|
711
|
+
this.emit(o);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
function U(d, e, t) {
|
|
715
|
+
if (!d)
|
|
716
|
+
throw new Error("Buffer is null or undefined");
|
|
717
|
+
if (!Number.isInteger(e) || e < 0)
|
|
718
|
+
throw new Error(`Invalid pointCount: ${e}. Must be a non-negative integer.`);
|
|
719
|
+
if (!Number.isInteger(t) || t <= 0)
|
|
720
|
+
throw new Error(`Invalid stride: ${t}. Must be a positive integer.`);
|
|
721
|
+
if (d.byteLength === 0 && e > 0)
|
|
722
|
+
throw new Error(
|
|
723
|
+
"Buffer is detached (byteLength = 0). The ArrayBuffer may have been transferred multiple times. Each ArrayBuffer can only be transferred once via postMessage."
|
|
724
|
+
);
|
|
725
|
+
if (d.byteLength % 4 !== 0)
|
|
726
|
+
throw new Error(
|
|
727
|
+
`Buffer size (${d.byteLength} bytes) is not 4-byte aligned. WebGPU requires all buffer sizes to be multiples of 4 bytes.`
|
|
728
|
+
);
|
|
729
|
+
if (t % 4 !== 0)
|
|
730
|
+
throw new Error(
|
|
731
|
+
`Stride (${t} bytes) is not 4-byte aligned. Float32 data requires stride to be a multiple of 4 bytes.`
|
|
732
|
+
);
|
|
733
|
+
const r = e * t;
|
|
734
|
+
if (d.byteLength !== r)
|
|
735
|
+
throw new Error(
|
|
736
|
+
`Buffer size mismatch: expected ${r} bytes (${e} points × ${t} bytes), got ${d.byteLength} bytes. Difference: ${d.byteLength - r} bytes.`
|
|
737
|
+
);
|
|
738
|
+
const a = new Float32Array(d), s = t / 4, i = e * s;
|
|
739
|
+
if (a.length !== i)
|
|
740
|
+
throw new Error(
|
|
741
|
+
`Float32Array length mismatch: expected ${i} elements, got ${a.length} elements`
|
|
742
|
+
);
|
|
743
|
+
if (t === 8) {
|
|
744
|
+
const o = new Array(e);
|
|
745
|
+
for (let c = 0, h = 0; c < e; c++, h += 2)
|
|
746
|
+
o[c] = [a[h], a[h + 1]];
|
|
747
|
+
return o;
|
|
748
|
+
} else if (t === 20) {
|
|
749
|
+
const o = new Array(e);
|
|
750
|
+
for (let c = 0, h = 0; c < e; c++, h += 5)
|
|
751
|
+
o[c] = [
|
|
752
|
+
a[h],
|
|
753
|
+
// timestamp (index 0 → 0)
|
|
754
|
+
a[h + 1],
|
|
755
|
+
// open (index 1 → 1)
|
|
756
|
+
a[h + 4],
|
|
757
|
+
// close (index 4 → 2) ← reordered
|
|
758
|
+
a[h + 3],
|
|
759
|
+
// low (index 3 → 3)
|
|
760
|
+
a[h + 2]
|
|
761
|
+
// high (index 2 → 4) ← reordered
|
|
762
|
+
];
|
|
763
|
+
return o;
|
|
764
|
+
} else
|
|
765
|
+
throw new Error(
|
|
766
|
+
`Invalid stride: ${t} bytes. Expected 8 (DataPoint) or 20 (OHLCDataPoint). Received stride corresponds to ${t / 4} floats per point.`
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
export {
|
|
770
|
+
L as C
|
|
771
|
+
};
|
|
772
|
+
//# sourceMappingURL=ChartGPUWorkerController-B50J-8sx.js.map
|