@pyreon/charts 0.11.4 → 0.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -64,16 +64,16 @@ Component shorthand wrapping `useChart`.
64
64
  />
65
65
  ```
66
66
 
67
- | Prop | Type | Description |
68
- | --- | --- | --- |
69
- | `options` | `() => EChartOption` | Reactive config function |
70
- | `theme?` | `string \| object` | ECharts theme |
71
- | `renderer?` | `'canvas' \| 'svg'` | Renderer (default: `'canvas'`) |
72
- | `style?` | `string` | CSS style for container |
73
- | `class?` | `string` | CSS class for container |
74
- | `onClick?` | `(params) => void` | Click event |
75
- | `onMouseover?` | `(params) => void` | Mouseover event |
76
- | `onMouseout?` | `(params) => void` | Mouseout event |
67
+ | Prop | Type | Description |
68
+ | -------------- | -------------------- | ------------------------------ |
69
+ | `options` | `() => EChartOption` | Reactive config function |
70
+ | `theme?` | `string \| object` | ECharts theme |
71
+ | `renderer?` | `'canvas' \| 'svg'` | Renderer (default: `'canvas'`) |
72
+ | `style?` | `string` | CSS style for container |
73
+ | `class?` | `string` | CSS class for container |
74
+ | `onClick?` | `(params) => void` | Click event |
75
+ | `onMouseover?` | `(params) => void` | Mouseover event |
76
+ | `onMouseout?` | `(params) => void` | Mouseout event |
77
77
 
78
78
  ### `useChart(options, config?)`
79
79
 
@@ -90,23 +90,23 @@ return <div ref={chart.ref} style="height: 400px" />
90
90
 
91
91
  **Returns:**
92
92
 
93
- | Property | Type | Description |
94
- | --- | --- | --- |
95
- | `ref` | `(el: HTMLElement \| null) => void` | Bind to container div |
96
- | `instance` | `Signal<ECharts \| null>` | ECharts instance (null until loaded) |
97
- | `loading` | `Signal<boolean>` | True while modules are loading |
98
- | `resize` | `() => void` | Manually trigger resize |
93
+ | Property | Type | Description |
94
+ | ---------- | ----------------------------------- | ------------------------------------ |
95
+ | `ref` | `(el: HTMLElement \| null) => void` | Bind to container div |
96
+ | `instance` | `Signal<ECharts \| null>` | ECharts instance (null until loaded) |
97
+ | `loading` | `Signal<boolean>` | True while modules are loading |
98
+ | `resize` | `() => void` | Manually trigger resize |
99
99
 
100
100
  **Config options:**
101
101
 
102
- | Option | Type | Default | Description |
103
- | --- | --- | --- | --- |
104
- | `theme` | `string \| object` | — | ECharts theme |
105
- | `renderer` | `'canvas' \| 'svg'` | `'canvas'` | Rendering engine |
106
- | `locale` | `string` | `'EN'` | ECharts locale |
107
- | `notMerge` | `boolean` | `false` | Replace options instead of merging |
108
- | `lazyUpdate` | `boolean` | `true` | Batch updates |
109
- | `onInit` | `(instance) => void` | — | Called when chart is created |
102
+ | Option | Type | Default | Description |
103
+ | ------------ | -------------------- | ---------- | ---------------------------------- |
104
+ | `theme` | `string \| object` | — | ECharts theme |
105
+ | `renderer` | `'canvas' \| 'svg'` | `'canvas'` | Rendering engine |
106
+ | `locale` | `string` | `'EN'` | ECharts locale |
107
+ | `notMerge` | `boolean` | `false` | Replace options instead of merging |
108
+ | `lazyUpdate` | `boolean` | `true` | Batch updates |
109
+ | `onInit` | `(instance) => void` | — | Called when chart is created |
110
110
 
111
111
  ## Manual Registration (Tree-shaking)
112
112
 
@@ -139,13 +139,13 @@ tooltip, legend, title, toolbox, dataZoom, visualMap, timeline, graphic, brush,
139
139
 
140
140
  ## Bundle Size
141
141
 
142
- | Usage | ECharts loaded | Approx gzipped |
143
- | --- | --- | --- |
144
- | No charts rendered | Nothing | 0 KB |
145
- | Bar + tooltip | core + BarChart + Grid + Tooltip + Canvas | ~35 KB |
146
- | Bar + Line + legend | core + BarChart + LineChart + Grid + Legend + Tooltip + Canvas | ~42 KB |
147
- | Pie only | core + PieChart + Canvas | ~25 KB |
148
- | @pyreon/charts itself | Module map + hook | ~3 KB |
142
+ | Usage | ECharts loaded | Approx gzipped |
143
+ | --------------------- | -------------------------------------------------------------- | -------------- |
144
+ | No charts rendered | Nothing | 0 KB |
145
+ | Bar + tooltip | core + BarChart + Grid + Tooltip + Canvas | ~35 KB |
146
+ | Bar + Line + legend | core + BarChart + LineChart + Grid + Legend + Tooltip + Canvas | ~42 KB |
147
+ | Pie only | core + PieChart + Canvas | ~25 KB |
148
+ | @pyreon/charts itself | Module map + hook | ~3 KB |
149
149
 
150
150
  ## Why Canvas by default
151
151
 
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/loader.ts","../src/use-chart.ts","../../../core/core/lib/jsx-runtime.js","../src/chart-component.tsx"],"sourcesContent":["/**\n * Lazy loading and auto-detection for ECharts modules.\n *\n * Maps config keys to ECharts modular imports. Only loads what's needed,\n * caches after first load. The echarts/core module itself is lazy-loaded\n * on first use — zero ECharts bytes until a chart actually renders.\n */\n\n/**\n * Loose option type for internal module analysis.\n * The strict EChartsOption type is used at the consumer-facing API level.\n */\ntype LooseOption = Record<string, unknown> & {\n series?: unknown\n}\n\ntype ModuleLoader = () => Promise<unknown>\n\n/** The argument type that `echarts/core.use()` accepts. */\ntype EChartsUseArg = Parameters<typeof import(\"echarts/core\").use>[0]\n\n// ─── Chart type mapping ─────────────────────────────────────────────────────\n\nconst CHARTS: Record<string, ModuleLoader> = {\n bar: () => import(\"echarts/charts\").then((m) => m.BarChart),\n line: () => import(\"echarts/charts\").then((m) => m.LineChart),\n pie: () => import(\"echarts/charts\").then((m) => m.PieChart),\n scatter: () => import(\"echarts/charts\").then((m) => m.ScatterChart),\n radar: () => import(\"echarts/charts\").then((m) => m.RadarChart),\n heatmap: () => import(\"echarts/charts\").then((m) => m.HeatmapChart),\n treemap: () => import(\"echarts/charts\").then((m) => m.TreemapChart),\n sunburst: () => import(\"echarts/charts\").then((m) => m.SunburstChart),\n sankey: () => import(\"echarts/charts\").then((m) => m.SankeyChart),\n funnel: () => import(\"echarts/charts\").then((m) => m.FunnelChart),\n gauge: () => import(\"echarts/charts\").then((m) => m.GaugeChart),\n graph: () => import(\"echarts/charts\").then((m) => m.GraphChart),\n tree: () => import(\"echarts/charts\").then((m) => m.TreeChart),\n boxplot: () => import(\"echarts/charts\").then((m) => m.BoxplotChart),\n candlestick: () => import(\"echarts/charts\").then((m) => m.CandlestickChart),\n parallel: () => import(\"echarts/charts\").then((m) => m.ParallelChart),\n themeRiver: () => import(\"echarts/charts\").then((m) => m.ThemeRiverChart),\n effectScatter: () => import(\"echarts/charts\").then((m) => m.EffectScatterChart),\n lines: () => import(\"echarts/charts\").then((m) => m.LinesChart),\n pictorialBar: () => import(\"echarts/charts\").then((m) => m.PictorialBarChart),\n custom: () => import(\"echarts/charts\").then((m) => m.CustomChart),\n map: () => import(\"echarts/charts\").then((m) => m.MapChart),\n}\n\n// ─── Component mapping ──────────────────────────────────────────────────────\n\n// Multiple config keys can map to the same component (xAxis/yAxis → Grid)\nconst COMPONENTS: Record<string, ModuleLoader> = {\n grid: () => import(\"echarts/components\").then((m) => m.GridComponent),\n xAxis: () => import(\"echarts/components\").then((m) => m.GridComponent),\n yAxis: () => import(\"echarts/components\").then((m) => m.GridComponent),\n polar: () => import(\"echarts/components\").then((m) => m.PolarComponent),\n radar: () => import(\"echarts/components\").then((m) => m.RadarComponent),\n geo: () => import(\"echarts/components\").then((m) => m.GeoComponent),\n tooltip: () => import(\"echarts/components\").then((m) => m.TooltipComponent),\n legend: () => import(\"echarts/components\").then((m) => m.LegendComponent),\n toolbox: () => import(\"echarts/components\").then((m) => m.ToolboxComponent),\n title: () => import(\"echarts/components\").then((m) => m.TitleComponent),\n dataZoom: () => import(\"echarts/components\").then((m) => m.DataZoomComponent),\n visualMap: () => import(\"echarts/components\").then((m) => m.VisualMapComponent),\n timeline: () => import(\"echarts/components\").then((m) => m.TimelineComponent),\n graphic: () => import(\"echarts/components\").then((m) => m.GraphicComponent),\n brush: () => import(\"echarts/components\").then((m) => m.BrushComponent),\n calendar: () => import(\"echarts/components\").then((m) => m.CalendarComponent),\n dataset: () => import(\"echarts/components\").then((m) => m.DatasetComponent),\n aria: () => import(\"echarts/components\").then((m) => m.AriaComponent),\n}\n\n// Series-level features\nconst SERIES_FEATURES: Record<string, ModuleLoader> = {\n markPoint: () => import(\"echarts/components\").then((m) => m.MarkPointComponent),\n markLine: () => import(\"echarts/components\").then((m) => m.MarkLineComponent),\n markArea: () => import(\"echarts/components\").then((m) => m.MarkAreaComponent),\n}\n\n// ─── Renderers ──────────────────────────────────────────────────────────────\n\nconst RENDERERS: Record<string, ModuleLoader> = {\n canvas: () => import(\"echarts/renderers\").then((m) => m.CanvasRenderer),\n svg: () => import(\"echarts/renderers\").then((m) => m.SVGRenderer),\n}\n\n// ─── Core loading ───────────────────────────────────────────────────────────\n\nlet coreModule: typeof import(\"echarts/core\") | null = null\nlet corePromise: Promise<typeof import(\"echarts/core\")> | null = null\n\n/**\n * Lazily load echarts/core. Cached after first call.\n */\nexport async function getCore(): Promise<typeof import(\"echarts/core\")> {\n if (coreModule) return coreModule\n if (!corePromise) {\n corePromise = import(\"echarts/core\").then((m) => {\n coreModule = m\n return m\n })\n }\n return corePromise\n}\n\n/**\n * Get the cached core module (null if not yet loaded).\n */\nexport function getCoreSync(): typeof import(\"echarts/core\") | null {\n return coreModule\n}\n\n// ─── Module registration ────────────────────────────────────────────────────\n\nconst registered = new Set<string>()\nconst inflight = new Map<string, Promise<void>>()\n\nasync function loadAndRegister(\n core: typeof import(\"echarts/core\"),\n key: string,\n loader: ModuleLoader,\n): Promise<void> {\n if (registered.has(key)) return\n if (inflight.has(key)) return inflight.get(key)\n\n const promise = loader().then((mod) => {\n core.use(mod as EChartsUseArg)\n registered.add(key)\n inflight.delete(key)\n })\n inflight.set(key, promise)\n return promise\n}\n\n/**\n * Analyze an ECharts option object and dynamically import only the\n * required chart types, components, and renderer. All imports are\n * cached — subsequent calls with the same types are instant.\n */\nexport async function ensureModules(\n option: LooseOption,\n renderer: \"canvas\" | \"svg\" = \"canvas\",\n): Promise<typeof import(\"echarts/core\")> {\n const core = await getCore()\n const loads: Promise<void>[] = []\n\n // Renderer (always needed)\n const rendererLoader = RENDERERS[renderer]\n if (rendererLoader) loads.push(loadAndRegister(core, `renderer:${renderer}`, rendererLoader))\n\n // Normalize series to array for analysis\n const rawSeries = option.series\n const seriesList: Record<string, unknown>[] = rawSeries\n ? ((Array.isArray(rawSeries) ? rawSeries : [rawSeries]) as Record<string, unknown>[])\n : []\n\n // Chart types from series[].type\n for (const s of seriesList) {\n const type = s.type as string | undefined\n const chartLoader = type ? CHARTS[type] : undefined\n if (chartLoader) {\n loads.push(loadAndRegister(core, `chart:${type}`, chartLoader))\n }\n }\n\n // Components from top-level config keys\n for (const key of Object.keys(option)) {\n const compLoader = COMPONENTS[key]\n if (compLoader) {\n loads.push(loadAndRegister(core, `component:${key}`, compLoader))\n }\n }\n\n // Series-level features (markPoint, markLine, markArea)\n for (const s of seriesList) {\n for (const key of Object.keys(s)) {\n const featureLoader = SERIES_FEATURES[key]\n if (featureLoader) {\n loads.push(loadAndRegister(core, `feature:${key}`, featureLoader))\n }\n }\n }\n\n await Promise.all(loads)\n return core\n}\n\n/**\n * Manually register ECharts modules (for tree-shaking entry point).\n * Call this at app startup instead of relying on auto-detection.\n *\n * @example\n * ```ts\n * import { use } from '@pyreon/charts/manual'\n * import { BarChart } from 'echarts/charts'\n * import { GridComponent, TooltipComponent } from 'echarts/components'\n * import { CanvasRenderer } from 'echarts/renderers'\n *\n * use(BarChart, GridComponent, TooltipComponent, CanvasRenderer)\n * ```\n */\nexport function manualUse(...modules: unknown[]): void {\n const core = getCoreSync()\n if (core) {\n core.use(modules as EChartsUseArg)\n } else {\n // Core not loaded yet — queue for when it loads\n getCore().then((c) => c.use(modules as any))\n }\n}\n\n// ─── Reset (for testing) ────────────────────────────────────────────────────\n\nexport function _resetLoader(): void {\n registered.clear()\n inflight.clear()\n coreModule = null\n corePromise = null\n}\n","import { onUnmount } from \"@pyreon/core\"\nimport { effect, signal } from \"@pyreon/reactivity\"\nimport type { EChartsOption } from \"echarts\"\nimport { ensureModules } from \"./loader\"\nimport type { UseChartConfig, UseChartResult } from \"./types\"\n\n/**\n * Reactive ECharts hook. Creates a chart instance bound to a container\n * element, with automatic module lazy-loading, signal tracking, resize\n * handling, error capture, and cleanup.\n *\n * Generic parameter `TOption` narrows the option type for exact autocomplete.\n * Use `ComposeOption<SeriesUnion>` from ECharts to restrict to specific chart types.\n *\n * @example\n * ```tsx\n * // Default — accepts any ECharts option\n * const chart = useChart(() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * }))\n *\n * // Strict — only bar + line allowed, full autocomplete\n * import type { ComposeOption, BarSeriesOption, LineSeriesOption } from '@pyreon/charts'\n * type MyChartOption = ComposeOption<BarSeriesOption | LineSeriesOption>\n *\n * const chart = useChart<MyChartOption>(() => ({\n * series: [{ type: 'bar', data: revenue() }], // ✓\n * }))\n * ```\n */\nexport function useChart<TOption extends EChartsOption = EChartsOption>(\n optionsFn: () => TOption,\n config?: UseChartConfig,\n): UseChartResult {\n const instance = signal<import(\"echarts/core\").ECharts | null>(null)\n const loading = signal(true)\n const error = signal<Error | null>(null)\n const container = signal<HTMLElement | null>(null)\n const renderer = config?.renderer ?? \"canvas\"\n\n let observer: ResizeObserver | null = null\n let initialized = false\n\n // Initialize chart when container is bound\n effect(() => {\n const el = container()\n if (!el || initialized) return\n\n initialized = true\n\n let opts: EChartsOption\n try {\n opts = optionsFn()\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n return\n }\n\n // Load required ECharts modules, then create chart\n ensureModules(opts as Record<string, unknown>, renderer)\n .then((core) => {\n // Guard: component may have unmounted during async load\n if (!container.peek()) return\n\n try {\n const chart = core.init(el, (config?.theme ?? null) as string | object | null, {\n renderer,\n ...(config?.locale != null ? { locale: config.locale } : {}),\n ...(config?.devicePixelRatio != null\n ? { devicePixelRatio: config.devicePixelRatio }\n : {}),\n ...(config?.width != null ? { width: config.width } : {}),\n ...(config?.height != null ? { height: config.height } : {}),\n })\n\n chart.setOption(opts)\n instance.set(chart)\n loading.set(false)\n error.set(null)\n\n config?.onInit?.(chart)\n\n // ResizeObserver for auto-resize\n observer = new ResizeObserver(() => {\n chart.resize()\n })\n observer.observe(el)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n }\n })\n .catch((err) => {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n })\n })\n\n // Reactive updates — re-run when signals in optionsFn change\n effect(() => {\n const chart = instance()\n if (!chart) return\n\n try {\n const opts = optionsFn()\n chart.setOption(opts, {\n notMerge: config?.notMerge ?? false,\n lazyUpdate: config?.lazyUpdate ?? true,\n })\n error.set(null)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n }\n })\n\n // Cleanup on unmount\n onUnmount(() => {\n observer?.disconnect()\n observer = null\n\n const chart = instance.peek()\n if (chart) {\n chart.dispose()\n instance.set(null)\n }\n\n initialized = false\n })\n\n return {\n ref: (el: Element | null) => container.set(el as HTMLElement | null),\n instance,\n loading,\n error,\n resize: () => instance.peek()?.resize(),\n }\n}\n","//#region src/h.ts\n/** Marker for fragment nodes — renders children without a wrapper element */\nconst Fragment = Symbol(\"Pyreon.Fragment\");\n/**\n* Hyperscript function — the compiled output of JSX.\n* `<div class=\"x\">hello</div>` → `h(\"div\", { class: \"x\" }, \"hello\")`\n*\n* Generic on P so TypeScript validates props match the component's signature\n* at the call site, then stores the result in the loosely-typed VNode.\n*/\n/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */\nconst EMPTY_PROPS = {};\nfunction h(type, props, ...children) {\n\treturn {\n\t\ttype,\n\t\tprops: props ?? EMPTY_PROPS,\n\t\tchildren: normalizeChildren(children),\n\t\tkey: props?.key ?? null\n\t};\n}\nfunction normalizeChildren(children) {\n\tfor (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);\n\treturn children;\n}\nfunction flattenChildren(children) {\n\tconst result = [];\n\tfor (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));\n\telse result.push(child);\n\treturn result;\n}\n\n//#endregion\n//#region src/jsx-runtime.ts\n/**\n* JSX automatic runtime.\n*\n* When tsconfig has `\"jsxImportSource\": \"@pyreon/core\"`, the TS/bundler compiler\n* rewrites JSX to imports from this file automatically:\n* <div class=\"x\" /> → jsx(\"div\", { class: \"x\" })\n*/\nfunction jsx(type, props, key) {\n\tconst { children, ...rest } = props;\n\tconst propsWithKey = key != null ? {\n\t\t...rest,\n\t\tkey\n\t} : rest;\n\tif (typeof type === \"function\") return h(type, children !== void 0 ? {\n\t\t...propsWithKey,\n\t\tchildren\n\t} : propsWithKey);\n\treturn h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);\n}\nconst jsxs = jsx;\n\n//#endregion\nexport { Fragment, jsx, jsxs };\n//# sourceMappingURL=jsx-runtime.js.map","import type { VNodeChild } from \"@pyreon/core\"\nimport { effect } from \"@pyreon/reactivity\"\nimport type { EChartsOption } from \"echarts\"\nimport type { ECElementEvent } from \"echarts/core\"\nimport type { ChartProps } from \"./types\"\nimport { useChart } from \"./use-chart\"\n\n/**\n * Handler type that bridges our duck-typed ChartEventParams with\n * echarts' internal ECElementEvent. Used for event binding casts.\n */\ntype ECHandler = (params: ECElementEvent) => boolean | undefined\n\n/**\n * Reactive chart component. Wraps useChart in a div with automatic\n * event binding.\n *\n * @example\n * ```tsx\n * // Default — any chart type\n * <Chart\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * tooltip: {},\n * })}\n * style=\"height: 400px\"\n * />\n *\n * // Strict — only specific chart types\n * import type { ComposeOption, BarSeriesOption } from '@pyreon/charts'\n * <Chart<ComposeOption<BarSeriesOption>>\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * })}\n * style=\"height: 400px\"\n * />\n * ```\n */\nexport function Chart<TOption extends EChartsOption = EChartsOption>(\n props: ChartProps<TOption>,\n): VNodeChild {\n const chart = useChart(props.options, {\n ...(props.theme != null ? { theme: props.theme } : {}),\n ...(props.renderer != null ? { renderer: props.renderer } : {}),\n })\n\n // Bind events when instance is ready\n effect(() => {\n const inst = chart.instance()\n if (!inst) return\n\n // Handlers are duck-typed ChartEventParams — cast through unknown\n // to ECHandler because echarts/core and echarts export incompatible\n // private class types for ECElementEvent.\n if (props.onClick) inst.on(\"click\", props.onClick as unknown as ECHandler)\n if (props.onMouseover) inst.on(\"mouseover\", props.onMouseover as unknown as ECHandler)\n if (props.onMouseout) inst.on(\"mouseout\", props.onMouseout as unknown as ECHandler)\n })\n\n return () => <div ref={chart.ref} style={props.style} class={props.class} />\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/loader.ts","../src/use-chart.ts","../../../core/core/lib/jsx-runtime.js","../src/chart-component.tsx"],"sourcesContent":["/**\n * Lazy loading and auto-detection for ECharts modules.\n *\n * Maps config keys to ECharts modular imports. Only loads what's needed,\n * caches after first load. The echarts/core module itself is lazy-loaded\n * on first use — zero ECharts bytes until a chart actually renders.\n */\n\n/**\n * Loose option type for internal module analysis.\n * The strict EChartsOption type is used at the consumer-facing API level.\n */\ntype LooseOption = Record<string, unknown> & {\n series?: unknown\n}\n\ntype ModuleLoader = () => Promise<unknown>\n\n/** The argument type that `echarts/core.use()` accepts. */\ntype EChartsUseArg = Parameters<typeof import('echarts/core').use>[0]\n\n// ─── Chart type mapping ─────────────────────────────────────────────────────\n\nconst CHARTS: Record<string, ModuleLoader> = {\n bar: () => import('echarts/charts').then((m) => m.BarChart),\n line: () => import('echarts/charts').then((m) => m.LineChart),\n pie: () => import('echarts/charts').then((m) => m.PieChart),\n scatter: () => import('echarts/charts').then((m) => m.ScatterChart),\n radar: () => import('echarts/charts').then((m) => m.RadarChart),\n heatmap: () => import('echarts/charts').then((m) => m.HeatmapChart),\n treemap: () => import('echarts/charts').then((m) => m.TreemapChart),\n sunburst: () => import('echarts/charts').then((m) => m.SunburstChart),\n sankey: () => import('echarts/charts').then((m) => m.SankeyChart),\n funnel: () => import('echarts/charts').then((m) => m.FunnelChart),\n gauge: () => import('echarts/charts').then((m) => m.GaugeChart),\n graph: () => import('echarts/charts').then((m) => m.GraphChart),\n tree: () => import('echarts/charts').then((m) => m.TreeChart),\n boxplot: () => import('echarts/charts').then((m) => m.BoxplotChart),\n candlestick: () => import('echarts/charts').then((m) => m.CandlestickChart),\n parallel: () => import('echarts/charts').then((m) => m.ParallelChart),\n themeRiver: () => import('echarts/charts').then((m) => m.ThemeRiverChart),\n effectScatter: () => import('echarts/charts').then((m) => m.EffectScatterChart),\n lines: () => import('echarts/charts').then((m) => m.LinesChart),\n pictorialBar: () => import('echarts/charts').then((m) => m.PictorialBarChart),\n custom: () => import('echarts/charts').then((m) => m.CustomChart),\n map: () => import('echarts/charts').then((m) => m.MapChart),\n}\n\n// ─── Component mapping ──────────────────────────────────────────────────────\n\n// Multiple config keys can map to the same component (xAxis/yAxis → Grid)\nconst COMPONENTS: Record<string, ModuleLoader> = {\n grid: () => import('echarts/components').then((m) => m.GridComponent),\n xAxis: () => import('echarts/components').then((m) => m.GridComponent),\n yAxis: () => import('echarts/components').then((m) => m.GridComponent),\n polar: () => import('echarts/components').then((m) => m.PolarComponent),\n radar: () => import('echarts/components').then((m) => m.RadarComponent),\n geo: () => import('echarts/components').then((m) => m.GeoComponent),\n tooltip: () => import('echarts/components').then((m) => m.TooltipComponent),\n legend: () => import('echarts/components').then((m) => m.LegendComponent),\n toolbox: () => import('echarts/components').then((m) => m.ToolboxComponent),\n title: () => import('echarts/components').then((m) => m.TitleComponent),\n dataZoom: () => import('echarts/components').then((m) => m.DataZoomComponent),\n visualMap: () => import('echarts/components').then((m) => m.VisualMapComponent),\n timeline: () => import('echarts/components').then((m) => m.TimelineComponent),\n graphic: () => import('echarts/components').then((m) => m.GraphicComponent),\n brush: () => import('echarts/components').then((m) => m.BrushComponent),\n calendar: () => import('echarts/components').then((m) => m.CalendarComponent),\n dataset: () => import('echarts/components').then((m) => m.DatasetComponent),\n aria: () => import('echarts/components').then((m) => m.AriaComponent),\n}\n\n// Series-level features\nconst SERIES_FEATURES: Record<string, ModuleLoader> = {\n markPoint: () => import('echarts/components').then((m) => m.MarkPointComponent),\n markLine: () => import('echarts/components').then((m) => m.MarkLineComponent),\n markArea: () => import('echarts/components').then((m) => m.MarkAreaComponent),\n}\n\n// ─── Renderers ──────────────────────────────────────────────────────────────\n\nconst RENDERERS: Record<string, ModuleLoader> = {\n canvas: () => import('echarts/renderers').then((m) => m.CanvasRenderer),\n svg: () => import('echarts/renderers').then((m) => m.SVGRenderer),\n}\n\n// ─── Core loading ───────────────────────────────────────────────────────────\n\nlet coreModule: typeof import('echarts/core') | null = null\nlet corePromise: Promise<typeof import('echarts/core')> | null = null\n\n/**\n * Lazily load echarts/core. Cached after first call.\n */\nexport async function getCore(): Promise<typeof import('echarts/core')> {\n if (coreModule) return coreModule\n if (!corePromise) {\n corePromise = import('echarts/core').then((m) => {\n coreModule = m\n return m\n })\n }\n return corePromise\n}\n\n/**\n * Get the cached core module (null if not yet loaded).\n */\nexport function getCoreSync(): typeof import('echarts/core') | null {\n return coreModule\n}\n\n// ─── Module registration ────────────────────────────────────────────────────\n\nconst registered = new Set<string>()\nconst inflight = new Map<string, Promise<void>>()\n\nasync function loadAndRegister(\n core: typeof import('echarts/core'),\n key: string,\n loader: ModuleLoader,\n): Promise<void> {\n if (registered.has(key)) return\n if (inflight.has(key)) return inflight.get(key)\n\n const promise = loader().then((mod) => {\n core.use(mod as EChartsUseArg)\n registered.add(key)\n inflight.delete(key)\n })\n inflight.set(key, promise)\n return promise\n}\n\n/**\n * Analyze an ECharts option object and dynamically import only the\n * required chart types, components, and renderer. All imports are\n * cached — subsequent calls with the same types are instant.\n */\nexport async function ensureModules(\n option: LooseOption,\n renderer: 'canvas' | 'svg' = 'canvas',\n): Promise<typeof import('echarts/core')> {\n const core = await getCore()\n const loads: Promise<void>[] = []\n\n // Renderer (always needed)\n const rendererLoader = RENDERERS[renderer]\n if (rendererLoader) loads.push(loadAndRegister(core, `renderer:${renderer}`, rendererLoader))\n\n // Normalize series to array for analysis\n const rawSeries = option.series\n const seriesList: Record<string, unknown>[] = rawSeries\n ? ((Array.isArray(rawSeries) ? rawSeries : [rawSeries]) as Record<string, unknown>[])\n : []\n\n // Chart types from series[].type\n for (const s of seriesList) {\n const type = s.type as string | undefined\n const chartLoader = type ? CHARTS[type] : undefined\n if (chartLoader) {\n loads.push(loadAndRegister(core, `chart:${type}`, chartLoader))\n }\n }\n\n // Components from top-level config keys\n for (const key of Object.keys(option)) {\n const compLoader = COMPONENTS[key]\n if (compLoader) {\n loads.push(loadAndRegister(core, `component:${key}`, compLoader))\n }\n }\n\n // Series-level features (markPoint, markLine, markArea)\n for (const s of seriesList) {\n for (const key of Object.keys(s)) {\n const featureLoader = SERIES_FEATURES[key]\n if (featureLoader) {\n loads.push(loadAndRegister(core, `feature:${key}`, featureLoader))\n }\n }\n }\n\n await Promise.all(loads)\n return core\n}\n\n/**\n * Manually register ECharts modules (for tree-shaking entry point).\n * Call this at app startup instead of relying on auto-detection.\n *\n * @example\n * ```ts\n * import { use } from '@pyreon/charts/manual'\n * import { BarChart } from 'echarts/charts'\n * import { GridComponent, TooltipComponent } from 'echarts/components'\n * import { CanvasRenderer } from 'echarts/renderers'\n *\n * use(BarChart, GridComponent, TooltipComponent, CanvasRenderer)\n * ```\n */\nexport function manualUse(...modules: unknown[]): void {\n const core = getCoreSync()\n if (core) {\n core.use(modules as EChartsUseArg)\n } else {\n // Core not loaded yet — queue for when it loads\n getCore().then((c) => c.use(modules as any))\n }\n}\n\n// ─── Reset (for testing) ────────────────────────────────────────────────────\n\nexport function _resetLoader(): void {\n registered.clear()\n inflight.clear()\n coreModule = null\n corePromise = null\n}\n","import { onUnmount } from '@pyreon/core'\nimport { effect, signal } from '@pyreon/reactivity'\nimport type { EChartsOption } from 'echarts'\nimport { ensureModules } from './loader'\nimport type { UseChartConfig, UseChartResult } from './types'\n\n/**\n * Reactive ECharts hook. Creates a chart instance bound to a container\n * element, with automatic module lazy-loading, signal tracking, resize\n * handling, error capture, and cleanup.\n *\n * Generic parameter `TOption` narrows the option type for exact autocomplete.\n * Use `ComposeOption<SeriesUnion>` from ECharts to restrict to specific chart types.\n *\n * @example\n * ```tsx\n * // Default — accepts any ECharts option\n * const chart = useChart(() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * }))\n *\n * // Strict — only bar + line allowed, full autocomplete\n * import type { ComposeOption, BarSeriesOption, LineSeriesOption } from '@pyreon/charts'\n * type MyChartOption = ComposeOption<BarSeriesOption | LineSeriesOption>\n *\n * const chart = useChart<MyChartOption>(() => ({\n * series: [{ type: 'bar', data: revenue() }], // ✓\n * }))\n * ```\n */\nexport function useChart<TOption extends EChartsOption = EChartsOption>(\n optionsFn: () => TOption,\n config?: UseChartConfig,\n): UseChartResult {\n const instance = signal<import('echarts/core').ECharts | null>(null)\n const loading = signal(true)\n const error = signal<Error | null>(null)\n const container = signal<HTMLElement | null>(null)\n const renderer = config?.renderer ?? 'canvas'\n\n let observer: ResizeObserver | null = null\n let initialized = false\n\n // Initialize chart when container is bound\n effect(() => {\n const el = container()\n if (!el || initialized) return\n\n initialized = true\n\n let opts: EChartsOption\n try {\n opts = optionsFn()\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n return\n }\n\n // Load required ECharts modules, then create chart\n ensureModules(opts as Record<string, unknown>, renderer)\n .then((core) => {\n // Guard: component may have unmounted during async load\n if (!container.peek()) return\n\n try {\n const chart = core.init(el, (config?.theme ?? null) as string | object | null, {\n renderer,\n ...(config?.locale != null ? { locale: config.locale } : {}),\n ...(config?.devicePixelRatio != null\n ? { devicePixelRatio: config.devicePixelRatio }\n : {}),\n ...(config?.width != null ? { width: config.width } : {}),\n ...(config?.height != null ? { height: config.height } : {}),\n })\n\n chart.setOption(opts)\n instance.set(chart)\n loading.set(false)\n error.set(null)\n\n config?.onInit?.(chart)\n\n // ResizeObserver for auto-resize\n observer = new ResizeObserver(() => {\n chart.resize()\n })\n observer.observe(el)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n }\n })\n .catch((err) => {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n })\n })\n\n // Reactive updates — re-run when signals in optionsFn change\n effect(() => {\n const chart = instance()\n if (!chart) return\n\n try {\n const opts = optionsFn()\n chart.setOption(opts, {\n notMerge: config?.notMerge ?? false,\n lazyUpdate: config?.lazyUpdate ?? true,\n })\n error.set(null)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n }\n })\n\n // Cleanup on unmount\n onUnmount(() => {\n observer?.disconnect()\n observer = null\n\n const chart = instance.peek()\n if (chart) {\n chart.dispose()\n instance.set(null)\n }\n\n initialized = false\n })\n\n return {\n ref: (el: Element | null) => container.set(el as HTMLElement | null),\n instance,\n loading,\n error,\n resize: () => instance.peek()?.resize(),\n }\n}\n","//#region src/h.ts\n/** Marker for fragment nodes — renders children without a wrapper element */\nconst Fragment = Symbol(\"Pyreon.Fragment\");\n/**\n* Hyperscript function — the compiled output of JSX.\n* `<div class=\"x\">hello</div>` → `h(\"div\", { class: \"x\" }, \"hello\")`\n*\n* Generic on P so TypeScript validates props match the component's signature\n* at the call site, then stores the result in the loosely-typed VNode.\n*/\n/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */\nconst EMPTY_PROPS = {};\nfunction h(type, props, ...children) {\n\treturn {\n\t\ttype,\n\t\tprops: props ?? EMPTY_PROPS,\n\t\tchildren: normalizeChildren(children),\n\t\tkey: props?.key ?? null\n\t};\n}\nfunction normalizeChildren(children) {\n\tfor (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);\n\treturn children;\n}\nfunction flattenChildren(children) {\n\tconst result = [];\n\tfor (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));\n\telse result.push(child);\n\treturn result;\n}\n\n//#endregion\n//#region src/jsx-runtime.ts\n/**\n* JSX automatic runtime.\n*\n* When tsconfig has `\"jsxImportSource\": \"@pyreon/core\"`, the TS/bundler compiler\n* rewrites JSX to imports from this file automatically:\n* <div class=\"x\" /> → jsx(\"div\", { class: \"x\" })\n*/\nfunction jsx(type, props, key) {\n\tconst { children, ...rest } = props;\n\tconst propsWithKey = key != null ? {\n\t\t...rest,\n\t\tkey\n\t} : rest;\n\tif (typeof type === \"function\") return h(type, children !== void 0 ? {\n\t\t...propsWithKey,\n\t\tchildren\n\t} : propsWithKey);\n\treturn h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);\n}\nconst jsxs = jsx;\n\n//#endregion\nexport { Fragment, jsx, jsxs };\n//# sourceMappingURL=jsx-runtime.js.map","import type { VNodeChild } from '@pyreon/core'\nimport { effect } from '@pyreon/reactivity'\nimport type { EChartsOption } from 'echarts'\nimport type { ECElementEvent } from 'echarts/core'\nimport type { ChartProps } from './types'\nimport { useChart } from './use-chart'\n\n/**\n * Handler type that bridges our duck-typed ChartEventParams with\n * echarts' internal ECElementEvent. Used for event binding casts.\n */\ntype ECHandler = (params: ECElementEvent) => boolean | undefined\n\n/**\n * Reactive chart component. Wraps useChart in a div with automatic\n * event binding.\n *\n * @example\n * ```tsx\n * // Default — any chart type\n * <Chart\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * tooltip: {},\n * })}\n * style=\"height: 400px\"\n * />\n *\n * // Strict — only specific chart types\n * import type { ComposeOption, BarSeriesOption } from '@pyreon/charts'\n * <Chart<ComposeOption<BarSeriesOption>>\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * })}\n * style=\"height: 400px\"\n * />\n * ```\n */\nexport function Chart<TOption extends EChartsOption = EChartsOption>(\n props: ChartProps<TOption>,\n): VNodeChild {\n const chart = useChart(props.options, {\n ...(props.theme != null ? { theme: props.theme } : {}),\n ...(props.renderer != null ? { renderer: props.renderer } : {}),\n })\n\n // Bind events when instance is ready\n effect(() => {\n const inst = chart.instance()\n if (!inst) return\n\n // Handlers are duck-typed ChartEventParams — cast through unknown\n // to ECHandler because echarts/core and echarts export incompatible\n // private class types for ECElementEvent.\n if (props.onClick) inst.on('click', props.onClick as unknown as ECHandler)\n if (props.onMouseover) inst.on('mouseover', props.onMouseover as unknown as ECHandler)\n if (props.onMouseout) inst.on('mouseout', props.onMouseout as unknown as ECHandler)\n })\n\n return () => <div ref={chart.ref} style={props.style} class={props.class} />\n}\n"],"mappings":";;;;AAuBA,MAAM,SAAuC;CAC3C,WAAW,OAAO,wBAAkB,MAAM,MAAM,EAAE,SAAS;CAC3D,YAAY,OAAO,wBAAkB,MAAM,MAAM,EAAE,UAAU;CAC7D,WAAW,OAAO,wBAAkB,MAAM,MAAM,EAAE,SAAS;CAC3D,eAAe,OAAO,wBAAkB,MAAM,MAAM,EAAE,aAAa;CACnE,aAAa,OAAO,wBAAkB,MAAM,MAAM,EAAE,WAAW;CAC/D,eAAe,OAAO,wBAAkB,MAAM,MAAM,EAAE,aAAa;CACnE,eAAe,OAAO,wBAAkB,MAAM,MAAM,EAAE,aAAa;CACnE,gBAAgB,OAAO,wBAAkB,MAAM,MAAM,EAAE,cAAc;CACrE,cAAc,OAAO,wBAAkB,MAAM,MAAM,EAAE,YAAY;CACjE,cAAc,OAAO,wBAAkB,MAAM,MAAM,EAAE,YAAY;CACjE,aAAa,OAAO,wBAAkB,MAAM,MAAM,EAAE,WAAW;CAC/D,aAAa,OAAO,wBAAkB,MAAM,MAAM,EAAE,WAAW;CAC/D,YAAY,OAAO,wBAAkB,MAAM,MAAM,EAAE,UAAU;CAC7D,eAAe,OAAO,wBAAkB,MAAM,MAAM,EAAE,aAAa;CACnE,mBAAmB,OAAO,wBAAkB,MAAM,MAAM,EAAE,iBAAiB;CAC3E,gBAAgB,OAAO,wBAAkB,MAAM,MAAM,EAAE,cAAc;CACrE,kBAAkB,OAAO,wBAAkB,MAAM,MAAM,EAAE,gBAAgB;CACzE,qBAAqB,OAAO,wBAAkB,MAAM,MAAM,EAAE,mBAAmB;CAC/E,aAAa,OAAO,wBAAkB,MAAM,MAAM,EAAE,WAAW;CAC/D,oBAAoB,OAAO,wBAAkB,MAAM,MAAM,EAAE,kBAAkB;CAC7E,cAAc,OAAO,wBAAkB,MAAM,MAAM,EAAE,YAAY;CACjE,WAAW,OAAO,wBAAkB,MAAM,MAAM,EAAE,SAAS;CAC5D;AAKD,MAAM,aAA2C;CAC/C,YAAY,OAAO,4BAAsB,MAAM,MAAM,EAAE,cAAc;CACrE,aAAa,OAAO,4BAAsB,MAAM,MAAM,EAAE,cAAc;CACtE,aAAa,OAAO,4BAAsB,MAAM,MAAM,EAAE,cAAc;CACtE,aAAa,OAAO,4BAAsB,MAAM,MAAM,EAAE,eAAe;CACvE,aAAa,OAAO,4BAAsB,MAAM,MAAM,EAAE,eAAe;CACvE,WAAW,OAAO,4BAAsB,MAAM,MAAM,EAAE,aAAa;CACnE,eAAe,OAAO,4BAAsB,MAAM,MAAM,EAAE,iBAAiB;CAC3E,cAAc,OAAO,4BAAsB,MAAM,MAAM,EAAE,gBAAgB;CACzE,eAAe,OAAO,4BAAsB,MAAM,MAAM,EAAE,iBAAiB;CAC3E,aAAa,OAAO,4BAAsB,MAAM,MAAM,EAAE,eAAe;CACvE,gBAAgB,OAAO,4BAAsB,MAAM,MAAM,EAAE,kBAAkB;CAC7E,iBAAiB,OAAO,4BAAsB,MAAM,MAAM,EAAE,mBAAmB;CAC/E,gBAAgB,OAAO,4BAAsB,MAAM,MAAM,EAAE,kBAAkB;CAC7E,eAAe,OAAO,4BAAsB,MAAM,MAAM,EAAE,iBAAiB;CAC3E,aAAa,OAAO,4BAAsB,MAAM,MAAM,EAAE,eAAe;CACvE,gBAAgB,OAAO,4BAAsB,MAAM,MAAM,EAAE,kBAAkB;CAC7E,eAAe,OAAO,4BAAsB,MAAM,MAAM,EAAE,iBAAiB;CAC3E,YAAY,OAAO,4BAAsB,MAAM,MAAM,EAAE,cAAc;CACtE;AAGD,MAAM,kBAAgD;CACpD,iBAAiB,OAAO,4BAAsB,MAAM,MAAM,EAAE,mBAAmB;CAC/E,gBAAgB,OAAO,4BAAsB,MAAM,MAAM,EAAE,kBAAkB;CAC7E,gBAAgB,OAAO,4BAAsB,MAAM,MAAM,EAAE,kBAAkB;CAC9E;AAID,MAAM,YAA0C;CAC9C,cAAc,OAAO,2BAAqB,MAAM,MAAM,EAAE,eAAe;CACvE,WAAW,OAAO,2BAAqB,MAAM,MAAM,EAAE,YAAY;CAClE;AAID,IAAI,aAAmD;AACvD,IAAI,cAA6D;;;;AAKjE,eAAsB,UAAkD;AACtE,KAAI,WAAY,QAAO;AACvB,KAAI,CAAC,YACH,eAAc,OAAO,sBAAgB,MAAM,MAAM;AAC/C,eAAa;AACb,SAAO;GACP;AAEJ,QAAO;;AAYT,MAAM,6BAAa,IAAI,KAAa;AACpC,MAAM,2BAAW,IAAI,KAA4B;AAEjD,eAAe,gBACb,MACA,KACA,QACe;AACf,KAAI,WAAW,IAAI,IAAI,CAAE;AACzB,KAAI,SAAS,IAAI,IAAI,CAAE,QAAO,SAAS,IAAI,IAAI;CAE/C,MAAM,UAAU,QAAQ,CAAC,MAAM,QAAQ;AACrC,OAAK,IAAI,IAAqB;AAC9B,aAAW,IAAI,IAAI;AACnB,WAAS,OAAO,IAAI;GACpB;AACF,UAAS,IAAI,KAAK,QAAQ;AAC1B,QAAO;;;;;;;AAQT,eAAsB,cACpB,QACA,WAA6B,UACW;CACxC,MAAM,OAAO,MAAM,SAAS;CAC5B,MAAM,QAAyB,EAAE;CAGjC,MAAM,iBAAiB,UAAU;AACjC,KAAI,eAAgB,OAAM,KAAK,gBAAgB,MAAM,YAAY,YAAY,eAAe,CAAC;CAG7F,MAAM,YAAY,OAAO;CACzB,MAAM,aAAwC,YACxC,MAAM,QAAQ,UAAU,GAAG,YAAY,CAAC,UAAU,GACpD,EAAE;AAGN,MAAK,MAAM,KAAK,YAAY;EAC1B,MAAM,OAAO,EAAE;EACf,MAAM,cAAc,OAAO,OAAO,QAAQ;AAC1C,MAAI,YACF,OAAM,KAAK,gBAAgB,MAAM,SAAS,QAAQ,YAAY,CAAC;;AAKnE,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;EACrC,MAAM,aAAa,WAAW;AAC9B,MAAI,WACF,OAAM,KAAK,gBAAgB,MAAM,aAAa,OAAO,WAAW,CAAC;;AAKrE,MAAK,MAAM,KAAK,WACd,MAAK,MAAM,OAAO,OAAO,KAAK,EAAE,EAAE;EAChC,MAAM,gBAAgB,gBAAgB;AACtC,MAAI,cACF,OAAM,KAAK,gBAAgB,MAAM,WAAW,OAAO,cAAc,CAAC;;AAKxE,OAAM,QAAQ,IAAI,MAAM;AACxB,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1JT,SAAgB,SACd,WACA,QACgB;CAChB,MAAM,WAAW,OAA8C,KAAK;CACpE,MAAM,UAAU,OAAO,KAAK;CAC5B,MAAM,QAAQ,OAAqB,KAAK;CACxC,MAAM,YAAY,OAA2B,KAAK;CAClD,MAAM,WAAW,QAAQ,YAAY;CAErC,IAAI,WAAkC;CACtC,IAAI,cAAc;AAGlB,cAAa;EACX,MAAM,KAAK,WAAW;AACtB,MAAI,CAAC,MAAM,YAAa;AAExB,gBAAc;EAEd,IAAI;AACJ,MAAI;AACF,UAAO,WAAW;WACX,KAAK;AACZ,SAAM,IAAI,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;AAC9D,WAAQ,IAAI,MAAM;AAClB;;AAIF,gBAAc,MAAiC,SAAS,CACrD,MAAM,SAAS;AAEd,OAAI,CAAC,UAAU,MAAM,CAAE;AAEvB,OAAI;IACF,MAAM,QAAQ,KAAK,KAAK,IAAK,QAAQ,SAAS,MAAiC;KAC7E;KACA,GAAI,QAAQ,UAAU,OAAO,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;KAC3D,GAAI,QAAQ,oBAAoB,OAC5B,EAAE,kBAAkB,OAAO,kBAAkB,GAC7C,EAAE;KACN,GAAI,QAAQ,SAAS,OAAO,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;KACxD,GAAI,QAAQ,UAAU,OAAO,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;KAC5D,CAAC;AAEF,UAAM,UAAU,KAAK;AACrB,aAAS,IAAI,MAAM;AACnB,YAAQ,IAAI,MAAM;AAClB,UAAM,IAAI,KAAK;AAEf,YAAQ,SAAS,MAAM;AAGvB,eAAW,IAAI,qBAAqB;AAClC,WAAM,QAAQ;MACd;AACF,aAAS,QAAQ,GAAG;YACb,KAAK;AACZ,UAAM,IAAI,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;AAC9D,YAAQ,IAAI,MAAM;;IAEpB,CACD,OAAO,QAAQ;AACd,SAAM,IAAI,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;AAC9D,WAAQ,IAAI,MAAM;IAClB;GACJ;AAGF,cAAa;EACX,MAAM,QAAQ,UAAU;AACxB,MAAI,CAAC,MAAO;AAEZ,MAAI;GACF,MAAM,OAAO,WAAW;AACxB,SAAM,UAAU,MAAM;IACpB,UAAU,QAAQ,YAAY;IAC9B,YAAY,QAAQ,cAAc;IACnC,CAAC;AACF,SAAM,IAAI,KAAK;WACR,KAAK;AACZ,SAAM,IAAI,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;;GAEhE;AAGF,iBAAgB;AACd,YAAU,YAAY;AACtB,aAAW;EAEX,MAAM,QAAQ,SAAS,MAAM;AAC7B,MAAI,OAAO;AACT,SAAM,SAAS;AACf,YAAS,IAAI,KAAK;;AAGpB,gBAAc;GACd;AAEF,QAAO;EACL,MAAM,OAAuB,UAAU,IAAI,GAAyB;EACpE;EACA;EACA;EACA,cAAc,SAAS,MAAM,EAAE,QAAQ;EACxC;;;;;;;;;;;;;AC7HH,MAAM,cAAc,EAAE;AACtB,SAAS,EAAE,MAAM,OAAO,GAAG,UAAU;AACpC,QAAO;EACN;EACA,OAAO,SAAS;EAChB,UAAU,kBAAkB,SAAS;EACrC,KAAK,OAAO,OAAO;EACnB;;AAEF,SAAS,kBAAkB,UAAU;AACpC,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAK,KAAI,MAAM,QAAQ,SAAS,GAAG,CAAE,QAAO,gBAAgB,SAAS;AAC1G,QAAO;;AAER,SAAS,gBAAgB,UAAU;CAClC,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,SAAS,SAAU,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,KAAK,GAAG,gBAAgB,MAAM,CAAC;KACzF,QAAO,KAAK,MAAM;AACvB,QAAO;;;;;;;;;AAYR,SAAS,IAAI,MAAM,OAAO,KAAK;CAC9B,MAAM,EAAE,UAAU,GAAG,SAAS;CAC9B,MAAM,eAAe,OAAO,OAAO;EAClC,GAAG;EACH;EACA,GAAG;AACJ,KAAI,OAAO,SAAS,WAAY,QAAO,EAAE,MAAM,aAAa,KAAK,IAAI;EACpE,GAAG;EACH;EACA,GAAG,aAAa;AACjB,QAAO,EAAE,MAAM,cAAc,GAAG,aAAa,KAAK,IAAI,EAAE,GAAG,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZ5G,SAAgB,MACd,OACY;CACZ,MAAM,QAAQ,SAAS,MAAM,SAAS;EACpC,GAAI,MAAM,SAAS,OAAO,EAAE,OAAO,MAAM,OAAO,GAAG,EAAE;EACrD,GAAI,MAAM,YAAY,OAAO,EAAE,UAAU,MAAM,UAAU,GAAG,EAAE;EAC/D,CAAC;AAGF,cAAa;EACX,MAAM,OAAO,MAAM,UAAU;AAC7B,MAAI,CAAC,KAAM;AAKX,MAAI,MAAM,QAAS,MAAK,GAAG,SAAS,MAAM,QAAgC;AAC1E,MAAI,MAAM,YAAa,MAAK,GAAG,aAAa,MAAM,YAAoC;AACtF,MAAI,MAAM,WAAY,MAAK,GAAG,YAAY,MAAM,WAAmC;GACnF;AAEF,cAAa,oBAAC,OAAD;EAAK,KAAK,MAAM;EAAK,OAAO,MAAM;EAAO,OAAO,MAAM;EAAS"}
package/lib/manual.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"manual.js","names":[],"sources":["../src/loader.ts","../src/use-chart.ts","../../../core/core/lib/jsx-runtime.js","../src/chart-component.tsx"],"sourcesContent":["/**\n * Lazy loading and auto-detection for ECharts modules.\n *\n * Maps config keys to ECharts modular imports. Only loads what's needed,\n * caches after first load. The echarts/core module itself is lazy-loaded\n * on first use — zero ECharts bytes until a chart actually renders.\n */\n\n/**\n * Loose option type for internal module analysis.\n * The strict EChartsOption type is used at the consumer-facing API level.\n */\ntype LooseOption = Record<string, unknown> & {\n series?: unknown\n}\n\ntype ModuleLoader = () => Promise<unknown>\n\n/** The argument type that `echarts/core.use()` accepts. */\ntype EChartsUseArg = Parameters<typeof import(\"echarts/core\").use>[0]\n\n// ─── Chart type mapping ─────────────────────────────────────────────────────\n\nconst CHARTS: Record<string, ModuleLoader> = {\n bar: () => import(\"echarts/charts\").then((m) => m.BarChart),\n line: () => import(\"echarts/charts\").then((m) => m.LineChart),\n pie: () => import(\"echarts/charts\").then((m) => m.PieChart),\n scatter: () => import(\"echarts/charts\").then((m) => m.ScatterChart),\n radar: () => import(\"echarts/charts\").then((m) => m.RadarChart),\n heatmap: () => import(\"echarts/charts\").then((m) => m.HeatmapChart),\n treemap: () => import(\"echarts/charts\").then((m) => m.TreemapChart),\n sunburst: () => import(\"echarts/charts\").then((m) => m.SunburstChart),\n sankey: () => import(\"echarts/charts\").then((m) => m.SankeyChart),\n funnel: () => import(\"echarts/charts\").then((m) => m.FunnelChart),\n gauge: () => import(\"echarts/charts\").then((m) => m.GaugeChart),\n graph: () => import(\"echarts/charts\").then((m) => m.GraphChart),\n tree: () => import(\"echarts/charts\").then((m) => m.TreeChart),\n boxplot: () => import(\"echarts/charts\").then((m) => m.BoxplotChart),\n candlestick: () => import(\"echarts/charts\").then((m) => m.CandlestickChart),\n parallel: () => import(\"echarts/charts\").then((m) => m.ParallelChart),\n themeRiver: () => import(\"echarts/charts\").then((m) => m.ThemeRiverChart),\n effectScatter: () => import(\"echarts/charts\").then((m) => m.EffectScatterChart),\n lines: () => import(\"echarts/charts\").then((m) => m.LinesChart),\n pictorialBar: () => import(\"echarts/charts\").then((m) => m.PictorialBarChart),\n custom: () => import(\"echarts/charts\").then((m) => m.CustomChart),\n map: () => import(\"echarts/charts\").then((m) => m.MapChart),\n}\n\n// ─── Component mapping ──────────────────────────────────────────────────────\n\n// Multiple config keys can map to the same component (xAxis/yAxis → Grid)\nconst COMPONENTS: Record<string, ModuleLoader> = {\n grid: () => import(\"echarts/components\").then((m) => m.GridComponent),\n xAxis: () => import(\"echarts/components\").then((m) => m.GridComponent),\n yAxis: () => import(\"echarts/components\").then((m) => m.GridComponent),\n polar: () => import(\"echarts/components\").then((m) => m.PolarComponent),\n radar: () => import(\"echarts/components\").then((m) => m.RadarComponent),\n geo: () => import(\"echarts/components\").then((m) => m.GeoComponent),\n tooltip: () => import(\"echarts/components\").then((m) => m.TooltipComponent),\n legend: () => import(\"echarts/components\").then((m) => m.LegendComponent),\n toolbox: () => import(\"echarts/components\").then((m) => m.ToolboxComponent),\n title: () => import(\"echarts/components\").then((m) => m.TitleComponent),\n dataZoom: () => import(\"echarts/components\").then((m) => m.DataZoomComponent),\n visualMap: () => import(\"echarts/components\").then((m) => m.VisualMapComponent),\n timeline: () => import(\"echarts/components\").then((m) => m.TimelineComponent),\n graphic: () => import(\"echarts/components\").then((m) => m.GraphicComponent),\n brush: () => import(\"echarts/components\").then((m) => m.BrushComponent),\n calendar: () => import(\"echarts/components\").then((m) => m.CalendarComponent),\n dataset: () => import(\"echarts/components\").then((m) => m.DatasetComponent),\n aria: () => import(\"echarts/components\").then((m) => m.AriaComponent),\n}\n\n// Series-level features\nconst SERIES_FEATURES: Record<string, ModuleLoader> = {\n markPoint: () => import(\"echarts/components\").then((m) => m.MarkPointComponent),\n markLine: () => import(\"echarts/components\").then((m) => m.MarkLineComponent),\n markArea: () => import(\"echarts/components\").then((m) => m.MarkAreaComponent),\n}\n\n// ─── Renderers ──────────────────────────────────────────────────────────────\n\nconst RENDERERS: Record<string, ModuleLoader> = {\n canvas: () => import(\"echarts/renderers\").then((m) => m.CanvasRenderer),\n svg: () => import(\"echarts/renderers\").then((m) => m.SVGRenderer),\n}\n\n// ─── Core loading ───────────────────────────────────────────────────────────\n\nlet coreModule: typeof import(\"echarts/core\") | null = null\nlet corePromise: Promise<typeof import(\"echarts/core\")> | null = null\n\n/**\n * Lazily load echarts/core. Cached after first call.\n */\nexport async function getCore(): Promise<typeof import(\"echarts/core\")> {\n if (coreModule) return coreModule\n if (!corePromise) {\n corePromise = import(\"echarts/core\").then((m) => {\n coreModule = m\n return m\n })\n }\n return corePromise\n}\n\n/**\n * Get the cached core module (null if not yet loaded).\n */\nexport function getCoreSync(): typeof import(\"echarts/core\") | null {\n return coreModule\n}\n\n// ─── Module registration ────────────────────────────────────────────────────\n\nconst registered = new Set<string>()\nconst inflight = new Map<string, Promise<void>>()\n\nasync function loadAndRegister(\n core: typeof import(\"echarts/core\"),\n key: string,\n loader: ModuleLoader,\n): Promise<void> {\n if (registered.has(key)) return\n if (inflight.has(key)) return inflight.get(key)\n\n const promise = loader().then((mod) => {\n core.use(mod as EChartsUseArg)\n registered.add(key)\n inflight.delete(key)\n })\n inflight.set(key, promise)\n return promise\n}\n\n/**\n * Analyze an ECharts option object and dynamically import only the\n * required chart types, components, and renderer. All imports are\n * cached — subsequent calls with the same types are instant.\n */\nexport async function ensureModules(\n option: LooseOption,\n renderer: \"canvas\" | \"svg\" = \"canvas\",\n): Promise<typeof import(\"echarts/core\")> {\n const core = await getCore()\n const loads: Promise<void>[] = []\n\n // Renderer (always needed)\n const rendererLoader = RENDERERS[renderer]\n if (rendererLoader) loads.push(loadAndRegister(core, `renderer:${renderer}`, rendererLoader))\n\n // Normalize series to array for analysis\n const rawSeries = option.series\n const seriesList: Record<string, unknown>[] = rawSeries\n ? ((Array.isArray(rawSeries) ? rawSeries : [rawSeries]) as Record<string, unknown>[])\n : []\n\n // Chart types from series[].type\n for (const s of seriesList) {\n const type = s.type as string | undefined\n const chartLoader = type ? CHARTS[type] : undefined\n if (chartLoader) {\n loads.push(loadAndRegister(core, `chart:${type}`, chartLoader))\n }\n }\n\n // Components from top-level config keys\n for (const key of Object.keys(option)) {\n const compLoader = COMPONENTS[key]\n if (compLoader) {\n loads.push(loadAndRegister(core, `component:${key}`, compLoader))\n }\n }\n\n // Series-level features (markPoint, markLine, markArea)\n for (const s of seriesList) {\n for (const key of Object.keys(s)) {\n const featureLoader = SERIES_FEATURES[key]\n if (featureLoader) {\n loads.push(loadAndRegister(core, `feature:${key}`, featureLoader))\n }\n }\n }\n\n await Promise.all(loads)\n return core\n}\n\n/**\n * Manually register ECharts modules (for tree-shaking entry point).\n * Call this at app startup instead of relying on auto-detection.\n *\n * @example\n * ```ts\n * import { use } from '@pyreon/charts/manual'\n * import { BarChart } from 'echarts/charts'\n * import { GridComponent, TooltipComponent } from 'echarts/components'\n * import { CanvasRenderer } from 'echarts/renderers'\n *\n * use(BarChart, GridComponent, TooltipComponent, CanvasRenderer)\n * ```\n */\nexport function manualUse(...modules: unknown[]): void {\n const core = getCoreSync()\n if (core) {\n core.use(modules as EChartsUseArg)\n } else {\n // Core not loaded yet — queue for when it loads\n getCore().then((c) => c.use(modules as any))\n }\n}\n\n// ─── Reset (for testing) ────────────────────────────────────────────────────\n\nexport function _resetLoader(): void {\n registered.clear()\n inflight.clear()\n coreModule = null\n corePromise = null\n}\n","import { onUnmount } from \"@pyreon/core\"\nimport { effect, signal } from \"@pyreon/reactivity\"\nimport type { EChartsOption } from \"echarts\"\nimport { ensureModules } from \"./loader\"\nimport type { UseChartConfig, UseChartResult } from \"./types\"\n\n/**\n * Reactive ECharts hook. Creates a chart instance bound to a container\n * element, with automatic module lazy-loading, signal tracking, resize\n * handling, error capture, and cleanup.\n *\n * Generic parameter `TOption` narrows the option type for exact autocomplete.\n * Use `ComposeOption<SeriesUnion>` from ECharts to restrict to specific chart types.\n *\n * @example\n * ```tsx\n * // Default — accepts any ECharts option\n * const chart = useChart(() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * }))\n *\n * // Strict — only bar + line allowed, full autocomplete\n * import type { ComposeOption, BarSeriesOption, LineSeriesOption } from '@pyreon/charts'\n * type MyChartOption = ComposeOption<BarSeriesOption | LineSeriesOption>\n *\n * const chart = useChart<MyChartOption>(() => ({\n * series: [{ type: 'bar', data: revenue() }], // ✓\n * }))\n * ```\n */\nexport function useChart<TOption extends EChartsOption = EChartsOption>(\n optionsFn: () => TOption,\n config?: UseChartConfig,\n): UseChartResult {\n const instance = signal<import(\"echarts/core\").ECharts | null>(null)\n const loading = signal(true)\n const error = signal<Error | null>(null)\n const container = signal<HTMLElement | null>(null)\n const renderer = config?.renderer ?? \"canvas\"\n\n let observer: ResizeObserver | null = null\n let initialized = false\n\n // Initialize chart when container is bound\n effect(() => {\n const el = container()\n if (!el || initialized) return\n\n initialized = true\n\n let opts: EChartsOption\n try {\n opts = optionsFn()\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n return\n }\n\n // Load required ECharts modules, then create chart\n ensureModules(opts as Record<string, unknown>, renderer)\n .then((core) => {\n // Guard: component may have unmounted during async load\n if (!container.peek()) return\n\n try {\n const chart = core.init(el, (config?.theme ?? null) as string | object | null, {\n renderer,\n ...(config?.locale != null ? { locale: config.locale } : {}),\n ...(config?.devicePixelRatio != null\n ? { devicePixelRatio: config.devicePixelRatio }\n : {}),\n ...(config?.width != null ? { width: config.width } : {}),\n ...(config?.height != null ? { height: config.height } : {}),\n })\n\n chart.setOption(opts)\n instance.set(chart)\n loading.set(false)\n error.set(null)\n\n config?.onInit?.(chart)\n\n // ResizeObserver for auto-resize\n observer = new ResizeObserver(() => {\n chart.resize()\n })\n observer.observe(el)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n }\n })\n .catch((err) => {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n })\n })\n\n // Reactive updates — re-run when signals in optionsFn change\n effect(() => {\n const chart = instance()\n if (!chart) return\n\n try {\n const opts = optionsFn()\n chart.setOption(opts, {\n notMerge: config?.notMerge ?? false,\n lazyUpdate: config?.lazyUpdate ?? true,\n })\n error.set(null)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n }\n })\n\n // Cleanup on unmount\n onUnmount(() => {\n observer?.disconnect()\n observer = null\n\n const chart = instance.peek()\n if (chart) {\n chart.dispose()\n instance.set(null)\n }\n\n initialized = false\n })\n\n return {\n ref: (el: Element | null) => container.set(el as HTMLElement | null),\n instance,\n loading,\n error,\n resize: () => instance.peek()?.resize(),\n }\n}\n","//#region src/h.ts\n/** Marker for fragment nodes — renders children without a wrapper element */\nconst Fragment = Symbol(\"Pyreon.Fragment\");\n/**\n* Hyperscript function — the compiled output of JSX.\n* `<div class=\"x\">hello</div>` → `h(\"div\", { class: \"x\" }, \"hello\")`\n*\n* Generic on P so TypeScript validates props match the component's signature\n* at the call site, then stores the result in the loosely-typed VNode.\n*/\n/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */\nconst EMPTY_PROPS = {};\nfunction h(type, props, ...children) {\n\treturn {\n\t\ttype,\n\t\tprops: props ?? EMPTY_PROPS,\n\t\tchildren: normalizeChildren(children),\n\t\tkey: props?.key ?? null\n\t};\n}\nfunction normalizeChildren(children) {\n\tfor (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);\n\treturn children;\n}\nfunction flattenChildren(children) {\n\tconst result = [];\n\tfor (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));\n\telse result.push(child);\n\treturn result;\n}\n\n//#endregion\n//#region src/jsx-runtime.ts\n/**\n* JSX automatic runtime.\n*\n* When tsconfig has `\"jsxImportSource\": \"@pyreon/core\"`, the TS/bundler compiler\n* rewrites JSX to imports from this file automatically:\n* <div class=\"x\" /> → jsx(\"div\", { class: \"x\" })\n*/\nfunction jsx(type, props, key) {\n\tconst { children, ...rest } = props;\n\tconst propsWithKey = key != null ? {\n\t\t...rest,\n\t\tkey\n\t} : rest;\n\tif (typeof type === \"function\") return h(type, children !== void 0 ? {\n\t\t...propsWithKey,\n\t\tchildren\n\t} : propsWithKey);\n\treturn h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);\n}\nconst jsxs = jsx;\n\n//#endregion\nexport { Fragment, jsx, jsxs };\n//# sourceMappingURL=jsx-runtime.js.map","import type { VNodeChild } from \"@pyreon/core\"\nimport { effect } from \"@pyreon/reactivity\"\nimport type { EChartsOption } from \"echarts\"\nimport type { ECElementEvent } from \"echarts/core\"\nimport type { ChartProps } from \"./types\"\nimport { useChart } from \"./use-chart\"\n\n/**\n * Handler type that bridges our duck-typed ChartEventParams with\n * echarts' internal ECElementEvent. Used for event binding casts.\n */\ntype ECHandler = (params: ECElementEvent) => boolean | undefined\n\n/**\n * Reactive chart component. Wraps useChart in a div with automatic\n * event binding.\n *\n * @example\n * ```tsx\n * // Default — any chart type\n * <Chart\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * tooltip: {},\n * })}\n * style=\"height: 400px\"\n * />\n *\n * // Strict — only specific chart types\n * import type { ComposeOption, BarSeriesOption } from '@pyreon/charts'\n * <Chart<ComposeOption<BarSeriesOption>>\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * })}\n * style=\"height: 400px\"\n * />\n * ```\n */\nexport function Chart<TOption extends EChartsOption = EChartsOption>(\n props: ChartProps<TOption>,\n): VNodeChild {\n const chart = useChart(props.options, {\n ...(props.theme != null ? { theme: props.theme } : {}),\n ...(props.renderer != null ? { renderer: props.renderer } : {}),\n })\n\n // Bind events when instance is ready\n effect(() => {\n const inst = chart.instance()\n if (!inst) return\n\n // Handlers are duck-typed ChartEventParams — cast through unknown\n // to ECHandler because echarts/core and echarts export incompatible\n // private class types for ECElementEvent.\n if (props.onClick) inst.on(\"click\", props.onClick as unknown as ECHandler)\n if (props.onMouseover) inst.on(\"mouseover\", props.onMouseover as unknown as ECHandler)\n if (props.onMouseout) inst.on(\"mouseout\", props.onMouseout as unknown as ECHandler)\n })\n\n return () => <div ref={chart.ref} style={props.style} class={props.class} />\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manual.js","names":[],"sources":["../src/loader.ts","../src/use-chart.ts","../../../core/core/lib/jsx-runtime.js","../src/chart-component.tsx"],"sourcesContent":["/**\n * Lazy loading and auto-detection for ECharts modules.\n *\n * Maps config keys to ECharts modular imports. Only loads what's needed,\n * caches after first load. The echarts/core module itself is lazy-loaded\n * on first use — zero ECharts bytes until a chart actually renders.\n */\n\n/**\n * Loose option type for internal module analysis.\n * The strict EChartsOption type is used at the consumer-facing API level.\n */\ntype LooseOption = Record<string, unknown> & {\n series?: unknown\n}\n\ntype ModuleLoader = () => Promise<unknown>\n\n/** The argument type that `echarts/core.use()` accepts. */\ntype EChartsUseArg = Parameters<typeof import('echarts/core').use>[0]\n\n// ─── Chart type mapping ─────────────────────────────────────────────────────\n\nconst CHARTS: Record<string, ModuleLoader> = {\n bar: () => import('echarts/charts').then((m) => m.BarChart),\n line: () => import('echarts/charts').then((m) => m.LineChart),\n pie: () => import('echarts/charts').then((m) => m.PieChart),\n scatter: () => import('echarts/charts').then((m) => m.ScatterChart),\n radar: () => import('echarts/charts').then((m) => m.RadarChart),\n heatmap: () => import('echarts/charts').then((m) => m.HeatmapChart),\n treemap: () => import('echarts/charts').then((m) => m.TreemapChart),\n sunburst: () => import('echarts/charts').then((m) => m.SunburstChart),\n sankey: () => import('echarts/charts').then((m) => m.SankeyChart),\n funnel: () => import('echarts/charts').then((m) => m.FunnelChart),\n gauge: () => import('echarts/charts').then((m) => m.GaugeChart),\n graph: () => import('echarts/charts').then((m) => m.GraphChart),\n tree: () => import('echarts/charts').then((m) => m.TreeChart),\n boxplot: () => import('echarts/charts').then((m) => m.BoxplotChart),\n candlestick: () => import('echarts/charts').then((m) => m.CandlestickChart),\n parallel: () => import('echarts/charts').then((m) => m.ParallelChart),\n themeRiver: () => import('echarts/charts').then((m) => m.ThemeRiverChart),\n effectScatter: () => import('echarts/charts').then((m) => m.EffectScatterChart),\n lines: () => import('echarts/charts').then((m) => m.LinesChart),\n pictorialBar: () => import('echarts/charts').then((m) => m.PictorialBarChart),\n custom: () => import('echarts/charts').then((m) => m.CustomChart),\n map: () => import('echarts/charts').then((m) => m.MapChart),\n}\n\n// ─── Component mapping ──────────────────────────────────────────────────────\n\n// Multiple config keys can map to the same component (xAxis/yAxis → Grid)\nconst COMPONENTS: Record<string, ModuleLoader> = {\n grid: () => import('echarts/components').then((m) => m.GridComponent),\n xAxis: () => import('echarts/components').then((m) => m.GridComponent),\n yAxis: () => import('echarts/components').then((m) => m.GridComponent),\n polar: () => import('echarts/components').then((m) => m.PolarComponent),\n radar: () => import('echarts/components').then((m) => m.RadarComponent),\n geo: () => import('echarts/components').then((m) => m.GeoComponent),\n tooltip: () => import('echarts/components').then((m) => m.TooltipComponent),\n legend: () => import('echarts/components').then((m) => m.LegendComponent),\n toolbox: () => import('echarts/components').then((m) => m.ToolboxComponent),\n title: () => import('echarts/components').then((m) => m.TitleComponent),\n dataZoom: () => import('echarts/components').then((m) => m.DataZoomComponent),\n visualMap: () => import('echarts/components').then((m) => m.VisualMapComponent),\n timeline: () => import('echarts/components').then((m) => m.TimelineComponent),\n graphic: () => import('echarts/components').then((m) => m.GraphicComponent),\n brush: () => import('echarts/components').then((m) => m.BrushComponent),\n calendar: () => import('echarts/components').then((m) => m.CalendarComponent),\n dataset: () => import('echarts/components').then((m) => m.DatasetComponent),\n aria: () => import('echarts/components').then((m) => m.AriaComponent),\n}\n\n// Series-level features\nconst SERIES_FEATURES: Record<string, ModuleLoader> = {\n markPoint: () => import('echarts/components').then((m) => m.MarkPointComponent),\n markLine: () => import('echarts/components').then((m) => m.MarkLineComponent),\n markArea: () => import('echarts/components').then((m) => m.MarkAreaComponent),\n}\n\n// ─── Renderers ──────────────────────────────────────────────────────────────\n\nconst RENDERERS: Record<string, ModuleLoader> = {\n canvas: () => import('echarts/renderers').then((m) => m.CanvasRenderer),\n svg: () => import('echarts/renderers').then((m) => m.SVGRenderer),\n}\n\n// ─── Core loading ───────────────────────────────────────────────────────────\n\nlet coreModule: typeof import('echarts/core') | null = null\nlet corePromise: Promise<typeof import('echarts/core')> | null = null\n\n/**\n * Lazily load echarts/core. Cached after first call.\n */\nexport async function getCore(): Promise<typeof import('echarts/core')> {\n if (coreModule) return coreModule\n if (!corePromise) {\n corePromise = import('echarts/core').then((m) => {\n coreModule = m\n return m\n })\n }\n return corePromise\n}\n\n/**\n * Get the cached core module (null if not yet loaded).\n */\nexport function getCoreSync(): typeof import('echarts/core') | null {\n return coreModule\n}\n\n// ─── Module registration ────────────────────────────────────────────────────\n\nconst registered = new Set<string>()\nconst inflight = new Map<string, Promise<void>>()\n\nasync function loadAndRegister(\n core: typeof import('echarts/core'),\n key: string,\n loader: ModuleLoader,\n): Promise<void> {\n if (registered.has(key)) return\n if (inflight.has(key)) return inflight.get(key)\n\n const promise = loader().then((mod) => {\n core.use(mod as EChartsUseArg)\n registered.add(key)\n inflight.delete(key)\n })\n inflight.set(key, promise)\n return promise\n}\n\n/**\n * Analyze an ECharts option object and dynamically import only the\n * required chart types, components, and renderer. All imports are\n * cached — subsequent calls with the same types are instant.\n */\nexport async function ensureModules(\n option: LooseOption,\n renderer: 'canvas' | 'svg' = 'canvas',\n): Promise<typeof import('echarts/core')> {\n const core = await getCore()\n const loads: Promise<void>[] = []\n\n // Renderer (always needed)\n const rendererLoader = RENDERERS[renderer]\n if (rendererLoader) loads.push(loadAndRegister(core, `renderer:${renderer}`, rendererLoader))\n\n // Normalize series to array for analysis\n const rawSeries = option.series\n const seriesList: Record<string, unknown>[] = rawSeries\n ? ((Array.isArray(rawSeries) ? rawSeries : [rawSeries]) as Record<string, unknown>[])\n : []\n\n // Chart types from series[].type\n for (const s of seriesList) {\n const type = s.type as string | undefined\n const chartLoader = type ? CHARTS[type] : undefined\n if (chartLoader) {\n loads.push(loadAndRegister(core, `chart:${type}`, chartLoader))\n }\n }\n\n // Components from top-level config keys\n for (const key of Object.keys(option)) {\n const compLoader = COMPONENTS[key]\n if (compLoader) {\n loads.push(loadAndRegister(core, `component:${key}`, compLoader))\n }\n }\n\n // Series-level features (markPoint, markLine, markArea)\n for (const s of seriesList) {\n for (const key of Object.keys(s)) {\n const featureLoader = SERIES_FEATURES[key]\n if (featureLoader) {\n loads.push(loadAndRegister(core, `feature:${key}`, featureLoader))\n }\n }\n }\n\n await Promise.all(loads)\n return core\n}\n\n/**\n * Manually register ECharts modules (for tree-shaking entry point).\n * Call this at app startup instead of relying on auto-detection.\n *\n * @example\n * ```ts\n * import { use } from '@pyreon/charts/manual'\n * import { BarChart } from 'echarts/charts'\n * import { GridComponent, TooltipComponent } from 'echarts/components'\n * import { CanvasRenderer } from 'echarts/renderers'\n *\n * use(BarChart, GridComponent, TooltipComponent, CanvasRenderer)\n * ```\n */\nexport function manualUse(...modules: unknown[]): void {\n const core = getCoreSync()\n if (core) {\n core.use(modules as EChartsUseArg)\n } else {\n // Core not loaded yet — queue for when it loads\n getCore().then((c) => c.use(modules as any))\n }\n}\n\n// ─── Reset (for testing) ────────────────────────────────────────────────────\n\nexport function _resetLoader(): void {\n registered.clear()\n inflight.clear()\n coreModule = null\n corePromise = null\n}\n","import { onUnmount } from '@pyreon/core'\nimport { effect, signal } from '@pyreon/reactivity'\nimport type { EChartsOption } from 'echarts'\nimport { ensureModules } from './loader'\nimport type { UseChartConfig, UseChartResult } from './types'\n\n/**\n * Reactive ECharts hook. Creates a chart instance bound to a container\n * element, with automatic module lazy-loading, signal tracking, resize\n * handling, error capture, and cleanup.\n *\n * Generic parameter `TOption` narrows the option type for exact autocomplete.\n * Use `ComposeOption<SeriesUnion>` from ECharts to restrict to specific chart types.\n *\n * @example\n * ```tsx\n * // Default — accepts any ECharts option\n * const chart = useChart(() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * }))\n *\n * // Strict — only bar + line allowed, full autocomplete\n * import type { ComposeOption, BarSeriesOption, LineSeriesOption } from '@pyreon/charts'\n * type MyChartOption = ComposeOption<BarSeriesOption | LineSeriesOption>\n *\n * const chart = useChart<MyChartOption>(() => ({\n * series: [{ type: 'bar', data: revenue() }], // ✓\n * }))\n * ```\n */\nexport function useChart<TOption extends EChartsOption = EChartsOption>(\n optionsFn: () => TOption,\n config?: UseChartConfig,\n): UseChartResult {\n const instance = signal<import('echarts/core').ECharts | null>(null)\n const loading = signal(true)\n const error = signal<Error | null>(null)\n const container = signal<HTMLElement | null>(null)\n const renderer = config?.renderer ?? 'canvas'\n\n let observer: ResizeObserver | null = null\n let initialized = false\n\n // Initialize chart when container is bound\n effect(() => {\n const el = container()\n if (!el || initialized) return\n\n initialized = true\n\n let opts: EChartsOption\n try {\n opts = optionsFn()\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n return\n }\n\n // Load required ECharts modules, then create chart\n ensureModules(opts as Record<string, unknown>, renderer)\n .then((core) => {\n // Guard: component may have unmounted during async load\n if (!container.peek()) return\n\n try {\n const chart = core.init(el, (config?.theme ?? null) as string | object | null, {\n renderer,\n ...(config?.locale != null ? { locale: config.locale } : {}),\n ...(config?.devicePixelRatio != null\n ? { devicePixelRatio: config.devicePixelRatio }\n : {}),\n ...(config?.width != null ? { width: config.width } : {}),\n ...(config?.height != null ? { height: config.height } : {}),\n })\n\n chart.setOption(opts)\n instance.set(chart)\n loading.set(false)\n error.set(null)\n\n config?.onInit?.(chart)\n\n // ResizeObserver for auto-resize\n observer = new ResizeObserver(() => {\n chart.resize()\n })\n observer.observe(el)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n }\n })\n .catch((err) => {\n error.set(err instanceof Error ? err : new Error(String(err)))\n loading.set(false)\n })\n })\n\n // Reactive updates — re-run when signals in optionsFn change\n effect(() => {\n const chart = instance()\n if (!chart) return\n\n try {\n const opts = optionsFn()\n chart.setOption(opts, {\n notMerge: config?.notMerge ?? false,\n lazyUpdate: config?.lazyUpdate ?? true,\n })\n error.set(null)\n } catch (err) {\n error.set(err instanceof Error ? err : new Error(String(err)))\n }\n })\n\n // Cleanup on unmount\n onUnmount(() => {\n observer?.disconnect()\n observer = null\n\n const chart = instance.peek()\n if (chart) {\n chart.dispose()\n instance.set(null)\n }\n\n initialized = false\n })\n\n return {\n ref: (el: Element | null) => container.set(el as HTMLElement | null),\n instance,\n loading,\n error,\n resize: () => instance.peek()?.resize(),\n }\n}\n","//#region src/h.ts\n/** Marker for fragment nodes — renders children without a wrapper element */\nconst Fragment = Symbol(\"Pyreon.Fragment\");\n/**\n* Hyperscript function — the compiled output of JSX.\n* `<div class=\"x\">hello</div>` → `h(\"div\", { class: \"x\" }, \"hello\")`\n*\n* Generic on P so TypeScript validates props match the component's signature\n* at the call site, then stores the result in the loosely-typed VNode.\n*/\n/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */\nconst EMPTY_PROPS = {};\nfunction h(type, props, ...children) {\n\treturn {\n\t\ttype,\n\t\tprops: props ?? EMPTY_PROPS,\n\t\tchildren: normalizeChildren(children),\n\t\tkey: props?.key ?? null\n\t};\n}\nfunction normalizeChildren(children) {\n\tfor (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);\n\treturn children;\n}\nfunction flattenChildren(children) {\n\tconst result = [];\n\tfor (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));\n\telse result.push(child);\n\treturn result;\n}\n\n//#endregion\n//#region src/jsx-runtime.ts\n/**\n* JSX automatic runtime.\n*\n* When tsconfig has `\"jsxImportSource\": \"@pyreon/core\"`, the TS/bundler compiler\n* rewrites JSX to imports from this file automatically:\n* <div class=\"x\" /> → jsx(\"div\", { class: \"x\" })\n*/\nfunction jsx(type, props, key) {\n\tconst { children, ...rest } = props;\n\tconst propsWithKey = key != null ? {\n\t\t...rest,\n\t\tkey\n\t} : rest;\n\tif (typeof type === \"function\") return h(type, children !== void 0 ? {\n\t\t...propsWithKey,\n\t\tchildren\n\t} : propsWithKey);\n\treturn h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);\n}\nconst jsxs = jsx;\n\n//#endregion\nexport { Fragment, jsx, jsxs };\n//# sourceMappingURL=jsx-runtime.js.map","import type { VNodeChild } from '@pyreon/core'\nimport { effect } from '@pyreon/reactivity'\nimport type { EChartsOption } from 'echarts'\nimport type { ECElementEvent } from 'echarts/core'\nimport type { ChartProps } from './types'\nimport { useChart } from './use-chart'\n\n/**\n * Handler type that bridges our duck-typed ChartEventParams with\n * echarts' internal ECElementEvent. Used for event binding casts.\n */\ntype ECHandler = (params: ECElementEvent) => boolean | undefined\n\n/**\n * Reactive chart component. Wraps useChart in a div with automatic\n * event binding.\n *\n * @example\n * ```tsx\n * // Default — any chart type\n * <Chart\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * tooltip: {},\n * })}\n * style=\"height: 400px\"\n * />\n *\n * // Strict — only specific chart types\n * import type { ComposeOption, BarSeriesOption } from '@pyreon/charts'\n * <Chart<ComposeOption<BarSeriesOption>>\n * options={() => ({\n * series: [{ type: 'bar', data: revenue() }],\n * })}\n * style=\"height: 400px\"\n * />\n * ```\n */\nexport function Chart<TOption extends EChartsOption = EChartsOption>(\n props: ChartProps<TOption>,\n): VNodeChild {\n const chart = useChart(props.options, {\n ...(props.theme != null ? { theme: props.theme } : {}),\n ...(props.renderer != null ? { renderer: props.renderer } : {}),\n })\n\n // Bind events when instance is ready\n effect(() => {\n const inst = chart.instance()\n if (!inst) return\n\n // Handlers are duck-typed ChartEventParams — cast through unknown\n // to ECHandler because echarts/core and echarts export incompatible\n // private class types for ECElementEvent.\n if (props.onClick) inst.on('click', props.onClick as unknown as ECHandler)\n if (props.onMouseover) inst.on('mouseover', props.onMouseover as unknown as ECHandler)\n if (props.onMouseout) inst.on('mouseout', props.onMouseout as unknown as ECHandler)\n })\n\n return () => <div ref={chart.ref} style={props.style} class={props.class} />\n}\n"],"mappings":"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"}
@@ -2108,7 +2108,7 @@ interface UseChartConfig {
2108
2108
  /** ECharts theme — 'dark', a registered theme name, or a theme object */
2109
2109
  theme?: string | Record<string, unknown>;
2110
2110
  /** Renderer — 'canvas' (default, best performance) or 'svg' */
2111
- renderer?: "canvas" | "svg";
2111
+ renderer?: 'canvas' | 'svg';
2112
2112
  /** ECharts locale — 'EN' (default), 'ZH', etc. */
2113
2113
  locale?: string;
2114
2114
  /** Whether to replace all options instead of merging — default: false */
@@ -2149,7 +2149,7 @@ interface ChartProps<TOption extends EChartsOption = EChartsOption> extends Prop
2149
2149
  /** ECharts theme */
2150
2150
  theme?: string | Record<string, unknown>;
2151
2151
  /** Renderer — 'canvas' (default) or 'svg' */
2152
- renderer?: "canvas" | "svg";
2152
+ renderer?: 'canvas' | 'svg';
2153
2153
  /** CSS style for the container div */
2154
2154
  style?: string;
2155
2155
  /** CSS class for the container div */
@@ -2108,7 +2108,7 @@ interface UseChartConfig {
2108
2108
  /** ECharts theme — 'dark', a registered theme name, or a theme object */
2109
2109
  theme?: string | Record<string, unknown>;
2110
2110
  /** Renderer — 'canvas' (default, best performance) or 'svg' */
2111
- renderer?: "canvas" | "svg";
2111
+ renderer?: 'canvas' | 'svg';
2112
2112
  /** ECharts locale — 'EN' (default), 'ZH', etc. */
2113
2113
  locale?: string;
2114
2114
  /** Whether to replace all options instead of merging — default: false */
@@ -2149,7 +2149,7 @@ interface ChartProps<TOption extends EChartsOption = EChartsOption> extends Prop
2149
2149
  /** ECharts theme */
2150
2150
  theme?: string | Record<string, unknown>;
2151
2151
  /** Renderer — 'canvas' (default) or 'svg' */
2152
- renderer?: "canvas" | "svg";
2152
+ renderer?: 'canvas' | 'svg';
2153
2153
  /** CSS style for the container div */
2154
2154
  style?: string;
2155
2155
  /** CSS class for the container div */
package/package.json CHANGED
@@ -1,28 +1,25 @@
1
1
  {
2
2
  "name": "@pyreon/charts",
3
- "version": "0.11.4",
3
+ "version": "0.11.6",
4
4
  "description": "Reactive ECharts bridge for Pyreon — lazy loading, signal-driven, Canvas by default",
5
+ "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/charts#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/pyreon/pyreon/issues"
8
+ },
5
9
  "license": "MIT",
6
10
  "repository": {
7
11
  "type": "git",
8
12
  "url": "https://github.com/pyreon/pyreon.git",
9
13
  "directory": "packages/fundamentals/charts"
10
14
  },
11
- "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/charts#readme",
12
- "bugs": {
13
- "url": "https://github.com/pyreon/pyreon/issues"
14
- },
15
- "publishConfig": {
16
- "access": "public"
17
- },
18
15
  "files": [
19
16
  "lib",
20
17
  "src",
21
18
  "README.md",
22
19
  "LICENSE"
23
20
  ],
24
- "sideEffects": false,
25
21
  "type": "module",
22
+ "sideEffects": false,
26
23
  "main": "./lib/index.js",
27
24
  "module": "./lib/index.js",
28
25
  "types": "./lib/types/index.d.ts",
@@ -38,22 +35,25 @@
38
35
  "types": "./lib/types/manual.d.ts"
39
36
  }
40
37
  },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
41
  "scripts": {
42
42
  "build": "vl_rolldown_build",
43
43
  "dev": "vl_rolldown_build-watch",
44
44
  "test": "vitest run",
45
45
  "typecheck": "tsc --noEmit",
46
- "lint": "biome check ."
47
- },
48
- "peerDependencies": {
49
- "@pyreon/core": "^0.11.4",
50
- "@pyreon/reactivity": "^0.11.4",
51
- "echarts": ">=5.6.0"
46
+ "lint": "oxlint ."
52
47
  },
53
48
  "devDependencies": {
54
- "@pyreon/core": "^0.11.4",
55
- "@pyreon/reactivity": "^0.11.4",
56
- "@pyreon/runtime-dom": "^0.11.4",
49
+ "@pyreon/core": "^0.11.6",
50
+ "@pyreon/reactivity": "^0.11.6",
51
+ "@pyreon/runtime-dom": "^0.11.6",
57
52
  "echarts": "^6.0.0"
53
+ },
54
+ "peerDependencies": {
55
+ "@pyreon/core": "^0.11.6",
56
+ "@pyreon/reactivity": "^0.11.6",
57
+ "echarts": ">=5.6.0"
58
58
  }
59
59
  }
@@ -1,9 +1,9 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import { effect } from "@pyreon/reactivity"
3
- import type { EChartsOption } from "echarts"
4
- import type { ECElementEvent } from "echarts/core"
5
- import type { ChartProps } from "./types"
6
- import { useChart } from "./use-chart"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import { effect } from '@pyreon/reactivity'
3
+ import type { EChartsOption } from 'echarts'
4
+ import type { ECElementEvent } from 'echarts/core'
5
+ import type { ChartProps } from './types'
6
+ import { useChart } from './use-chart'
7
7
 
8
8
  /**
9
9
  * Handler type that bridges our duck-typed ChartEventParams with
@@ -52,9 +52,9 @@ export function Chart<TOption extends EChartsOption = EChartsOption>(
52
52
  // Handlers are duck-typed ChartEventParams — cast through unknown
53
53
  // to ECHandler because echarts/core and echarts export incompatible
54
54
  // private class types for ECElementEvent.
55
- if (props.onClick) inst.on("click", props.onClick as unknown as ECHandler)
56
- if (props.onMouseover) inst.on("mouseover", props.onMouseover as unknown as ECHandler)
57
- if (props.onMouseout) inst.on("mouseout", props.onMouseout as unknown as ECHandler)
55
+ if (props.onClick) inst.on('click', props.onClick as unknown as ECHandler)
56
+ if (props.onMouseover) inst.on('mouseover', props.onMouseover as unknown as ECHandler)
57
+ if (props.onMouseout) inst.on('mouseout', props.onMouseout as unknown as ECHandler)
58
58
  })
59
59
 
60
60
  return () => <div ref={chart.ref} style={props.style} class={props.class} />
package/src/index.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  * ```
23
23
  */
24
24
 
25
- export { Chart } from "./chart-component"
25
+ export { Chart } from './chart-component'
26
26
  // Chart configuration types
27
27
  // Re-exported ECharts types for consumer convenience —
28
28
  // consumers get full autocomplete without importing echarts directly
@@ -60,5 +60,5 @@ export type {
60
60
  UseChartConfig,
61
61
  UseChartResult,
62
62
  VisualMapComponentOption,
63
- } from "./types"
64
- export { useChart } from "./use-chart"
63
+ } from './types'
64
+ export { useChart } from './use-chart'