@pyreon/charts 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/lib/analysis/index.js.html +5406 -0
  4. package/lib/analysis/manual.js.html +5406 -0
  5. package/lib/charts-Ckh2qxB5.js +17571 -0
  6. package/lib/charts-Ckh2qxB5.js.map +1 -0
  7. package/lib/components-BcPePBeS.js +13688 -0
  8. package/lib/components-BcPePBeS.js.map +1 -0
  9. package/lib/core-9w0g6EOI.js +200 -0
  10. package/lib/core-9w0g6EOI.js.map +1 -0
  11. package/lib/createSeriesData-DOHScdgk.js +412 -0
  12. package/lib/createSeriesData-DOHScdgk.js.map +1 -0
  13. package/lib/customGraphicKeyframeAnimation-CvkEkSt_.js +8524 -0
  14. package/lib/customGraphicKeyframeAnimation-CvkEkSt_.js.map +1 -0
  15. package/lib/graphic-CPJ2K90a.js +10771 -0
  16. package/lib/graphic-CPJ2K90a.js.map +1 -0
  17. package/lib/index.js +309 -0
  18. package/lib/index.js.map +1 -0
  19. package/lib/manual.js +334 -0
  20. package/lib/manual.js.map +1 -0
  21. package/lib/parseGeoJson-BlBe5Vig.js +18498 -0
  22. package/lib/parseGeoJson-BlBe5Vig.js.map +1 -0
  23. package/lib/renderers-Dytryvoy.js +2044 -0
  24. package/lib/renderers-Dytryvoy.js.map +1 -0
  25. package/lib/types/charts.d.ts +7968 -0
  26. package/lib/types/charts.d.ts.map +1 -0
  27. package/lib/types/components.d.ts +4074 -0
  28. package/lib/types/components.d.ts.map +1 -0
  29. package/lib/types/core.d.ts +98 -0
  30. package/lib/types/core.d.ts.map +1 -0
  31. package/lib/types/createSeriesData.d.ts +325 -0
  32. package/lib/types/createSeriesData.d.ts.map +1 -0
  33. package/lib/types/customGraphicKeyframeAnimation.d.ts +3531 -0
  34. package/lib/types/customGraphicKeyframeAnimation.d.ts.map +1 -0
  35. package/lib/types/graphic.d.ts +4043 -0
  36. package/lib/types/graphic.d.ts.map +1 -0
  37. package/lib/types/index.d.ts +255 -0
  38. package/lib/types/index.d.ts.map +1 -0
  39. package/lib/types/index2.d.ts +2221 -0
  40. package/lib/types/index2.d.ts.map +1 -0
  41. package/lib/types/manual.d.ts +279 -0
  42. package/lib/types/manual.d.ts.map +1 -0
  43. package/lib/types/manual2.d.ts +2238 -0
  44. package/lib/types/manual2.d.ts.map +1 -0
  45. package/lib/types/parseGeoJson.d.ts +8695 -0
  46. package/lib/types/parseGeoJson.d.ts.map +1 -0
  47. package/lib/types/renderers.d.ts +995 -0
  48. package/lib/types/renderers.d.ts.map +1 -0
  49. package/package.json +58 -0
  50. package/src/chart-component.tsx +53 -0
  51. package/src/index.ts +64 -0
  52. package/src/loader.ts +222 -0
  53. package/src/manual.ts +36 -0
  54. package/src/tests/charts.test.tsx +363 -0
  55. package/src/types.ts +118 -0
  56. package/src/use-chart.ts +136 -0
@@ -0,0 +1,363 @@
1
+ import { mount } from '@pyreon/runtime-dom'
2
+ import { Chart } from '../chart-component'
3
+ import {
4
+ _resetLoader,
5
+ ensureModules,
6
+ getCore,
7
+ getCoreSync,
8
+ manualUse,
9
+ } from '../loader'
10
+
11
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
12
+
13
+ function mountWith<T>(fn: () => T): { result: T; unmount: () => void } {
14
+ let result: T | undefined
15
+ const el = document.createElement('div')
16
+ document.body.appendChild(el)
17
+ const Child = () => {
18
+ result = fn()
19
+ return null
20
+ }
21
+ const unmount = mount(<Child />, el)
22
+ return {
23
+ result: result!,
24
+ unmount: () => {
25
+ unmount()
26
+ el.remove()
27
+ },
28
+ }
29
+ }
30
+
31
+ afterEach(() => {
32
+ _resetLoader()
33
+ })
34
+
35
+ // ─── Loader ───────────────────────────────────────────────────────────────────
36
+
37
+ describe('loader', () => {
38
+ it('lazily loads echarts/core on first call', async () => {
39
+ const core = await getCore()
40
+ expect(core).toBeDefined()
41
+ expect(typeof core.init).toBe('function')
42
+ expect(typeof core.use).toBe('function')
43
+ })
44
+
45
+ it('caches core module on subsequent calls', async () => {
46
+ const core1 = await getCore()
47
+ const core2 = await getCore()
48
+ expect(core1).toBe(core2)
49
+ })
50
+
51
+ it('auto-detects BarChart from series type', async () => {
52
+ const core = await ensureModules({
53
+ series: [{ type: 'bar', data: [1, 2, 3] }],
54
+ })
55
+ expect(core).toBeDefined()
56
+ // If it didn't throw, the modules were registered successfully
57
+ })
58
+
59
+ it('auto-detects PieChart from series type', async () => {
60
+ const core = await ensureModules({
61
+ series: [{ type: 'pie', data: [{ value: 1 }] }],
62
+ })
63
+ expect(core).toBeDefined()
64
+ })
65
+
66
+ it('auto-detects LineChart from series type', async () => {
67
+ const core = await ensureModules({
68
+ series: [{ type: 'line', data: [1, 2, 3] }],
69
+ })
70
+ expect(core).toBeDefined()
71
+ })
72
+
73
+ it('auto-detects components from config keys', async () => {
74
+ const core = await ensureModules({
75
+ tooltip: { trigger: 'axis' },
76
+ legend: {},
77
+ xAxis: { type: 'category' },
78
+ yAxis: { type: 'value' },
79
+ series: [{ type: 'bar', data: [1] }],
80
+ })
81
+ expect(core).toBeDefined()
82
+ })
83
+
84
+ it('auto-detects series features (markPoint, markLine, markArea)', async () => {
85
+ const core = await ensureModules({
86
+ series: [
87
+ {
88
+ type: 'line',
89
+ data: [1, 2, 3],
90
+ markPoint: { data: [{ type: 'max' }] },
91
+ markLine: { data: [{ type: 'average' }] },
92
+ markArea: { data: [[{ xAxis: 'A' }, { xAxis: 'B' }]] },
93
+ },
94
+ ],
95
+ })
96
+ expect(core).toBeDefined()
97
+ })
98
+
99
+ it('loads multiple chart types in one config', async () => {
100
+ const core = await ensureModules({
101
+ series: [
102
+ { type: 'bar', data: [1, 2] },
103
+ { type: 'line', data: [3, 4] },
104
+ { type: 'scatter', data: [[1, 2]] },
105
+ ],
106
+ })
107
+ expect(core).toBeDefined()
108
+ })
109
+
110
+ it('caches modules across calls', async () => {
111
+ // First call loads BarChart
112
+ await ensureModules({ series: [{ type: 'bar', data: [1] }] })
113
+ // Second call should be instant (cached)
114
+ const start = performance.now()
115
+ await ensureModules({ series: [{ type: 'bar', data: [2] }] })
116
+ const duration = performance.now() - start
117
+ // Should be near-instant since modules are cached
118
+ expect(duration).toBeLessThan(50)
119
+ })
120
+
121
+ it('handles series as single object (not array)', async () => {
122
+ const core = await ensureModules({
123
+ series: { type: 'bar', data: [1, 2, 3] },
124
+ })
125
+ expect(core).toBeDefined()
126
+ })
127
+
128
+ it('handles empty series gracefully', async () => {
129
+ const core = await ensureModules({ series: [] })
130
+ expect(core).toBeDefined()
131
+ })
132
+
133
+ it('handles config with no series', async () => {
134
+ const core = await ensureModules({ title: { text: 'Hello' } })
135
+ expect(core).toBeDefined()
136
+ })
137
+
138
+ it('ignores unknown chart types', async () => {
139
+ const core = await ensureModules({
140
+ series: [{ type: 'nonexistent', data: [1] }],
141
+ })
142
+ expect(core).toBeDefined()
143
+ })
144
+
145
+ it('loads SVG renderer when specified', async () => {
146
+ const core = await ensureModules(
147
+ { series: [{ type: 'bar', data: [1] }] },
148
+ 'svg',
149
+ )
150
+ expect(core).toBeDefined()
151
+ })
152
+
153
+ it('resets state with _resetLoader', async () => {
154
+ await getCore() // load core
155
+ _resetLoader()
156
+ // After reset, core should be null internally but getCore still works
157
+ const core = await getCore()
158
+ expect(core).toBeDefined()
159
+ })
160
+
161
+ it('getCoreSync returns null before loading', () => {
162
+ _resetLoader()
163
+ expect(getCoreSync()).toBeNull()
164
+ })
165
+
166
+ it('getCoreSync returns core after loading', async () => {
167
+ await getCore()
168
+ expect(getCoreSync()).not.toBeNull()
169
+ expect(typeof getCoreSync()!.init).toBe('function')
170
+ })
171
+
172
+ it('manualUse registers modules when core is loaded', async () => {
173
+ await getCore() // ensure core is loaded
174
+ // Should not throw — registers module with core.use()
175
+ const { CanvasRenderer } = await import('echarts/renderers')
176
+ expect(() => manualUse(CanvasRenderer)).not.toThrow()
177
+ })
178
+
179
+ it('manualUse queues modules when core is not yet loaded', async () => {
180
+ _resetLoader()
181
+ // Core not loaded yet — should queue, not throw
182
+ const { CanvasRenderer } = await import('echarts/renderers')
183
+ expect(() => manualUse(CanvasRenderer)).not.toThrow()
184
+ })
185
+
186
+ it('loads radar component for radar config key', async () => {
187
+ const core = await ensureModules({
188
+ radar: { indicator: [{ name: 'A' }] },
189
+ series: [{ type: 'radar', data: [{ value: [1] }] }],
190
+ })
191
+ expect(core).toBeDefined()
192
+ })
193
+ })
194
+
195
+ // ─── Chart component ─────────────────────────────────────────────────────────
196
+
197
+ describe('Chart component', () => {
198
+ it('renders a div element', () => {
199
+ const container = document.createElement('div')
200
+ document.body.appendChild(container)
201
+
202
+ const unmount = mount(
203
+ <Chart
204
+ options={() => ({
205
+ series: [{ type: 'bar', data: [1, 2, 3] }],
206
+ })}
207
+ style="height: 300px"
208
+ />,
209
+ container,
210
+ )
211
+
212
+ const div = container.querySelector('div')
213
+ expect(div).not.toBeNull()
214
+
215
+ unmount()
216
+ container.remove()
217
+ })
218
+
219
+ it('applies style and class props to container', () => {
220
+ const container = document.createElement('div')
221
+ document.body.appendChild(container)
222
+
223
+ const unmount = mount(
224
+ <Chart
225
+ options={() => ({
226
+ series: [{ type: 'bar', data: [1] }],
227
+ })}
228
+ style="height: 400px; width: 100%"
229
+ class="revenue-chart"
230
+ />,
231
+ container,
232
+ )
233
+
234
+ const div = container.querySelector('div')
235
+ expect(div?.getAttribute('style')).toContain('height: 400px')
236
+ expect(div?.getAttribute('class')).toContain('revenue-chart')
237
+
238
+ unmount()
239
+ container.remove()
240
+ })
241
+ })
242
+
243
+ // ─── useChart basic API ──────────────────────────────────────────────────────
244
+
245
+ describe('useChart API', () => {
246
+ // Import useChart lazily to avoid module-level echarts import issues
247
+ it('returns the correct shape', async () => {
248
+ const { useChart } = await import('../use-chart')
249
+
250
+ const { result: chart, unmount } = mountWith(() =>
251
+ useChart(() => ({
252
+ series: [{ type: 'bar', data: [1, 2, 3] }],
253
+ })),
254
+ )
255
+
256
+ expect(typeof chart.ref).toBe('function')
257
+ expect(chart.instance()).toBeNull()
258
+ expect(chart.loading()).toBe(true)
259
+ expect(typeof chart.resize).toBe('function')
260
+
261
+ unmount()
262
+ })
263
+
264
+ it('resize does not throw when no instance', async () => {
265
+ const { useChart } = await import('../use-chart')
266
+
267
+ const { result: chart, unmount } = mountWith(() =>
268
+ useChart(() => ({
269
+ series: [{ type: 'bar', data: [1] }],
270
+ })),
271
+ )
272
+
273
+ expect(() => chart.resize()).not.toThrow()
274
+ unmount()
275
+ })
276
+
277
+ it('loading starts as true', async () => {
278
+ const { useChart } = await import('../use-chart')
279
+
280
+ const { result: chart, unmount } = mountWith(() =>
281
+ useChart(() => ({
282
+ series: [{ type: 'pie', data: [{ value: 1 }] }],
283
+ })),
284
+ )
285
+
286
+ expect(chart.loading()).toBe(true)
287
+ unmount()
288
+ })
289
+ })
290
+
291
+ // ─── All supported chart types ──────────────────────────────────────────────
292
+
293
+ describe('supported chart types', () => {
294
+ const chartTypes = [
295
+ 'bar',
296
+ 'line',
297
+ 'pie',
298
+ 'scatter',
299
+ 'radar',
300
+ 'heatmap',
301
+ 'treemap',
302
+ 'sunburst',
303
+ 'sankey',
304
+ 'funnel',
305
+ 'gauge',
306
+ 'graph',
307
+ 'tree',
308
+ 'boxplot',
309
+ 'candlestick',
310
+ 'parallel',
311
+ 'themeRiver',
312
+ 'effectScatter',
313
+ 'lines',
314
+ 'pictorialBar',
315
+ 'custom',
316
+ 'map',
317
+ ]
318
+
319
+ for (const type of chartTypes) {
320
+ it(`loads modules for type: ${type}`, async () => {
321
+ _resetLoader()
322
+ const core = await ensureModules({
323
+ series: [{ type, data: [1] }],
324
+ })
325
+ expect(core).toBeDefined()
326
+ })
327
+ }
328
+ })
329
+
330
+ // ─── All supported component keys ───────────────────────────────────────────
331
+
332
+ describe('supported component keys', () => {
333
+ const componentKeys = [
334
+ 'tooltip',
335
+ 'legend',
336
+ 'title',
337
+ 'toolbox',
338
+ 'dataZoom',
339
+ 'visualMap',
340
+ 'timeline',
341
+ 'graphic',
342
+ 'brush',
343
+ 'calendar',
344
+ 'dataset',
345
+ 'aria',
346
+ 'grid',
347
+ 'xAxis',
348
+ 'yAxis',
349
+ 'polar',
350
+ 'geo',
351
+ ]
352
+
353
+ for (const key of componentKeys) {
354
+ it(`loads component for config key: ${key}`, async () => {
355
+ _resetLoader()
356
+ const core = await ensureModules({
357
+ [key]: {},
358
+ series: [{ type: 'bar', data: [1] }],
359
+ })
360
+ expect(core).toBeDefined()
361
+ })
362
+ }
363
+ })
package/src/types.ts ADDED
@@ -0,0 +1,118 @@
1
+ import type { Props } from '@pyreon/core'
2
+ import type { Signal } from '@pyreon/reactivity'
3
+ import type { ComposeOption, EChartsOption, SetOptionOpts } from 'echarts'
4
+ import type { ECharts } from 'echarts/core'
5
+
6
+ // ─── Re-export ECharts types for consumer convenience ────────────────────────
7
+
8
+ // Re-export series option types
9
+ // Re-export component option types
10
+ export type {
11
+ BarSeriesOption,
12
+ BoxplotSeriesOption,
13
+ CandlestickSeriesOption,
14
+ DataZoomComponentOption,
15
+ FunnelSeriesOption,
16
+ GaugeSeriesOption,
17
+ GraphSeriesOption,
18
+ GridComponentOption,
19
+ HeatmapSeriesOption,
20
+ LegendComponentOption,
21
+ LineSeriesOption,
22
+ PieSeriesOption,
23
+ RadarSeriesOption,
24
+ SankeySeriesOption,
25
+ ScatterSeriesOption,
26
+ SunburstSeriesOption,
27
+ TitleComponentOption,
28
+ ToolboxComponentOption,
29
+ TooltipComponentOption,
30
+ TreemapSeriesOption,
31
+ TreeSeriesOption,
32
+ VisualMapComponentOption,
33
+ } from 'echarts'
34
+ export type { ComposeOption, ECharts, EChartsOption, SetOptionOpts }
35
+
36
+ // ─── Event types (duck-typed to avoid echarts dual-package type conflicts) ───
37
+
38
+ /** Chart event params — duck-typed to work across echarts entry points */
39
+ export interface ChartEventParams {
40
+ componentType?: string
41
+ seriesType?: string
42
+ seriesIndex?: number
43
+ seriesName?: string
44
+ name?: string
45
+ dataIndex?: number
46
+ data?: unknown
47
+ dataType?: string
48
+ value?: unknown
49
+ color?: string
50
+ event?: Event
51
+ [key: string]: unknown
52
+ }
53
+
54
+ // ─── Chart config ────────────────────────────────────────────────────────────
55
+
56
+ /**
57
+ * Configuration for useChart.
58
+ */
59
+ export interface UseChartConfig {
60
+ /** ECharts theme — 'dark', a registered theme name, or a theme object */
61
+ theme?: string | Record<string, unknown>
62
+ /** Renderer — 'canvas' (default, best performance) or 'svg' */
63
+ renderer?: 'canvas' | 'svg'
64
+ /** ECharts locale — 'EN' (default), 'ZH', etc. */
65
+ locale?: string
66
+ /** Whether to replace all options instead of merging — default: false */
67
+ notMerge?: boolean
68
+ /** Whether to batch updates — default: true */
69
+ lazyUpdate?: boolean
70
+ /** Device pixel ratio — default: window.devicePixelRatio */
71
+ devicePixelRatio?: number
72
+ /** Width override — default: container width */
73
+ width?: number
74
+ /** Height override — default: container height */
75
+ height?: number
76
+ /** Called when chart instance is created */
77
+ onInit?: (instance: ECharts) => void
78
+ }
79
+
80
+ /**
81
+ * Return type of useChart.
82
+ */
83
+ export interface UseChartResult {
84
+ /** Bind to container element via ref */
85
+ ref: (el: Element | null) => void
86
+ /** The ECharts instance — null until mounted and modules loaded */
87
+ instance: Signal<ECharts | null>
88
+ /** True while ECharts modules are being dynamically imported */
89
+ loading: Signal<boolean>
90
+ /** Error signal — set if chart init or setOption throws */
91
+ error: Signal<Error | null>
92
+ /** Manually trigger resize */
93
+ resize: () => void
94
+ }
95
+
96
+ /**
97
+ * Props for the <Chart /> component.
98
+ * Generic parameter narrows the option type for exact autocomplete.
99
+ */
100
+ export interface ChartProps<TOption extends EChartsOption = EChartsOption>
101
+ extends Props {
102
+ /** Reactive ECharts option config — fully typed */
103
+ options: () => TOption
104
+ /** ECharts theme */
105
+ theme?: string | Record<string, unknown>
106
+ /** Renderer — 'canvas' (default) or 'svg' */
107
+ renderer?: 'canvas' | 'svg'
108
+ /** CSS style for the container div */
109
+ style?: string
110
+ /** CSS class for the container div */
111
+ class?: string
112
+ /** Click event handler */
113
+ onClick?: (params: ChartEventParams) => void
114
+ /** Mouseover event handler */
115
+ onMouseover?: (params: ChartEventParams) => void
116
+ /** Mouseout event handler */
117
+ onMouseout?: (params: ChartEventParams) => void
118
+ }
@@ -0,0 +1,136 @@
1
+ import { onUnmount } from '@pyreon/core'
2
+ import { effect, signal } from '@pyreon/reactivity'
3
+ import type { EChartsOption } from 'echarts'
4
+ import { ensureModules } from './loader'
5
+ import type { UseChartConfig, UseChartResult } from './types'
6
+
7
+ /**
8
+ * Reactive ECharts hook. Creates a chart instance bound to a container
9
+ * element, with automatic module lazy-loading, signal tracking, resize
10
+ * handling, error capture, and cleanup.
11
+ *
12
+ * Generic parameter `TOption` narrows the option type for exact autocomplete.
13
+ * Use `ComposeOption<SeriesUnion>` from ECharts to restrict to specific chart types.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * // Default — accepts any ECharts option
18
+ * const chart = useChart(() => ({
19
+ * series: [{ type: 'bar', data: revenue() }],
20
+ * }))
21
+ *
22
+ * // Strict — only bar + line allowed, full autocomplete
23
+ * import type { ComposeOption, BarSeriesOption, LineSeriesOption } from '@pyreon/charts'
24
+ * type MyChartOption = ComposeOption<BarSeriesOption | LineSeriesOption>
25
+ *
26
+ * const chart = useChart<MyChartOption>(() => ({
27
+ * series: [{ type: 'bar', data: revenue() }], // ✓
28
+ * }))
29
+ * ```
30
+ */
31
+ export function useChart<TOption extends EChartsOption = EChartsOption>(
32
+ optionsFn: () => TOption,
33
+ config?: UseChartConfig,
34
+ ): UseChartResult {
35
+ const instance = signal<import('echarts/core').ECharts | null>(null)
36
+ const loading = signal(true)
37
+ const error = signal<Error | null>(null)
38
+ const container = signal<HTMLElement | null>(null)
39
+ const renderer = config?.renderer ?? 'canvas'
40
+
41
+ let observer: ResizeObserver | null = null
42
+ let initialized = false
43
+
44
+ // Initialize chart when container is bound
45
+ effect(() => {
46
+ const el = container()
47
+ if (!el || initialized) return
48
+
49
+ initialized = true
50
+
51
+ let opts: EChartsOption
52
+ try {
53
+ opts = optionsFn()
54
+ } catch (err) {
55
+ error.set(err instanceof Error ? err : new Error(String(err)))
56
+ loading.set(false)
57
+ return
58
+ }
59
+
60
+ // Load required ECharts modules, then create chart
61
+ ensureModules(opts as Record<string, unknown>, renderer)
62
+ .then((core) => {
63
+ // Guard: component may have unmounted during async load
64
+ if (!container.peek()) return
65
+
66
+ try {
67
+ const chart = core.init(el, config?.theme as any, {
68
+ renderer,
69
+ locale: config?.locale,
70
+ devicePixelRatio: config?.devicePixelRatio,
71
+ width: config?.width,
72
+ height: config?.height,
73
+ })
74
+
75
+ chart.setOption(opts)
76
+ instance.set(chart)
77
+ loading.set(false)
78
+ error.set(null)
79
+
80
+ config?.onInit?.(chart)
81
+
82
+ // ResizeObserver for auto-resize
83
+ observer = new ResizeObserver(() => {
84
+ chart.resize()
85
+ })
86
+ observer.observe(el)
87
+ } catch (err) {
88
+ error.set(err instanceof Error ? err : new Error(String(err)))
89
+ loading.set(false)
90
+ }
91
+ })
92
+ .catch((err) => {
93
+ error.set(err instanceof Error ? err : new Error(String(err)))
94
+ loading.set(false)
95
+ })
96
+ })
97
+
98
+ // Reactive updates — re-run when signals in optionsFn change
99
+ effect(() => {
100
+ const chart = instance()
101
+ if (!chart) return
102
+
103
+ try {
104
+ const opts = optionsFn()
105
+ chart.setOption(opts, {
106
+ notMerge: config?.notMerge ?? false,
107
+ lazyUpdate: config?.lazyUpdate ?? true,
108
+ })
109
+ error.set(null)
110
+ } catch (err) {
111
+ error.set(err instanceof Error ? err : new Error(String(err)))
112
+ }
113
+ })
114
+
115
+ // Cleanup on unmount
116
+ onUnmount(() => {
117
+ observer?.disconnect()
118
+ observer = null
119
+
120
+ const chart = instance.peek()
121
+ if (chart) {
122
+ chart.dispose()
123
+ instance.set(null)
124
+ }
125
+
126
+ initialized = false
127
+ })
128
+
129
+ return {
130
+ ref: (el: Element | null) => container.set(el as HTMLElement | null),
131
+ instance,
132
+ loading,
133
+ error,
134
+ resize: () => instance.peek()?.resize(),
135
+ }
136
+ }