@vroomchart/core-wasm 0.1.0 → 0.1.1

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/handle.ts","../src/color.ts","../src/packCandles.ts","../src/stub/stubModule.ts","../src/wasm/adapter.ts","../src/wasm/loadWasm.ts","../src/index.ts"],"sourcesContent":["// The low-level contract for one chart instance on the web.\n//\n// This mirrors the C facade (packages/core/include/vroom/vroom_chart.h) and the\n// native JSI handle (packages/react-native/src/jsi.d.ts) — but WITHOUT the\n// SkPicture return values. On web the core (A1c) owns the <canvas> and its\n// rendering surface, so mutations are `void` and `present()` paints. Today this\n// is backed by a Canvas2D stub (./stub); later by the Skia-WASM module, with no\n// change to this interface or to @vroomchart/react.\n\n/** Theme color slots — mirrors the `VroomColorKey` enum in the C facade. */\nexport enum ColorKey {\n Background = 0,\n Bull = 1,\n Bear = 2,\n Wick = 3,\n Grid = 4,\n AxisText = 5,\n Crosshair = 6,\n TooltipBg = 7,\n TooltipText = 8,\n CrosshairTarget = 9,\n}\n\n/** OHLCV readout for the candle under the crosshair. */\nexport type CrosshairCandle = {\n timeMs: number;\n open: number;\n high: number;\n low: number;\n close: number;\n volume: number;\n};\n\n/** Axis region sizes in CSS px, for hit-testing gestures on the JS side. */\nexport type AxisMetrics = {\n yAxisWidth: number;\n xAxisHeight: number;\n /** Below-chart indicator pane height; 0 when no pane is shown. */\n indicatorHeight: number;\n};\n\n/** A moving-average overlay line, in the core's numeric encoding. */\nexport type OverlaySpec = {\n /** 0 = SMA, 1 = EMA. */\n kind: number;\n period: number;\n /** 0=close,1=open,2=high,3=low,4=hl2,5=hlc3,6=ohlc4 */\n source: number;\n /** Packed 0xAARRGGBB. */\n color: number;\n /** Stroke width in px. */\n width: number;\n};\n\n/**\n * A single chart instance bound to a canvas. Method semantics match the native\n * handle one-to-one (see jsi.d.ts) so the two platforms behave identically.\n */\nexport interface VroomChartHandle {\n /** Replace the full candle series (packed buffer; see packCandles). */\n setCandles(packed: ArrayBuffer): void;\n /** Set the drawing size in CSS px plus the device pixel ratio. */\n setSize(width: number, height: number, dpr: number): void;\n /** Override one theme color. `argb` is packed 0xAARRGGBB. */\n setColor(key: ColorKey | number, argb: number): void;\n /** Pass 0, 0 to show all candles. */\n setVisibleRange(startMs: number, endMs: number): void;\n\n /** Shift the visible range by dx/dy CSS px. */\n pan(dx: number, dy: number): void;\n /** Shift the time window and price bounds without rescaling. */\n translate(dx: number, dy: number): void;\n /** Directional zoom by per-axis factors around focus (fx, fy) in px. */\n zoom(scaleX: number, scaleY: number, fx: number, fy: number): void;\n /** Drag-on-y-axis price scaling; dy>0 widens the price range. */\n scalePriceAxis(dy: number): void;\n /** Drag-on-x-axis time scaling; dx>0 widens the time window. */\n scaleTimeAxis(dx: number): void;\n\n /** Current axis dimensions for hit-testing in JS gestures. */\n getAxisMetrics(): AxisMetrics;\n\n /** Show the crosshair at (x, y) CSS px (y already lifted above the pointer). */\n setCrosshair(x: number, y: number): void;\n /** Hide the crosshair. */\n clearCrosshair(): void;\n /** OHLCV of the candle the crosshair snaps to, or null when inactive. */\n getCrosshairCandle(): CrosshairCandle | null;\n\n setRSI(\n enabled: boolean,\n period: number,\n upperBand: number,\n lowerBand: number,\n maEnabled: boolean,\n maPeriod: number,\n ): void;\n setMACD(enabled: boolean, fast: number, slow: number, signal: number): void;\n setOverlays(overlays: OverlaySpec[]): void;\n setVWAP(\n enabled: boolean,\n resetOffsetMin: number,\n color: number,\n width: number,\n ): void;\n\n /** True while any axis-label fade is in progress (drives the rAF loop). */\n isAnimating(): boolean;\n /** Paint the current state to the canvas. */\n present(): void;\n /** Release resources; the handle is unusable afterward. */\n destroy(): void;\n}\n\n/** Factory for chart instances. The loaded core module implements this. */\nexport interface VroomModule {\n /** Create a chart bound to `canvas`, attaching its rendering surface. */\n create(canvas: HTMLCanvasElement): VroomChartHandle;\n}\n","import type { VroomColor, VroomTheme } from '@vroomchart/types';\nimport { ColorKey, type VroomChartHandle } from './handle';\n\n// Maps each VroomTheme field to its ColorKey. Mirror of\n// packages/react-native/src/theme.ts (which keys off the same C enum).\nexport const COLOR_KEYS: Record<keyof VroomTheme, ColorKey> = {\n background: ColorKey.Background,\n bull: ColorKey.Bull,\n bear: ColorKey.Bear,\n grid: ColorKey.Grid,\n axisText: ColorKey.AxisText,\n crosshair: ColorKey.Crosshair,\n crosshairTarget: ColorKey.CrosshairTarget,\n};\n\n/**\n * Parse a color into a packed 0xAARRGGBB integer (Skia's ARGB order).\n * - number → taken as already-packed ARGB\n * - 6-digit hex → opaque (alpha forced to ff)\n * - 8-digit hex → interpreted as AARRGGBB\n * Returns null for anything malformed so the caller can skip it.\n */\nexport function parseColor(value: VroomColor): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value >>> 0 : null;\n }\n let s = value.trim();\n if (s.startsWith('#')) s = s.slice(1);\n if (s.length === 6) s = `ff${s}`;\n if (s.length !== 8 || !/^[0-9a-fA-F]{8}$/.test(s)) return null;\n return parseInt(s, 16) >>> 0;\n}\n\n/** Push every provided theme color into the handle; skip unparseable ones. */\nexport function applyTheme(handle: VroomChartHandle, theme: VroomTheme): void {\n (Object.keys(COLOR_KEYS) as (keyof VroomTheme)[]).forEach((field) => {\n const value = theme[field];\n if (value == null) return;\n const argb = parseColor(value);\n if (argb == null) return;\n handle.setColor(COLOR_KEYS[field], argb);\n });\n}\n\n/** Split a packed 0xAARRGGBB integer into a CSS `rgba(...)` string. */\nexport function argbToCss(argb: number): string {\n const a = ((argb >>> 24) & 0xff) / 255;\n const r = (argb >>> 16) & 0xff;\n const g = (argb >>> 8) & 0xff;\n const b = argb & 0xff;\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n","import type { Candle } from '@vroomchart/types';\n\n// Wire format must match `VroomCandle` in packages/core/include/vroom/vroom_chart.h:\n// int64_t time_ms; double open, high, low, close, volume;\n// = 48 bytes per candle, 8-byte aligned, little-endian.\n//\n// This is a deliberate mirror of packages/react-native/src/packCandles.ts so\n// the web side speaks the same binary ABI the Skia-WASM core will decode. Keep\n// the two in sync with the C struct.\nexport const BYTES_PER_CANDLE = 48;\n\n/** Serialize candles into the packed little-endian buffer the core expects. */\nexport function packCandles(candles: Candle[]): ArrayBuffer {\n const buf = new ArrayBuffer(candles.length * BYTES_PER_CANDLE);\n const view = new DataView(buf);\n for (let i = 0; i < candles.length; i++) {\n const c = candles[i]!;\n const off = i * BYTES_PER_CANDLE;\n view.setBigInt64(off, BigInt(Math.trunc(c.timeMs)), true);\n view.setFloat64(off + 8, c.open, true);\n view.setFloat64(off + 16, c.high, true);\n view.setFloat64(off + 24, c.low, true);\n view.setFloat64(off + 32, c.close, true);\n view.setFloat64(off + 40, c.volume, true);\n }\n return buf;\n}\n\n/** Decode the packed buffer back to candles (used by the Canvas2D stub core). */\nexport function unpackCandles(buf: ArrayBuffer): Candle[] {\n const view = new DataView(buf);\n const n = Math.floor(buf.byteLength / BYTES_PER_CANDLE);\n const out: Candle[] = new Array(n);\n for (let i = 0; i < n; i++) {\n const off = i * BYTES_PER_CANDLE;\n out[i] = {\n timeMs: Number(view.getBigInt64(off, true)),\n open: view.getFloat64(off + 8, true),\n high: view.getFloat64(off + 16, true),\n low: view.getFloat64(off + 24, true),\n close: view.getFloat64(off + 32, true),\n volume: view.getFloat64(off + 40, true),\n };\n }\n return out;\n}\n","// Canvas2D stub of the chart core.\n//\n// A pure-TS stand-in for the Skia-WASM core so @vroomchart/react can be built and\n// run in a browser before the WASM toolchain exists. It implements the same\n// VroomChartHandle contract and the same viewport model as the C++ core\n// (count-based default window, fixed candle slots, persistent price bounds),\n// drawing candles / axes / crosshair with the Canvas2D API.\n//\n// Intentional gaps vs. the real core: indicators (RSI/MACD/MA/VWAP) and volume\n// bars are accepted but not drawn, and there's no label-fade animation. Swapping\n// loadVroom() to the WASM module replaces this with pixel-accurate rendering and\n// no API change.\n\nimport type { Candle } from '@vroomchart/types';\nimport {\n ColorKey,\n type AxisMetrics,\n type CrosshairCandle,\n type OverlaySpec,\n type VroomChartHandle,\n type VroomModule,\n} from '../handle';\nimport { argbToCss } from '../color';\nimport { unpackCandles } from '../packCandles';\n\nconst DEFAULT_VISIBLE = 80; // matches the core's kDefaultVisible\nconst Y_AXIS_W = 58;\nconst X_AXIS_H = 22;\nconst RIGHT_PAD_CANDLES = 4; // empty future slots past the last candle\n\n// Default theme — mirrors the core's defaults closely enough for the stub.\nconst DEFAULT_COLORS: Record<number, number> = {\n [ColorKey.Background]: 0xff0d1117,\n [ColorKey.Bull]: 0xff26a69a,\n [ColorKey.Bear]: 0xffef5350,\n [ColorKey.Wick]: 0xff787b86,\n [ColorKey.Grid]: 0xff1f2630,\n [ColorKey.AxisText]: 0xff8b949e,\n [ColorKey.Crosshair]: 0xffc9d1d9,\n [ColorKey.CrosshairTarget]: 0xffc9d1d9,\n};\n\nfunction median(xs: number[]): number {\n if (xs.length === 0) return 0;\n const s = [...xs].sort((a, b) => a - b);\n const mid = s.length >> 1;\n return s.length % 2 ? s[mid]! : (s[mid - 1]! + s[mid]!) / 2;\n}\n\n// A \"nice\" axis step (1/2/5 × 10^n) at or just above `raw`.\nfunction niceStep(raw: number): number {\n if (raw <= 0 || !Number.isFinite(raw)) return 1;\n const mag = Math.pow(10, Math.floor(Math.log10(raw)));\n const norm = raw / mag;\n const step = norm <= 1 ? 1 : norm <= 2 ? 2 : norm <= 5 ? 5 : 10;\n return step * mag;\n}\n\nclass StubChart implements VroomChartHandle {\n private ctx: CanvasRenderingContext2D;\n private candles: Candle[] = [];\n private durationMs = 60_000;\n\n private wCss = 0;\n private hCss = 0;\n private dpr = 1;\n\n private visStart = 0;\n private visEnd = 0;\n private priceMin = 0;\n private priceMax = 1;\n private rangeInit = false;\n\n private crosshair = false;\n private chX = 0;\n private chY = 0;\n\n private colors: Record<number, number> = { ...DEFAULT_COLORS };\n\n constructor(private canvas: HTMLCanvasElement) {\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('VroomChart stub: 2D canvas context unavailable');\n this.ctx = ctx;\n }\n\n // --- geometry helpers ---------------------------------------------------\n private get plotW() {\n return Math.max(0, this.wCss - Y_AXIS_W);\n }\n private get plotH() {\n return Math.max(0, this.hCss - X_AXIS_H);\n }\n private xOf(timeMs: number) {\n const span = this.visEnd - this.visStart || 1;\n return ((timeMs - this.visStart) / span) * this.plotW;\n }\n private yOf(price: number) {\n const span = this.priceMax - this.priceMin || 1;\n return ((this.priceMax - price) / span) * this.plotH;\n }\n private color(key: number) {\n return argbToCss(this.colors[key] ?? DEFAULT_COLORS[key] ?? 0xff000000);\n }\n\n // --- data ---------------------------------------------------------------\n setCandles(packed: ArrayBuffer): void {\n this.candles = unpackCandles(packed);\n if (this.candles.length >= 2) {\n const diffs: number[] = [];\n for (let i = 1; i < this.candles.length; i++) {\n diffs.push(this.candles[i]!.timeMs - this.candles[i - 1]!.timeMs);\n }\n const m = median(diffs);\n if (m > 0) this.durationMs = m;\n }\n if (!this.rangeInit) this.resetWindow();\n this.recomputePriceBounds();\n }\n\n private resetWindow(): void {\n const n = this.candles.length;\n if (n === 0) {\n this.visStart = 0;\n this.visEnd = 1;\n return;\n }\n const last = this.candles[n - 1]!.timeMs;\n this.visEnd = last + this.durationMs * RIGHT_PAD_CANDLES;\n this.visStart = this.visEnd - this.durationMs * (DEFAULT_VISIBLE + RIGHT_PAD_CANDLES);\n this.rangeInit = true;\n }\n\n private recomputePriceBounds(): void {\n let lo = Infinity;\n let hi = -Infinity;\n for (const c of this.candles) {\n if (c.timeMs < this.visStart || c.timeMs > this.visEnd) continue;\n if (c.low < lo) lo = c.low;\n if (c.high > hi) hi = c.high;\n }\n if (!Number.isFinite(lo) || !Number.isFinite(hi) || hi <= lo) {\n // No visible candles (or flat): keep prior bounds if sensible.\n if (this.priceMax > this.priceMin) return;\n lo = 0;\n hi = 1;\n }\n const pad = (hi - lo) * 0.08;\n this.priceMin = lo - pad;\n this.priceMax = hi + pad;\n }\n\n // --- sizing -------------------------------------------------------------\n setSize(width: number, height: number, dpr: number): void {\n this.wCss = width;\n this.hCss = height;\n this.dpr = dpr || 1;\n this.canvas.width = Math.max(1, Math.round(width * this.dpr));\n this.canvas.height = Math.max(1, Math.round(height * this.dpr));\n this.ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);\n }\n\n setColor(key: number, argb: number): void {\n this.colors[key] = argb >>> 0;\n }\n\n setVisibleRange(startMs: number, endMs: number): void {\n if (startMs === 0 && endMs === 0) {\n this.rangeInit = false;\n this.resetWindow();\n } else {\n this.visStart = startMs;\n this.visEnd = endMs;\n this.rangeInit = true;\n }\n this.recomputePriceBounds();\n }\n\n // --- viewport mutators --------------------------------------------------\n pan(dx: number, dy: number): void {\n this.translate(dx, dy);\n }\n\n translate(dx: number, dy: number): void {\n const span = this.visEnd - this.visStart;\n const dt = (dx / (this.plotW || 1)) * span;\n this.visStart -= dt;\n this.visEnd -= dt;\n if (dy) {\n const pspan = this.priceMax - this.priceMin;\n const dp = (dy / (this.plotH || 1)) * pspan;\n this.priceMin += dp;\n this.priceMax += dp;\n }\n }\n\n zoom(scaleX: number, scaleY: number, fx: number, fy: number): void {\n if (scaleX !== 1) {\n const span = this.visEnd - this.visStart;\n const focalT = this.visStart + (fx / (this.plotW || 1)) * span;\n const newSpan = span / scaleX;\n this.visStart = focalT - (fx / (this.plotW || 1)) * newSpan;\n this.visEnd = this.visStart + newSpan;\n }\n if (scaleY !== 1) {\n const pspan = this.priceMax - this.priceMin;\n const focalP = this.priceMax - (fy / (this.plotH || 1)) * pspan;\n const newSpan = pspan / scaleY;\n this.priceMax = focalP + (fy / (this.plotH || 1)) * newSpan;\n this.priceMin = this.priceMax - newSpan;\n }\n }\n\n scalePriceAxis(dy: number): void {\n const factor = Math.max(0.1, 1 + dy / (this.plotH || 1));\n const center = (this.priceMin + this.priceMax) / 2;\n const half = ((this.priceMax - this.priceMin) / 2) * factor;\n this.priceMin = center - half;\n this.priceMax = center + half;\n }\n\n scaleTimeAxis(dx: number): void {\n const factor = Math.max(0.1, 1 + dx / (this.plotW || 1));\n const span = (this.visEnd - this.visStart) * factor;\n this.visStart = this.visEnd - span;\n }\n\n getAxisMetrics(): AxisMetrics {\n return { yAxisWidth: Y_AXIS_W, xAxisHeight: X_AXIS_H, indicatorHeight: 0 };\n }\n\n // --- crosshair ----------------------------------------------------------\n setCrosshair(x: number, y: number): void {\n this.crosshair = true;\n this.chX = x;\n this.chY = y;\n }\n clearCrosshair(): void {\n this.crosshair = false;\n }\n private snapIndex(): number {\n if (this.candles.length === 0) return -1;\n const span = this.visEnd - this.visStart || 1;\n const t = this.visStart + (this.chX / (this.plotW || 1)) * span;\n let best = -1;\n let bestD = Infinity;\n for (let i = 0; i < this.candles.length; i++) {\n const d = Math.abs(this.candles[i]!.timeMs - t);\n if (d < bestD) {\n bestD = d;\n best = i;\n }\n }\n return best;\n }\n getCrosshairCandle(): CrosshairCandle | null {\n if (!this.crosshair) return null;\n const i = this.snapIndex();\n if (i < 0) return null;\n const c = this.candles[i]!;\n return { ...c };\n }\n\n // --- indicators (accepted, not drawn in the stub) -----------------------\n setRSI(): void {}\n setMACD(): void {}\n setOverlays(_overlays: OverlaySpec[]): void {}\n setVWAP(): void {}\n\n isAnimating(): boolean {\n return false;\n }\n\n // --- rendering ----------------------------------------------------------\n present(): void {\n const ctx = this.ctx;\n const w = this.wCss;\n const h = this.hCss;\n if (w <= 0 || h <= 0) return;\n\n ctx.clearRect(0, 0, w, h);\n ctx.fillStyle = this.color(ColorKey.Background);\n ctx.fillRect(0, 0, w, h);\n\n this.drawPriceAxis();\n this.drawTimeAxis();\n this.drawCandles();\n if (this.crosshair) this.drawCrosshair();\n }\n\n private priceTicks(): number[] {\n const span = this.priceMax - this.priceMin;\n if (span <= 0) return [];\n const step = niceStep(span / 5);\n const first = Math.ceil(this.priceMin / step) * step;\n const out: number[] = [];\n for (let p = first; p <= this.priceMax; p += step) out.push(p);\n return out;\n }\n\n private fmtPrice(p: number): string {\n const span = this.priceMax - this.priceMin;\n const decimals = span < 1 ? 4 : span < 100 ? 2 : 0;\n return p.toFixed(decimals);\n }\n\n private drawPriceAxis(): void {\n const ctx = this.ctx;\n const plotW = this.plotW;\n ctx.lineWidth = 1;\n ctx.strokeStyle = this.color(ColorKey.Grid);\n ctx.fillStyle = this.color(ColorKey.AxisText);\n ctx.font = '11px -apple-system, system-ui, \"Segoe UI\", sans-serif';\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n for (const p of this.priceTicks()) {\n const y = this.yOf(p);\n if (y < 0 || y > this.plotH) continue;\n ctx.beginPath();\n ctx.moveTo(0, Math.round(y) + 0.5);\n ctx.lineTo(plotW, Math.round(y) + 0.5);\n ctx.stroke();\n ctx.fillText(this.fmtPrice(p), plotW + 6, y);\n }\n }\n\n private fmtTime(timeMs: number): string {\n const d = new Date(timeMs);\n const span = this.visEnd - this.visStart;\n const twoDays = 2 * 24 * 3600 * 1000;\n const pad = (n: number) => String(n).padStart(2, '0');\n if (span < twoDays) return `${pad(d.getHours())}:${pad(d.getMinutes())}`;\n return `${d.getMonth() + 1}/${d.getDate()}`;\n }\n\n private drawTimeAxis(): void {\n const ctx = this.ctx;\n const span = this.visEnd - this.visStart;\n if (span <= 0) return;\n const targetPx = 80;\n const stepMs = niceStep((span / this.plotW) * targetPx);\n const first = Math.ceil(this.visStart / stepMs) * stepMs;\n ctx.fillStyle = this.color(ColorKey.AxisText);\n ctx.font = '11px -apple-system, system-ui, \"Segoe UI\", sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n const y = this.plotH + X_AXIS_H / 2;\n for (let t = first; t <= this.visEnd; t += stepMs) {\n const x = this.xOf(t);\n if (x < 0 || x > this.plotW) continue;\n ctx.fillText(this.fmtTime(t), x, y);\n }\n }\n\n private drawCandles(): void {\n const ctx = this.ctx;\n const span = this.visEnd - this.visStart || 1;\n const slotW = (this.durationMs / span) * this.plotW;\n const bodyW = Math.max(1, slotW * 0.7);\n const bull = this.color(ColorKey.Bull);\n const bear = this.color(ColorKey.Bear);\n const wick = this.color(ColorKey.Wick);\n\n for (const c of this.candles) {\n const x = this.xOf(c.timeMs);\n if (x < -slotW || x > this.plotW + slotW) continue;\n const up = c.close >= c.open;\n const yHigh = this.yOf(c.high);\n const yLow = this.yOf(c.low);\n const yOpen = this.yOf(c.open);\n const yClose = this.yOf(c.close);\n\n // wick\n ctx.strokeStyle = wick;\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.moveTo(Math.round(x) + 0.5, yHigh);\n ctx.lineTo(Math.round(x) + 0.5, yLow);\n ctx.stroke();\n\n // body\n ctx.fillStyle = up ? bull : bear;\n const top = Math.min(yOpen, yClose);\n const bodyH = Math.max(1, Math.abs(yClose - yOpen));\n ctx.fillRect(x - bodyW / 2, top, bodyW, bodyH);\n }\n }\n\n private drawCrosshair(): void {\n const ctx = this.ctx;\n const i = this.snapIndex();\n if (i < 0) return;\n const c = this.candles[i]!;\n const x = this.xOf(c.timeMs);\n const y = Math.max(0, Math.min(this.plotH, this.chY));\n\n ctx.save();\n ctx.strokeStyle = this.color(ColorKey.Crosshair);\n ctx.lineWidth = 1;\n ctx.setLineDash([4, 4]);\n ctx.beginPath();\n ctx.moveTo(Math.round(x) + 0.5, 0);\n ctx.lineTo(Math.round(x) + 0.5, this.plotH);\n ctx.moveTo(0, Math.round(y) + 0.5);\n ctx.lineTo(this.plotW, Math.round(y) + 0.5);\n ctx.stroke();\n ctx.setLineDash([]);\n\n // target ring at the close\n const ty = this.yOf(c.close);\n ctx.strokeStyle = this.color(ColorKey.CrosshairTarget);\n ctx.beginPath();\n ctx.arc(x, ty, 3.5, 0, Math.PI * 2);\n ctx.stroke();\n ctx.restore();\n }\n\n destroy(): void {\n this.candles = [];\n }\n}\n\nexport function createStubModule(): VroomModule {\n return {\n create(canvas: HTMLCanvasElement): VroomChartHandle {\n return new StubChart(canvas);\n },\n };\n}\n","// Adapts the emscripten `WebChart` (embind class from web/vroom_web.cpp) to the\n// VroomChartHandle / VroomModule contract that @vroomchart/react consumes. This is\n// the only place that knows the WASM module's shape — swapping the stub for the\n// real core changes nothing above this line.\n\nimport type {\n AxisMetrics,\n CrosshairCandle,\n OverlaySpec,\n VroomChartHandle,\n VroomModule,\n} from '../handle';\n\n// The embind class instance. Methods mirror web/vroom_web.cpp; `delete()` frees\n// the C++ object (embind requires explicit disposal).\ninterface WebChartInstance {\n setCandles(bytes: Uint8Array): void;\n setSize(width: number, height: number, dpr: number): void;\n setColor(key: number, argb: number): void;\n setVisibleRange(startMs: number, endMs: number): void;\n pan(dx: number, dy: number): void;\n translate(dx: number, dy: number): void;\n zoom(sx: number, sy: number, fx: number, fy: number): void;\n scalePriceAxis(dy: number): void;\n scaleTimeAxis(dx: number): void;\n getAxisMetrics(): AxisMetrics;\n setCrosshair(x: number, y: number): void;\n clearCrosshair(): void;\n getCrosshairCandle(): CrosshairCandle | null;\n setRSI(e: boolean, p: number, u: number, l: number, mae: boolean, map: number): void;\n setMACD(e: boolean, f: number, s: number, sig: number): void;\n setOverlays(overlays: OverlaySpec[]): void;\n setVWAP(e: boolean, reset: number, color: number, width: number): void;\n setTypeface(bytes: Uint8Array): void;\n isAnimating(): boolean;\n present(): void;\n delete(): void;\n}\n\n/** The shape of the instantiated emscripten module we depend on. */\nexport interface VroomWasmModule {\n WebChart: new (canvasSelector: string) => WebChartInstance;\n}\n\nlet uid = 0;\n\nclass WasmHandle implements VroomChartHandle {\n constructor(private wc: WebChartInstance) {}\n\n setCandles(packed: ArrayBuffer): void {\n this.wc.setCandles(new Uint8Array(packed));\n }\n setSize(width: number, height: number, dpr: number): void {\n this.wc.setSize(width, height, dpr);\n }\n setColor(key: number, argb: number): void {\n this.wc.setColor(key, argb >>> 0);\n }\n setVisibleRange(startMs: number, endMs: number): void {\n this.wc.setVisibleRange(startMs, endMs);\n }\n pan(dx: number, dy: number): void {\n this.wc.pan(dx, dy);\n }\n translate(dx: number, dy: number): void {\n this.wc.translate(dx, dy);\n }\n zoom(scaleX: number, scaleY: number, fx: number, fy: number): void {\n this.wc.zoom(scaleX, scaleY, fx, fy);\n }\n scalePriceAxis(dy: number): void {\n this.wc.scalePriceAxis(dy);\n }\n scaleTimeAxis(dx: number): void {\n this.wc.scaleTimeAxis(dx);\n }\n getAxisMetrics(): AxisMetrics {\n return this.wc.getAxisMetrics();\n }\n setCrosshair(x: number, y: number): void {\n this.wc.setCrosshair(x, y);\n }\n clearCrosshair(): void {\n this.wc.clearCrosshair();\n }\n getCrosshairCandle(): CrosshairCandle | null {\n return this.wc.getCrosshairCandle();\n }\n setRSI(\n enabled: boolean,\n period: number,\n upperBand: number,\n lowerBand: number,\n maEnabled: boolean,\n maPeriod: number,\n ): void {\n this.wc.setRSI(enabled, period, upperBand, lowerBand, maEnabled, maPeriod);\n }\n setMACD(enabled: boolean, fast: number, slow: number, signal: number): void {\n this.wc.setMACD(enabled, fast, slow, signal);\n }\n setOverlays(overlays: OverlaySpec[]): void {\n this.wc.setOverlays(overlays);\n }\n setVWAP(enabled: boolean, resetOffsetMin: number, color: number, width: number): void {\n this.wc.setVWAP(enabled, resetOffsetMin, color >>> 0, width);\n }\n isAnimating(): boolean {\n return this.wc.isAnimating();\n }\n present(): void {\n this.wc.present();\n }\n destroy(): void {\n this.wc.delete();\n }\n}\n\n/**\n * Wrap an instantiated WASM module as a VroomModule. `fontBytes` (a .ttf/.otf)\n * is installed as the axis typeface on each chart — required for text labels,\n * since the WASM sandbox has no system fonts.\n */\nexport function makeWasmModule(\n module: VroomWasmModule,\n fontBytes: Uint8Array | null,\n): VroomModule {\n return {\n create(canvas: HTMLCanvasElement) {\n if (!canvas.id) canvas.id = `vroom-canvas-${uid++}`;\n const wc = new module.WebChart(`#${canvas.id}`);\n if (fontBytes) wc.setTypeface(fontBytes);\n return new WasmHandle(wc);\n },\n };\n}\n","// Instantiates the Skia-WASM core (the emscripten ES module built from\n// packages/core/web + CMake VROOM_WASM) and adapts it to a VroomModule.\n//\n// The module URL is resolved at runtime (not statically imported) so bundlers\n// don't try to resolve a not-yet-built artifact — keeping the stub-only build\n// green until the WASM file actually exists.\n\nimport type { VroomModule } from '../handle';\nimport { makeWasmModule, type VroomWasmModule } from './adapter';\n\nexport type WasmConfig = {\n /** URL to the emscripten ES module (vroom_core.mjs). */\n moduleUrl: string;\n /** URL to vroom_core.wasm. Defaults to resolving next to the module. */\n wasmUrl?: string;\n /** URL to a .ttf/.otf used for axis/price/time labels. */\n fontUrl?: string;\n};\n\n// The emscripten MODULARIZE/EXPORT_ES6 default export is a factory:\n// createVroomCore(moduleOverrides) => Promise<Module>\ntype EmscriptenFactory = (overrides?: Record<string, unknown>) => Promise<VroomWasmModule>;\n\n// Import the emscripten ES module from a runtime URL WITHOUT the bundler trying\n// to resolve/transform it. A plain import(url) (even with /* @vite-ignore */) is\n// still intercepted by Vite's \"don't import from /public\" guard and by other\n// bundlers' static analysis. Routing through Function keeps it fully opaque.\n// (Requires 'unsafe-eval' under a strict CSP — self-host the module differently\n// if that's a constraint.)\nconst dynamicImport = new Function('u', 'return import(u)') as (\n u: string,\n) => Promise<{ default: EmscriptenFactory }>;\n\nexport async function loadWasmCore(cfg: WasmConfig): Promise<VroomModule> {\n const mod = await dynamicImport(cfg.moduleUrl);\n const instance = await mod.default({\n locateFile: (path: string) =>\n path.endsWith('.wasm') && cfg.wasmUrl ? cfg.wasmUrl : path,\n });\n\n let fontBytes: Uint8Array | null = null;\n if (cfg.fontUrl) {\n try {\n const res = await fetch(cfg.fontUrl);\n if (res.ok) {\n fontBytes = new Uint8Array(await res.arrayBuffer());\n console.info(`[vroom] axis font loaded (${cfg.fontUrl}, ${fontBytes.length} bytes)`);\n } else {\n console.warn(`[vroom] axis font fetch ${cfg.fontUrl} → HTTP ${res.status}; labels will be blank.`);\n }\n } catch (e) {\n console.warn(`[vroom] axis font fetch failed (${cfg.fontUrl}); labels will be blank.`, e);\n }\n } else {\n console.warn('[vroom] no fontUrl provided; text labels will be blank.');\n }\n\n return makeWasmModule(instance, fontBytes);\n}\n","// @vroomchart/core-wasm — the framework-agnostic web core for the vroom chart.\n//\n// Exposes loadVroom(): Promise<VroomModule>, which yields a factory for chart\n// instances bound to a <canvas>. Today it resolves to a Canvas2D stub so the\n// web stack is buildable/runnable before the Skia-WASM toolchain exists; the\n// only change to ship the real core is to instantiate the WASM module inside\n// loadVroom() — the VroomModule / VroomChartHandle contract stays identical.\n\nimport type { VroomModule } from './handle';\nimport { createStubModule } from './stub/stubModule';\nimport { loadWasmCore, type WasmConfig } from './wasm/loadWasm';\n\n// URLs of the WASM assets bundled in this package. Defined here (one level under\n// the package root, matching the built dist/index.js) so the relative paths\n// resolve correctly both from source in dev and from the bundle in production.\n// Static `new URL(..., import.meta.url)` so bundlers (Vite, webpack 5, …) emit\n// and rewrite them automatically — no asset hosting needed by consumers.\nfunction bundledWasmConfig(): WasmConfig {\n return {\n moduleUrl: new URL('../assets/vroom_core.mjs', import.meta.url).href,\n wasmUrl: new URL('../assets/vroom_core.wasm', import.meta.url).href,\n fontUrl: new URL('../assets/VroomSans-Regular.ttf', import.meta.url).href,\n };\n}\n\nexport type {\n VroomModule,\n VroomChartHandle,\n AxisMetrics,\n CrosshairCandle,\n OverlaySpec,\n} from './handle';\nexport { ColorKey } from './handle';\nexport { packCandles, unpackCandles, BYTES_PER_CANDLE } from './packCandles';\nexport { parseColor, applyTheme, argbToCss, COLOR_KEYS } from './color';\nexport type { WasmConfig } from './wasm/loadWasm';\n\n/** Options for loading the core. */\nexport type LoadVroomOptions = {\n /**\n * Override where the Skia-WASM core is loaded from. By default the core uses\n * the WASM build bundled in this package (turnkey, no asset hosting needed);\n * pass `wasm` to load it from your own URLs instead. On load failure the\n * Canvas2D stub is used unless `fallbackToStub: false`.\n */\n wasm?: WasmConfig;\n /** When wasm loading fails, fall back to the stub (default true). */\n fallbackToStub?: boolean;\n /** Force the Canvas2D stub instead of the WASM core (tests / SSR). */\n forceStub?: boolean;\n};\n\nlet modulePromise: Promise<VroomModule> | null = null;\n\n/**\n * Load the chart core. Cached: repeated calls share one module instance.\n *\n * Defaults to the real Skia-WASM core bundled in this package. Pass\n * `forceStub` for the Canvas2D stub, or `wasm` to load the core from custom\n * URLs. WASM load failures fall back to the stub unless `fallbackToStub: false`.\n */\nexport function loadVroom(opts?: LoadVroomOptions): Promise<VroomModule> {\n if (modulePromise) return modulePromise;\n\n if (opts?.forceStub) {\n modulePromise = Promise.resolve(createStubModule());\n } else {\n const cfg = opts?.wasm ?? bundledWasmConfig();\n const fallback = opts?.fallbackToStub !== false;\n modulePromise = loadWasmCore(cfg).catch((err) => {\n if (!fallback) throw err;\n console.warn('[vroom] Skia-WASM core failed to load; using Canvas2D stub.', err);\n return createStubModule();\n });\n }\n return modulePromise;\n}\n\n/** Test/HMR helper: drop the cached module so the next loadVroom() re-creates it. */\nexport function resetVroomForTesting(): void {\n modulePromise = null;\n}\n"],"mappings":"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","names":["ColorKey"]}
1
+ {"version":3,"sources":["../src/wasm/adapter.ts","../src/wasm/loadWasm.ts","../src/handle.ts","../src/packCandles.ts","../src/color.ts","../src/index.ts"],"sourcesContent":["// Adapts the emscripten `WebChart` (embind class from web/vroom_web.cpp) to the\n// VroomChartHandle / VroomModule contract that @vroomchart/react consumes. This is\n// the only place that knows the WASM module's shape — swapping the stub for the\n// real core changes nothing above this line.\n\nimport type {\n AxisMetrics,\n CrosshairCandle,\n CrosshairInfo,\n OverlaySpec,\n VroomChartHandle,\n VroomModule,\n} from '../handle';\n\n// The embind class instance. Methods mirror web/vroom_web.cpp; `delete()` frees\n// the C++ object (embind requires explicit disposal).\ninterface WebChartInstance {\n setCandles(bytes: Uint8Array): void;\n setSize(width: number, height: number, dpr: number): void;\n setColor(key: number, argb: number): void;\n setVisibleRange(startMs: number, endMs: number): void;\n pan(dx: number, dy: number): void;\n translate(dx: number, dy: number): void;\n zoom(sx: number, sy: number, fx: number, fy: number): void;\n scalePriceAxis(dy: number): void;\n scaleTimeAxis(dx: number): void;\n getAxisMetrics(): AxisMetrics;\n setCrosshair(x: number, y: number): void;\n clearCrosshair(): void;\n getCrosshairCandle(): CrosshairCandle | null;\n getCrosshairInfo(): CrosshairInfo | null;\n setRSI(e: boolean, p: number, u: number, l: number, mae: boolean, map: number): void;\n setMACD(e: boolean, f: number, s: number, sig: number): void;\n setOverlays(overlays: OverlaySpec[]): void;\n setVWAP(e: boolean, reset: number, color: number, width: number): void;\n setTypeface(bytes: Uint8Array): void;\n isAnimating(): boolean;\n present(): void;\n delete(): void;\n}\n\n/** The shape of the instantiated emscripten module we depend on. */\nexport interface VroomWasmModule {\n WebChart: new (canvasSelector: string) => WebChartInstance;\n}\n\nlet uid = 0;\n\nclass WasmHandle implements VroomChartHandle {\n constructor(private wc: WebChartInstance) {}\n\n setCandles(packed: ArrayBuffer): void {\n this.wc.setCandles(new Uint8Array(packed));\n }\n setSize(width: number, height: number, dpr: number): void {\n this.wc.setSize(width, height, dpr);\n }\n setColor(key: number, argb: number): void {\n this.wc.setColor(key, argb >>> 0);\n }\n setVisibleRange(startMs: number, endMs: number): void {\n this.wc.setVisibleRange(startMs, endMs);\n }\n pan(dx: number, dy: number): void {\n this.wc.pan(dx, dy);\n }\n translate(dx: number, dy: number): void {\n this.wc.translate(dx, dy);\n }\n zoom(scaleX: number, scaleY: number, fx: number, fy: number): void {\n this.wc.zoom(scaleX, scaleY, fx, fy);\n }\n scalePriceAxis(dy: number): void {\n this.wc.scalePriceAxis(dy);\n }\n scaleTimeAxis(dx: number): void {\n this.wc.scaleTimeAxis(dx);\n }\n getAxisMetrics(): AxisMetrics {\n return this.wc.getAxisMetrics();\n }\n setCrosshair(x: number, y: number): void {\n this.wc.setCrosshair(x, y);\n }\n clearCrosshair(): void {\n this.wc.clearCrosshair();\n }\n getCrosshairCandle(): CrosshairCandle | null {\n return this.wc.getCrosshairCandle();\n }\n getCrosshairInfo(): CrosshairInfo | null {\n return this.wc.getCrosshairInfo();\n }\n setRSI(\n enabled: boolean,\n period: number,\n upperBand: number,\n lowerBand: number,\n maEnabled: boolean,\n maPeriod: number,\n ): void {\n this.wc.setRSI(enabled, period, upperBand, lowerBand, maEnabled, maPeriod);\n }\n setMACD(enabled: boolean, fast: number, slow: number, signal: number): void {\n this.wc.setMACD(enabled, fast, slow, signal);\n }\n setOverlays(overlays: OverlaySpec[]): void {\n this.wc.setOverlays(overlays);\n }\n setVWAP(enabled: boolean, resetOffsetMin: number, color: number, width: number): void {\n this.wc.setVWAP(enabled, resetOffsetMin, color >>> 0, width);\n }\n isAnimating(): boolean {\n return this.wc.isAnimating();\n }\n present(): void {\n this.wc.present();\n }\n destroy(): void {\n this.wc.delete();\n }\n}\n\n/**\n * Wrap an instantiated WASM module as a VroomModule. `fontBytes` (a .ttf/.otf)\n * is installed as the axis typeface on each chart — required for text labels,\n * since the WASM sandbox has no system fonts.\n */\nexport function makeWasmModule(\n module: VroomWasmModule,\n fontBytes: Uint8Array | null,\n): VroomModule {\n return {\n create(canvas: HTMLCanvasElement) {\n if (!canvas.id) canvas.id = `vroom-canvas-${uid++}`;\n const wc = new module.WebChart(`#${canvas.id}`);\n if (fontBytes) wc.setTypeface(fontBytes);\n return new WasmHandle(wc);\n },\n };\n}\n","// Instantiates the Skia-WASM core (the emscripten ES module built from\n// packages/core/web + CMake VROOM_WASM) and adapts it to a VroomModule.\n//\n// The module URL is resolved at runtime (not statically imported) so bundlers\n// don't try to resolve a not-yet-built artifact — keeping the stub-only build\n// green until the WASM file actually exists.\n\nimport type { VroomModule } from '../handle';\nimport { makeWasmModule, type VroomWasmModule } from './adapter';\n\nexport type WasmConfig = {\n /** URL to the emscripten ES module (vroom_core.mjs). */\n moduleUrl: string;\n /** URL to vroom_core.wasm. Defaults to resolving next to the module. */\n wasmUrl?: string;\n /** URL to a .ttf/.otf used for axis/price/time labels. */\n fontUrl?: string;\n};\n\n// The emscripten MODULARIZE/EXPORT_ES6 default export is a factory:\n// createVroomCore(moduleOverrides) => Promise<Module>\ntype EmscriptenFactory = (overrides?: Record<string, unknown>) => Promise<VroomWasmModule>;\n\n// Import the emscripten ES module from a runtime URL WITHOUT the bundler trying\n// to resolve/transform it. A plain import(url) (even with /* @vite-ignore */) is\n// still intercepted by Vite's \"don't import from /public\" guard and by other\n// bundlers' static analysis. Routing through Function keeps it fully opaque.\n// (Requires 'unsafe-eval' under a strict CSP — self-host the module differently\n// if that's a constraint.)\nconst dynamicImport = new Function('u', 'return import(u)') as (\n u: string,\n) => Promise<{ default: EmscriptenFactory }>;\n\nexport async function loadWasmCore(cfg: WasmConfig): Promise<VroomModule> {\n const mod = await dynamicImport(cfg.moduleUrl);\n const instance = await mod.default({\n locateFile: (path: string) =>\n path.endsWith('.wasm') && cfg.wasmUrl ? cfg.wasmUrl : path,\n });\n\n let fontBytes: Uint8Array | null = null;\n if (cfg.fontUrl) {\n try {\n const res = await fetch(cfg.fontUrl);\n if (res.ok) {\n fontBytes = new Uint8Array(await res.arrayBuffer());\n console.info(`[vroom] axis font loaded (${cfg.fontUrl}, ${fontBytes.length} bytes)`);\n } else {\n console.warn(`[vroom] axis font fetch ${cfg.fontUrl} → HTTP ${res.status}; labels will be blank.`);\n }\n } catch (e) {\n console.warn(`[vroom] axis font fetch failed (${cfg.fontUrl}); labels will be blank.`, e);\n }\n } else {\n console.warn('[vroom] no fontUrl provided; text labels will be blank.');\n }\n\n return makeWasmModule(instance, fontBytes);\n}\n","// The low-level contract for one chart instance on the web.\n//\n// This mirrors the C facade (packages/core/include/vroom/vroom_chart.h) and the\n// native JSI handle (packages/react-native/src/jsi.d.ts) — but WITHOUT the\n// SkPicture return values. On web the core owns the <canvas> and its rendering\n// surface, so mutations are `void` and `present()` paints. Backed by the\n// Skia-WASM module (./wasm).\n\n/** Theme color slots — mirrors the `VroomColorKey` enum in the C facade. */\nexport enum ColorKey {\n Background = 0,\n Bull = 1,\n Bear = 2,\n Wick = 3,\n Grid = 4,\n AxisText = 5,\n Crosshair = 6,\n TooltipBg = 7,\n TooltipText = 8,\n CrosshairTarget = 9,\n}\n\n/** OHLCV readout for the candle under the crosshair. */\nexport type CrosshairCandle = {\n timeMs: number;\n open: number;\n high: number;\n low: number;\n close: number;\n volume: number;\n};\n\n/**\n * What the crosshair currently snaps to. `timeMs` is the snapped slot's\n * period-start time — set even in the empty space ahead of the most recent\n * candle. `candle` holds the OHLCV when a real candle sits at that slot, and is\n * null when the crosshair is parked on a future candle-aligned slot.\n */\nexport type CrosshairInfo = {\n timeMs: number;\n candle: CrosshairCandle | null;\n};\n\n/** Axis region sizes in CSS px, for hit-testing gestures on the JS side. */\nexport type AxisMetrics = {\n yAxisWidth: number;\n xAxisHeight: number;\n /** Below-chart indicator pane height; 0 when no pane is shown. */\n indicatorHeight: number;\n};\n\n/** A moving-average overlay line, in the core's numeric encoding. */\nexport type OverlaySpec = {\n /** 0 = SMA, 1 = EMA. */\n kind: number;\n period: number;\n /** 0=close,1=open,2=high,3=low,4=hl2,5=hlc3,6=ohlc4 */\n source: number;\n /** Packed 0xAARRGGBB. */\n color: number;\n /** Stroke width in px. */\n width: number;\n};\n\n/**\n * A single chart instance bound to a canvas. Method semantics match the native\n * handle one-to-one (see jsi.d.ts) so the two platforms behave identically.\n */\nexport interface VroomChartHandle {\n /** Replace the full candle series (packed buffer; see packCandles). */\n setCandles(packed: ArrayBuffer): void;\n /** Set the drawing size in CSS px plus the device pixel ratio. */\n setSize(width: number, height: number, dpr: number): void;\n /** Override one theme color. `argb` is packed 0xAARRGGBB. */\n setColor(key: ColorKey | number, argb: number): void;\n /** Pass 0, 0 to show all candles. */\n setVisibleRange(startMs: number, endMs: number): void;\n\n /** Shift the visible range by dx/dy CSS px. */\n pan(dx: number, dy: number): void;\n /** Shift the time window and price bounds without rescaling. */\n translate(dx: number, dy: number): void;\n /** Directional zoom by per-axis factors around focus (fx, fy) in px. */\n zoom(scaleX: number, scaleY: number, fx: number, fy: number): void;\n /** Drag-on-y-axis price scaling; dy>0 widens the price range. */\n scalePriceAxis(dy: number): void;\n /** Drag-on-x-axis time scaling; dx>0 widens the time window. */\n scaleTimeAxis(dx: number): void;\n\n /** Current axis dimensions for hit-testing in JS gestures. */\n getAxisMetrics(): AxisMetrics;\n\n /** Show the crosshair at (x, y) CSS px (y already lifted above the pointer). */\n setCrosshair(x: number, y: number): void;\n /** Hide the crosshair. */\n clearCrosshair(): void;\n /** OHLCV of the candle the crosshair snaps to, or null when inactive. */\n getCrosshairCandle(): CrosshairCandle | null;\n /**\n * The slot the crosshair snaps to (real candle or future candle-aligned\n * slot), or null when inactive. Unlike getCrosshairCandle this reports a\n * timeMs even in the empty space ahead of the most recent candle.\n */\n getCrosshairInfo(): CrosshairInfo | null;\n\n setRSI(\n enabled: boolean,\n period: number,\n upperBand: number,\n lowerBand: number,\n maEnabled: boolean,\n maPeriod: number,\n ): void;\n setMACD(enabled: boolean, fast: number, slow: number, signal: number): void;\n setOverlays(overlays: OverlaySpec[]): void;\n setVWAP(\n enabled: boolean,\n resetOffsetMin: number,\n color: number,\n width: number,\n ): void;\n\n /** True while any axis-label fade is in progress (drives the rAF loop). */\n isAnimating(): boolean;\n /** Paint the current state to the canvas. */\n present(): void;\n /** Release resources; the handle is unusable afterward. */\n destroy(): void;\n}\n\n/** Factory for chart instances. The loaded core module implements this. */\nexport interface VroomModule {\n /** Create a chart bound to `canvas`, attaching its rendering surface. */\n create(canvas: HTMLCanvasElement): VroomChartHandle;\n}\n","import type { Candle } from '@vroomchart/types';\n\n// Wire format must match `VroomCandle` in packages/core/include/vroom/vroom_chart.h:\n// int64_t time_ms; double open, high, low, close, volume;\n// = 48 bytes per candle, 8-byte aligned, little-endian.\n//\n// This is a deliberate mirror of packages/react-native/src/packCandles.ts so\n// the web side speaks the same binary ABI the Skia-WASM core will decode. Keep\n// the two in sync with the C struct.\nexport const BYTES_PER_CANDLE = 48;\n\n/** Serialize candles into the packed little-endian buffer the core expects. */\nexport function packCandles(candles: Candle[]): ArrayBuffer {\n const buf = new ArrayBuffer(candles.length * BYTES_PER_CANDLE);\n const view = new DataView(buf);\n for (let i = 0; i < candles.length; i++) {\n const c = candles[i]!;\n const off = i * BYTES_PER_CANDLE;\n view.setBigInt64(off, BigInt(Math.trunc(c.timeMs)), true);\n view.setFloat64(off + 8, c.open, true);\n view.setFloat64(off + 16, c.high, true);\n view.setFloat64(off + 24, c.low, true);\n view.setFloat64(off + 32, c.close, true);\n view.setFloat64(off + 40, c.volume, true);\n }\n return buf;\n}\n\n/** Decode the packed buffer back to candles (inverse of packCandles). */\nexport function unpackCandles(buf: ArrayBuffer): Candle[] {\n const view = new DataView(buf);\n const n = Math.floor(buf.byteLength / BYTES_PER_CANDLE);\n const out: Candle[] = new Array(n);\n for (let i = 0; i < n; i++) {\n const off = i * BYTES_PER_CANDLE;\n out[i] = {\n timeMs: Number(view.getBigInt64(off, true)),\n open: view.getFloat64(off + 8, true),\n high: view.getFloat64(off + 16, true),\n low: view.getFloat64(off + 24, true),\n close: view.getFloat64(off + 32, true),\n volume: view.getFloat64(off + 40, true),\n };\n }\n return out;\n}\n","import type { VroomColor, VroomTheme } from '@vroomchart/types';\nimport { ColorKey, type VroomChartHandle } from './handle';\n\n// Maps each VroomTheme field to its ColorKey. Mirror of\n// packages/react-native/src/theme.ts (which keys off the same C enum).\nexport const COLOR_KEYS: Record<keyof VroomTheme, ColorKey> = {\n background: ColorKey.Background,\n bull: ColorKey.Bull,\n bear: ColorKey.Bear,\n grid: ColorKey.Grid,\n axisText: ColorKey.AxisText,\n crosshair: ColorKey.Crosshair,\n crosshairTarget: ColorKey.CrosshairTarget,\n};\n\n/**\n * Parse a color into a packed 0xAARRGGBB integer (Skia's ARGB order).\n * - number → taken as already-packed ARGB\n * - 6-digit hex → opaque (alpha forced to ff)\n * - 8-digit hex → interpreted as AARRGGBB\n * Returns null for anything malformed so the caller can skip it.\n */\nexport function parseColor(value: VroomColor): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value >>> 0 : null;\n }\n let s = value.trim();\n if (s.startsWith('#')) s = s.slice(1);\n if (s.length === 6) s = `ff${s}`;\n if (s.length !== 8 || !/^[0-9a-fA-F]{8}$/.test(s)) return null;\n return parseInt(s, 16) >>> 0;\n}\n\n/** Push every provided theme color into the handle; skip unparseable ones. */\nexport function applyTheme(handle: VroomChartHandle, theme: VroomTheme): void {\n (Object.keys(COLOR_KEYS) as (keyof VroomTheme)[]).forEach((field) => {\n const value = theme[field];\n if (value == null) return;\n const argb = parseColor(value);\n if (argb == null) return;\n handle.setColor(COLOR_KEYS[field], argb);\n });\n}\n\n/** Split a packed 0xAARRGGBB integer into a CSS `rgba(...)` string. */\nexport function argbToCss(argb: number): string {\n const a = ((argb >>> 24) & 0xff) / 255;\n const r = (argb >>> 16) & 0xff;\n const g = (argb >>> 8) & 0xff;\n const b = argb & 0xff;\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n","// @vroomchart/core-wasm — the framework-agnostic web core for the vroom chart.\n//\n// Exposes loadVroom(): Promise<VroomModule>, which yields a factory for chart\n// instances bound to a <canvas>. It resolves to the Skia-WASM core bundled in\n// this package; pass `wasm` to load it from your own URLs instead.\n\nimport type { VroomModule } from './handle';\nimport { loadWasmCore, type WasmConfig } from './wasm/loadWasm';\n\n// URLs of the WASM assets bundled in this package. Defined here (one level under\n// the package root, matching the built dist/index.js) so the relative paths\n// resolve correctly both from source in dev and from the bundle in production.\n// Static `new URL(..., import.meta.url)` so bundlers (Vite, webpack 5, …) emit\n// and rewrite them automatically — no asset hosting needed by consumers.\nfunction bundledWasmConfig(): WasmConfig {\n return {\n moduleUrl: new URL('../assets/vroom_core.mjs', import.meta.url).href,\n wasmUrl: new URL('../assets/vroom_core.wasm', import.meta.url).href,\n fontUrl: new URL('../assets/VroomSans-Regular.ttf', import.meta.url).href,\n };\n}\n\nexport type {\n VroomModule,\n VroomChartHandle,\n AxisMetrics,\n CrosshairCandle,\n CrosshairInfo,\n OverlaySpec,\n} from './handle';\nexport { ColorKey } from './handle';\nexport { packCandles, unpackCandles, BYTES_PER_CANDLE } from './packCandles';\nexport { parseColor, applyTheme, argbToCss, COLOR_KEYS } from './color';\nexport type { WasmConfig } from './wasm/loadWasm';\n\n/** Options for loading the core. */\nexport type LoadVroomOptions = {\n /**\n * Override where the Skia-WASM core is loaded from. By default the core uses\n * the WASM build bundled in this package (turnkey, no asset hosting needed);\n * pass `wasm` to load it from your own URLs instead.\n */\n wasm?: WasmConfig;\n};\n\nlet modulePromise: Promise<VroomModule> | null = null;\n\n/**\n * Load the chart core. Cached: repeated calls share one module instance.\n *\n * Resolves to the Skia-WASM core bundled in this package, or the core at the\n * URLs in `opts.wasm`. The returned promise rejects if the WASM module fails to\n * load (and the cache is cleared so a later call can retry).\n */\nexport function loadVroom(opts?: LoadVroomOptions): Promise<VroomModule> {\n if (modulePromise) return modulePromise;\n\n const cfg = opts?.wasm ?? bundledWasmConfig();\n modulePromise = loadWasmCore(cfg).catch((err) => {\n modulePromise = null; // allow a retry on the next call\n throw err;\n });\n return modulePromise;\n}\n\n/** Test/HMR helper: drop the cached module so the next loadVroom() re-creates it. */\nexport function resetVroomForTesting(): void {\n modulePromise = null;\n}\n"],"mappings":"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","names":["ColorKey"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vroomchart/core-wasm",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Framework-agnostic web core for the vroom chart — Skia-WASM renderer with a Canvas2D fallback.",
5
5
  "license": "MIT",
6
6
  "author": "Darion Welch",