@chartbuddy.io/embed 1.7.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +56 -0
- package/README.md +391 -0
- package/chart-schema.d.ts +91 -0
- package/chart-schema.json +1144 -0
- package/chartbuddy-embed.api.mjs +64 -0
- package/chartbuddy-embed.d.ts +488 -0
- package/chartbuddy-embed.global.js +135 -0
- package/chartbuddy-embed.mjs +135 -0
- package/chartbuddy-embed.single.global.js +4201 -0
- package/chartbuddy-embed.single.mjs +4201 -0
- package/element.d.ts +78 -0
- package/element.mjs +233 -0
- package/js/core/chart/labelPlacementWorker.js +2 -0
- package/labelPlacementAccel-QHVANOZO.wasm +0 -0
- package/llms.txt +341 -0
- package/package.json +101 -0
- package/react.d.ts +97 -0
- package/react.mjs +219 -0
- package/ts/shared/libraries/DOMPurify.min.js +2 -0
- package/ts/shared/libraries/d3.min.js +2 -0
- package/vue.d.ts +108 -0
- package/vue.mjs +253 -0
- package/webapp-entry.css +2 -0
- package/webapp-entry.js +4063 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @chartbuddy.io/embed — ChartBuddy Insights (NOT Chart.js / Recharts).
|
|
3
|
+
* This file is the readable package-root stub (unpkg / exports["."]).
|
|
4
|
+
* Default is view-only (hover ChartBuddy ball: Download / Drag to slide /
|
|
5
|
+
* Export / Edit). Pass editable: true for the full editor. Ball → Done exits.
|
|
6
|
+
*
|
|
7
|
+
* Exports:
|
|
8
|
+
* new Insight(target, options?) → Insight
|
|
9
|
+
* validateChartData(chartData, options?) → { valid, issues, errors, warnings }
|
|
10
|
+
* assertValidChartData / formatValidationIssues / ChartDataValidationError
|
|
11
|
+
* getInsights() / snapshotInsights({ png? })
|
|
12
|
+
* clearPersistedChart(instanceId?)
|
|
13
|
+
* version: string
|
|
14
|
+
* Agent hook: window.__CHARTBUDDY_INSIGHTS__ (keyed by instanceId)
|
|
15
|
+
*
|
|
16
|
+
* Minimal example (view mode, data-in, no account / chart ID):
|
|
17
|
+
* import { Insight } from 'https://unpkg.com/@chartbuddy.io/embed';
|
|
18
|
+
* const insight = new Insight('#chart', {
|
|
19
|
+
* instanceId: 'revenue',
|
|
20
|
+
* chartData: {
|
|
21
|
+
* chartType: 'clusteredBar',
|
|
22
|
+
* isDataTransposed: true,
|
|
23
|
+
* seriesData: [['','Q1','Q2'],['Revenue',100,112],['Costs',60,66]],
|
|
24
|
+
* },
|
|
25
|
+
* });
|
|
26
|
+
* await insight.ready;
|
|
27
|
+
* // Agent observe: await insight.toPngBase64() / insight.getChartData()
|
|
28
|
+
* // Full editor: new Insight('#chart', { editable: true, chartData: … })
|
|
29
|
+
* // Leave edit: insight.exitEditMode() or ball → Done
|
|
30
|
+
*
|
|
31
|
+
* Check before you mount (agent generate → check → repair loop):
|
|
32
|
+
* const { valid, errors } = validateChartData(candidate);
|
|
33
|
+
* // errors[i] = { path, code, message, expected?, received?, allowed?, suggestion? }
|
|
34
|
+
* // codes: unknown-chart-type | wrong-type | out-of-range | not-in-enum |
|
|
35
|
+
* // series-data-shape | ragged-series-data | foreign-option-bag |
|
|
36
|
+
* // empty-patch | not-an-object (branch on code, never on message)
|
|
37
|
+
*
|
|
38
|
+
* Framework bindings (each ships its own types):
|
|
39
|
+
* React 18/19 : import { InsightChart, useInsight } from '@chartbuddy.io/embed/react'
|
|
40
|
+
* Vue 3 : import { InsightChart, useInsight } from '@chartbuddy.io/embed/vue'
|
|
41
|
+
* Angular etc : import '@chartbuddy.io/embed/element' → <chartbuddy-insight>
|
|
42
|
+
*
|
|
43
|
+
* Docs (fetch next if needed):
|
|
44
|
+
* https://unpkg.com/@chartbuddy.io/embed/llms.txt
|
|
45
|
+
* https://cb-acc.xyz/llms.txt
|
|
46
|
+
* https://cb-acc.xyz/embed/api
|
|
47
|
+
* https://unpkg.com/@chartbuddy.io/embed/README.md
|
|
48
|
+
*
|
|
49
|
+
* Implementation: re-exports the self-contained single-file build (no assetBase).
|
|
50
|
+
*/
|
|
51
|
+
export {
|
|
52
|
+
Insight,
|
|
53
|
+
clearPersistedChart,
|
|
54
|
+
getInsights,
|
|
55
|
+
snapshotInsights,
|
|
56
|
+
CHARTBUDDY_INSIGHTS_GLOBAL,
|
|
57
|
+
version,
|
|
58
|
+
validateChartData,
|
|
59
|
+
assertValidChartData,
|
|
60
|
+
formatValidationIssues,
|
|
61
|
+
ChartDataValidationError,
|
|
62
|
+
} from './chartbuddy-embed.single.mjs';
|
|
63
|
+
|
|
64
|
+
export { default } from './chartbuddy-embed.single.mjs';
|
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @chartbuddy.io/embed — type declarations.
|
|
3
|
+
*
|
|
4
|
+
* ChartBuddy creates **Insights**. Default is view-only (headless draw +
|
|
5
|
+
* ChartBuddy hover ball). Pass `editable: true` for the full interactive
|
|
6
|
+
* editor. In edit mode, ball → **Done** (or `exitEditMode()`) returns to view.
|
|
7
|
+
* Spreadsheet is not included in this package.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Chart type unions, generated from the ChartBuddy chart schema registry.
|
|
12
|
+
* Do not restate the chart type list here — edit the registry and regenerate.
|
|
13
|
+
*/
|
|
14
|
+
export type {
|
|
15
|
+
ChartType,
|
|
16
|
+
ChartTypeAlias,
|
|
17
|
+
ChartTypeInput,
|
|
18
|
+
ChartTypeOptionBag,
|
|
19
|
+
ChartTypeSeriesLayout,
|
|
20
|
+
} from './chart-schema.js';
|
|
21
|
+
|
|
22
|
+
import type { ChartType, ChartTypeInput } from './chart-schema.js';
|
|
23
|
+
|
|
24
|
+
/** A single spreadsheet cell. `null` marks an intentionally empty cell. */
|
|
25
|
+
export type ChartCell = string | number | boolean | null;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The raw 2D data grid. The required layout depends on `chartType` — see
|
|
29
|
+
* `ChartTypeSeriesLayout` and the `seriesData` section of llms.txt.
|
|
30
|
+
*/
|
|
31
|
+
export type SeriesData = ChartCell[][];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Fields common to every chart type.
|
|
35
|
+
*
|
|
36
|
+
* Stays open (`[key: string]: unknown`) because a config may legitimately carry
|
|
37
|
+
* keys a given build does not know about; ChartBuddy migrates shapes on load.
|
|
38
|
+
*/
|
|
39
|
+
export interface ChartDataCommon {
|
|
40
|
+
id?: string;
|
|
41
|
+
/** App version this config was last migrated to. */
|
|
42
|
+
version?: string;
|
|
43
|
+
title?: TextElement;
|
|
44
|
+
subtitle?: TextElement;
|
|
45
|
+
footnote?: TextElement;
|
|
46
|
+
/** When true (default), `seriesData` rows are series. */
|
|
47
|
+
isDataTransposed?: boolean;
|
|
48
|
+
canvas?: { width: number; height: number };
|
|
49
|
+
orientation?: 'vertical' | 'horizontal';
|
|
50
|
+
axes?: Record<string, Record<string, unknown>>;
|
|
51
|
+
annotations?: Record<string, unknown>;
|
|
52
|
+
legend?: {
|
|
53
|
+
visible?: boolean;
|
|
54
|
+
/** The chart's color palette. */
|
|
55
|
+
colors?: string[];
|
|
56
|
+
position?: string;
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
};
|
|
59
|
+
backgroundColor?: string;
|
|
60
|
+
seriesLabels?: Record<string, unknown>;
|
|
61
|
+
multilines?: unknown[];
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Title / subtitle / footnote / axis title. `text` accepts inline HTML. */
|
|
66
|
+
export interface TextElement {
|
|
67
|
+
id?: string;
|
|
68
|
+
visible?: boolean;
|
|
69
|
+
text?: string;
|
|
70
|
+
fontFamily?: string;
|
|
71
|
+
fontSize?: number;
|
|
72
|
+
fontColor?: string;
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Chart data you PASS IN (`new Insight()` / `setChartData()`).
|
|
78
|
+
*
|
|
79
|
+
* Partial configs are merged over ChartBuddy's defaults, so only the fields you
|
|
80
|
+
* care about are required. Aliases (`donut`, `bubble`) are accepted and
|
|
81
|
+
* normalized. An unknown `chartType` is a type error here and throws at runtime.
|
|
82
|
+
*/
|
|
83
|
+
export interface ChartDataInput extends ChartDataCommon {
|
|
84
|
+
chartType?: ChartTypeInput;
|
|
85
|
+
seriesData?: SeriesData;
|
|
86
|
+
/** Bar options (`clusteredBar`, `stackedBar`, `stackedBar100`). */
|
|
87
|
+
bar?: Record<string, unknown>;
|
|
88
|
+
line?: Record<string, unknown>;
|
|
89
|
+
/** Shared by `area` and `area100`. */
|
|
90
|
+
area?: Record<string, unknown>;
|
|
91
|
+
/** Shared by `scatter` and the `bubble` alias. */
|
|
92
|
+
scatter?: Record<string, unknown>;
|
|
93
|
+
/** Shared by `pie` and the `donut` alias (`innerRadiusRatio`). */
|
|
94
|
+
pie?: Record<string, unknown>;
|
|
95
|
+
waterfall?: Record<string, unknown>;
|
|
96
|
+
mekko?: Record<string, unknown>;
|
|
97
|
+
/** Bar Mekko options, e.g. `{ sort: 'heightDesc' }`. */
|
|
98
|
+
barMekko?: Record<string, unknown>;
|
|
99
|
+
combo?: Record<string, unknown>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A resolved chart config — what `getChartData()` returns.
|
|
104
|
+
*
|
|
105
|
+
* `chartType` is always canonical (aliases already normalized) and `seriesData`
|
|
106
|
+
* is always present. Safe to round-trip straight back into `setChartData()`.
|
|
107
|
+
*/
|
|
108
|
+
export interface ChartData extends ChartDataInput {
|
|
109
|
+
chartType: ChartType;
|
|
110
|
+
seriesData: SeriesData;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type EmbedMode = 'view' | 'edit';
|
|
114
|
+
|
|
115
|
+
/** Events an Insight can emit. Handlers are typed per event. */
|
|
116
|
+
export type InsightEventMap = {
|
|
117
|
+
/** Fired once when the insight finishes booting (view or edit). */
|
|
118
|
+
ready: [];
|
|
119
|
+
/** Fired whenever the insight switches between view and edit. */
|
|
120
|
+
mode: [EmbedMode];
|
|
121
|
+
/**
|
|
122
|
+
* Fired after a meaningful config change — programmatic `setChartData` /
|
|
123
|
+
* `setData` / `update`, live edits in edit mode, or Done.
|
|
124
|
+
*/
|
|
125
|
+
change: [ChartData | null];
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export type InsightEvent = keyof InsightEventMap;
|
|
129
|
+
export type InsightEventHandler<E extends InsightEvent> = (...args: InsightEventMap[E]) => void;
|
|
130
|
+
|
|
131
|
+
/** Options for PNG export helpers (`toPngBlob` / `toPngBase64` / `downloadPng`). */
|
|
132
|
+
export interface PngOptions {
|
|
133
|
+
/**
|
|
134
|
+
* Pixel scale multiplier (same as the download pipeline). Default 4.
|
|
135
|
+
*/
|
|
136
|
+
scale?: number;
|
|
137
|
+
/**
|
|
138
|
+
* CSS color baked under the chart in the PNG (e.g. `#ffffff`).
|
|
139
|
+
* Export strips the live SVG background for Slides-friendly transparency.
|
|
140
|
+
* - `toPngBlob` / `toPngBase64` default: `#ffffff`
|
|
141
|
+
* - `downloadPng` default: transparent
|
|
142
|
+
* - Pass `null` or `'transparent'` for a transparent PNG
|
|
143
|
+
*/
|
|
144
|
+
background?: string | null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface InsightOptions {
|
|
148
|
+
/**
|
|
149
|
+
* Chart data to open with. A partial config is merged over ChartBuddy's
|
|
150
|
+
* defaults; a full config (e.g. the JSON from "Export Config") is used as-is.
|
|
151
|
+
* Omit to open the default starter chart.
|
|
152
|
+
*/
|
|
153
|
+
chartData?: ChartDataInput;
|
|
154
|
+
/**
|
|
155
|
+
* Where to fetch the editor engine/assets from (multi-file loader only).
|
|
156
|
+
* Defaults to the directory this loader was served from. Ignored by the
|
|
157
|
+
* single-file build (`chartbuddy-embed.single.mjs` / `@chartbuddy.io/embed/single`).
|
|
158
|
+
* Must end with `/`.
|
|
159
|
+
*/
|
|
160
|
+
assetBase?: string;
|
|
161
|
+
/**
|
|
162
|
+
* When true, open the full interactive editor. When false (default), open
|
|
163
|
+
* view-only with the ChartBuddy hover ball (Download / Export / Edit).
|
|
164
|
+
*/
|
|
165
|
+
editable?: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Show the built-in Reset / Import / Export strip. Only applies when
|
|
168
|
+
* `editable: true`. Default false.
|
|
169
|
+
*/
|
|
170
|
+
toolbar?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Persist this insight's config under a unique per-instance localStorage key.
|
|
173
|
+
* Default false. With a stable `instanceId`, edits survive reload
|
|
174
|
+
* (checkpointed on Done / `exitEditMode`).
|
|
175
|
+
*/
|
|
176
|
+
persist?: boolean;
|
|
177
|
+
/**
|
|
178
|
+
* Stable, developer-controlled id for this mount. Used for localStorage keys,
|
|
179
|
+
* `data-cb-instance`, and `getInsights()` / `window.__CHARTBUDDY_INSIGHTS__`.
|
|
180
|
+
* When omitted, a random UUID is generated (breaks persist across reloads).
|
|
181
|
+
* Allowed chars: letters, digits, `_`, `.`, `:`, `-`.
|
|
182
|
+
*/
|
|
183
|
+
instanceId?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Customize where/how the editor's chrome mounts — e.g. keep the
|
|
186
|
+
* formatting toolbar inside your own widget instead of floating over the
|
|
187
|
+
* whole viewport. See {@link EmbedHostOverrides}.
|
|
188
|
+
*/
|
|
189
|
+
host?: EmbedHostOverrides;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Optional host hooks for customizing editor chrome placement/behavior.
|
|
194
|
+
* All fields are optional — anything you don't override keeps the built-in
|
|
195
|
+
* default (a full-viewport overlay for the formatting toolbar, default
|
|
196
|
+
* positioning, and a no-op for background drags).
|
|
197
|
+
*/
|
|
198
|
+
export interface EmbedHostOverrides {
|
|
199
|
+
/**
|
|
200
|
+
* Where to mount the formatting toolbar that appears when a chart element
|
|
201
|
+
* is selected. Return a CSS selector or an `Element`. Defaults to a
|
|
202
|
+
* per-instance full-viewport overlay.
|
|
203
|
+
*/
|
|
204
|
+
getToolbarContainer?: () => string | Element | null;
|
|
205
|
+
/**
|
|
206
|
+
* Override the default toolbar positioning logic (called after the
|
|
207
|
+
* toolbar is appended into the container from `getToolbarContainer`).
|
|
208
|
+
* @param toolbarNode The rendered toolbar DOM element.
|
|
209
|
+
* @param targetNode The chart element that was selected (if any).
|
|
210
|
+
*/
|
|
211
|
+
positionToolbar?: (toolbarNode: HTMLElement, targetNode: HTMLElement | null) => void;
|
|
212
|
+
/**
|
|
213
|
+
* Called when the user starts dragging on non-interactive chart
|
|
214
|
+
* background. Use this to let the host move/drag its own outer widget
|
|
215
|
+
* chrome instead (the engine will not move anything itself).
|
|
216
|
+
*/
|
|
217
|
+
startDragging?: (event: MouseEvent) => void;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* A ChartBuddy Insight — view-only chart or full editor in a host element.
|
|
222
|
+
*
|
|
223
|
+
* Default is view-only. Pass `editable: true` for the full editor.
|
|
224
|
+
* In edit mode, the hover ball offers **Done** to return to view.
|
|
225
|
+
*
|
|
226
|
+
* Safe to construct multiple times in one document. For Claude / strict CSP,
|
|
227
|
+
* import from `chartbuddy-embed.single.mjs` (or `@chartbuddy.io/embed/single`)
|
|
228
|
+
* so the engine does not fetch sibling scripts.
|
|
229
|
+
*/
|
|
230
|
+
export declare class Insight {
|
|
231
|
+
constructor(target: string | HTMLElement, options?: InsightOptions);
|
|
232
|
+
|
|
233
|
+
/** The container element the insight was mounted into. */
|
|
234
|
+
readonly container: HTMLElement;
|
|
235
|
+
/** The asset base the engine was loaded from. */
|
|
236
|
+
readonly assetBase: string;
|
|
237
|
+
/** Unique id for this instance (stable when `options.instanceId` is set). */
|
|
238
|
+
readonly instanceId: string;
|
|
239
|
+
/** Id of the chart container element for this instance. */
|
|
240
|
+
readonly chartContainerId: string;
|
|
241
|
+
/** Current mode (`view` by default, `edit` after Edit or `editable: true`). */
|
|
242
|
+
readonly mode: EmbedMode;
|
|
243
|
+
/** Promise that resolves when the insight has finished booting (or rejected). */
|
|
244
|
+
readonly ready: Promise<void>;
|
|
245
|
+
/**
|
|
246
|
+
* Live ChartBuddy engine instance (`any` — internals are unstable). Prefer
|
|
247
|
+
* `getChartData` / `setChartData` / export helpers instead of touching this.
|
|
248
|
+
*/
|
|
249
|
+
readonly chart: any | null;
|
|
250
|
+
|
|
251
|
+
/** Claim keyboard / interaction focus for this chart (edit mode). */
|
|
252
|
+
focus(): void;
|
|
253
|
+
/**
|
|
254
|
+
* Update the live chart with a full or partial config.
|
|
255
|
+
*
|
|
256
|
+
* Passing only `seriesData` refreshes the data while keeping the current chart
|
|
257
|
+
* type and formatting. Nested `axes` / `annotations` patches are deep-merged.
|
|
258
|
+
* `chartType` is optional — omit it to keep the current type.
|
|
259
|
+
*/
|
|
260
|
+
setChartData(chartData: ChartDataInput): void;
|
|
261
|
+
/**
|
|
262
|
+
* Refresh only the data grid. Keeps chart type and formatting.
|
|
263
|
+
* Chart.js equivalent of assigning `chart.data` then calling `update()`.
|
|
264
|
+
*/
|
|
265
|
+
setData(seriesData: SeriesData): void;
|
|
266
|
+
/**
|
|
267
|
+
* Apply a partial patch and redraw. With no argument, redraws without
|
|
268
|
+
* changing config (Chart.js `chart.update()`).
|
|
269
|
+
*/
|
|
270
|
+
update(patch?: ChartDataInput): void;
|
|
271
|
+
/** Snapshot of the current chart config (`cd`). */
|
|
272
|
+
getChartData(): ChartData | null;
|
|
273
|
+
/**
|
|
274
|
+
* Subscribe to a lifecycle event. Returns an unsubscribe function.
|
|
275
|
+
* Events: `ready`, `mode` (view ↔ edit), `change` (after meaningful edits).
|
|
276
|
+
*/
|
|
277
|
+
on<E extends InsightEvent>(event: E, handler: InsightEventHandler<E>): () => void;
|
|
278
|
+
/** Remove a previously registered handler. */
|
|
279
|
+
off<E extends InsightEvent>(event: E, handler: InsightEventHandler<E>): void;
|
|
280
|
+
/** True when the chart has changed since boot / last Done checkpoint. */
|
|
281
|
+
isDirty(): boolean;
|
|
282
|
+
/** Monotonic edit counter — increments on every meaningful change. */
|
|
283
|
+
getRevision(): number;
|
|
284
|
+
/**
|
|
285
|
+
* PNG bytes as a Blob (no browser download). Prefer this or `toPngBase64`
|
|
286
|
+
* for agent / CDP loops — `downloadPng` only triggers a Save dialog.
|
|
287
|
+
*/
|
|
288
|
+
toPngBlob(options?: PngOptions): Promise<Blob>;
|
|
289
|
+
/**
|
|
290
|
+
* PNG as raw base64 (no `data:` prefix). For agent observation / writing files.
|
|
291
|
+
*/
|
|
292
|
+
toPngBase64(options?: PngOptions): Promise<string>;
|
|
293
|
+
/** Download a PNG of the current chart (human Save dialog). */
|
|
294
|
+
downloadPng(options?: PngOptions): Promise<void>;
|
|
295
|
+
/** Open the drag-to-export widget (multi-scale PNG you can drag into slides etc.). */
|
|
296
|
+
dragExport(): Promise<void>;
|
|
297
|
+
/** Download the current chart config as JSON. */
|
|
298
|
+
exportConfig(): void;
|
|
299
|
+
/** Switch from view mode to the full interactive editor (no-op if already editing). */
|
|
300
|
+
enterEditMode(): Promise<void>;
|
|
301
|
+
/**
|
|
302
|
+
* Leave edit mode and return to view-only (no-op if already in view).
|
|
303
|
+
* When `persist: true`, checkpoints `chartData` to localStorage first.
|
|
304
|
+
*/
|
|
305
|
+
exitEditMode(): Promise<void>;
|
|
306
|
+
/** Tear down listeners, persistence, overlay, and DOM shell. */
|
|
307
|
+
destroy(): void;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Clear persisted insight chart config.
|
|
312
|
+
* @param instanceId When set, clears that embed instance's keys only.
|
|
313
|
+
* When omitted, clears the legacy shared webapp key.
|
|
314
|
+
*/
|
|
315
|
+
export function clearPersistedChart(instanceId?: string): void;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Live Insights on this page, keyed by `instanceId`.
|
|
319
|
+
* Also mirrored at `window.__CHARTBUDDY_INSIGHTS__` for agent CDP hooks.
|
|
320
|
+
*/
|
|
321
|
+
export function getInsights(): Record<string, Insight>;
|
|
322
|
+
|
|
323
|
+
export interface InsightSnapshotEntry {
|
|
324
|
+
chartData: ChartData | null;
|
|
325
|
+
/** Present only when `png: true`. */
|
|
326
|
+
pngBase64?: string;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export interface InsightsSnapshot {
|
|
330
|
+
schemaVersion: 1;
|
|
331
|
+
version: string;
|
|
332
|
+
charts: Record<string, InsightSnapshotEntry>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Agent-oriented snapshot of every registered Insight.
|
|
337
|
+
* Config-only by default (`png` is opt-in — multi-chart PNG payloads are large).
|
|
338
|
+
*/
|
|
339
|
+
export function snapshotInsights(options?: {
|
|
340
|
+
png?: boolean;
|
|
341
|
+
scale?: number;
|
|
342
|
+
/** Passed through to `toPngBase64` when `png: true`. Default `#ffffff`. */
|
|
343
|
+
background?: string | null;
|
|
344
|
+
}): Promise<InsightsSnapshot>;
|
|
345
|
+
|
|
346
|
+
/** Documented agent hook name (`window.__CHARTBUDDY_INSIGHTS__`). */
|
|
347
|
+
export const CHARTBUDDY_INSIGHTS_GLOBAL: '__CHARTBUDDY_INSIGHTS__';
|
|
348
|
+
|
|
349
|
+
/* ------------------------------------------------------------------ *
|
|
350
|
+
* Validation
|
|
351
|
+
*
|
|
352
|
+
* `new Insight()`, `setChartData()`, `setData()`, and `update()` all validate
|
|
353
|
+
* their input and throw `ChartDataValidationError` on an error-severity problem.
|
|
354
|
+
* The same checks are exported so you can validate a candidate config first —
|
|
355
|
+
* useful when an LLM authored it and you want a generate → check → repair loop
|
|
356
|
+
* without mounting anything.
|
|
357
|
+
* ------------------------------------------------------------------ */
|
|
358
|
+
|
|
359
|
+
/** Stable, machine-readable classification of a validation problem. */
|
|
360
|
+
export type ValidationIssueCode =
|
|
361
|
+
/** The value is not a chart-data object at all. */
|
|
362
|
+
| 'not-an-object'
|
|
363
|
+
/** `chartType` is not a known type or alias. `allowed` lists every legal value. */
|
|
364
|
+
| 'unknown-chart-type'
|
|
365
|
+
/** Neither `chartType` nor `seriesData` was supplied. */
|
|
366
|
+
| 'empty-patch'
|
|
367
|
+
/** A known field holds the wrong JavaScript type. */
|
|
368
|
+
| 'wrong-type'
|
|
369
|
+
/** A numeric field is outside its documented range. */
|
|
370
|
+
| 'out-of-range'
|
|
371
|
+
/** A string field is outside its documented set of values. */
|
|
372
|
+
| 'not-in-enum'
|
|
373
|
+
/** `seriesData` is not a usable 2D grid for this chart type. */
|
|
374
|
+
| 'series-data-shape'
|
|
375
|
+
/** `seriesData` rows have unequal lengths. Warning — the renderer pads. */
|
|
376
|
+
| 'ragged-series-data'
|
|
377
|
+
/** An option bag belongs to a different chart type. */
|
|
378
|
+
| 'foreign-option-bag';
|
|
379
|
+
|
|
380
|
+
/** Errors reject at the API boundary; warnings are logged and the call proceeds. */
|
|
381
|
+
export type ValidationSeverity = 'error' | 'warning';
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* One problem found in a chart-data object.
|
|
385
|
+
*
|
|
386
|
+
* `code` and `path` are the stable part of this contract — branch on `code`,
|
|
387
|
+
* repair the value at `path`. `message` is for humans and may be reworded in
|
|
388
|
+
* any release, so do not parse it.
|
|
389
|
+
*/
|
|
390
|
+
export interface ValidationIssue {
|
|
391
|
+
/** Dotted/bracketed path to the offending value, e.g. `pie.innerRadiusRatio`. */
|
|
392
|
+
readonly path: string;
|
|
393
|
+
readonly code: ValidationIssueCode;
|
|
394
|
+
readonly message: string;
|
|
395
|
+
readonly severity: ValidationSeverity;
|
|
396
|
+
/** What the schema wanted, e.g. `'number'`, `'integer'`, `'>= 0'`, `'2D array'`. */
|
|
397
|
+
readonly expected?: string;
|
|
398
|
+
/** What arrived, as a type name or short literal, e.g. `'string'`, `'1.5'`. */
|
|
399
|
+
readonly received?: string;
|
|
400
|
+
/** For `not-in-enum` / `unknown-chart-type`: the full set of legal values. */
|
|
401
|
+
readonly allowed?: readonly string[];
|
|
402
|
+
/** Nearest legal value, when one is close enough to be a likely typo fix. */
|
|
403
|
+
readonly suggestion?: string;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export interface ValidationResult {
|
|
407
|
+
/** True when there are no `error`-severity issues. Warnings do not invalidate. */
|
|
408
|
+
readonly valid: boolean;
|
|
409
|
+
/** Every issue found, errors and warnings together, in document order. */
|
|
410
|
+
readonly issues: readonly ValidationIssue[];
|
|
411
|
+
/** The `error`-severity subset — what makes `valid` false. */
|
|
412
|
+
readonly errors: readonly ValidationIssue[];
|
|
413
|
+
/** The `warning`-severity subset — rendered anyway, but probably a bug. */
|
|
414
|
+
readonly warnings: readonly ValidationIssue[];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export interface ValidateChartDataOptions {
|
|
418
|
+
/**
|
|
419
|
+
* Which form the input is in.
|
|
420
|
+
* - `patch` — a hand-authored partial config; a foreign option bag is an issue.
|
|
421
|
+
* - `resolved` — a full snapshot (e.g. from `getChartData()`); every bag expected.
|
|
422
|
+
* - `auto` — infer from whether every option bag is present (default).
|
|
423
|
+
*/
|
|
424
|
+
readonly form?: 'patch' | 'resolved' | 'auto';
|
|
425
|
+
/**
|
|
426
|
+
* Require at least one of `chartType` / `seriesData`. Default true.
|
|
427
|
+
* Turn off when validating a styling-only patch.
|
|
428
|
+
*/
|
|
429
|
+
readonly requireSomething?: boolean;
|
|
430
|
+
/** Stop after this many issues, so messages stay readable. Default 20. */
|
|
431
|
+
readonly maxIssues?: number;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Check a chart-data object against the schema. Never throws.
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* const { valid, errors } = validateChartData(candidate);
|
|
439
|
+
* if (!valid) return repair(errors); // branch on error.code, fix error.path
|
|
440
|
+
* new Insight('#chart', { chartData: candidate });
|
|
441
|
+
*/
|
|
442
|
+
export function validateChartData(
|
|
443
|
+
chartData: unknown,
|
|
444
|
+
options?: ValidateChartDataOptions,
|
|
445
|
+
): ValidationResult;
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Thrown by `new Insight()`, `setChartData()`, `setData()`, and `update()` when
|
|
449
|
+
* the input has error-severity problems. Carries the structured issues.
|
|
450
|
+
*/
|
|
451
|
+
export class ChartDataValidationError extends Error {
|
|
452
|
+
readonly name: 'ChartDataValidationError';
|
|
453
|
+
/** Error-severity issues only — the reasons this threw. */
|
|
454
|
+
readonly errors: readonly ValidationIssue[];
|
|
455
|
+
/** Warnings found in the same pass. Already logged; did not cause the throw. */
|
|
456
|
+
readonly warnings: readonly ValidationIssue[];
|
|
457
|
+
/** Errors and warnings together. */
|
|
458
|
+
readonly issues: readonly ValidationIssue[];
|
|
459
|
+
toJSON(): { name: string; message: string; issues: readonly ValidationIssue[] };
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Validate and throw `ChartDataValidationError` on any error-severity issue.
|
|
464
|
+
* Warnings are logged to the console instead. This is what the Insight API calls.
|
|
465
|
+
*/
|
|
466
|
+
export function assertValidChartData(
|
|
467
|
+
chartData: unknown,
|
|
468
|
+
context?: string,
|
|
469
|
+
options?: ValidateChartDataOptions,
|
|
470
|
+
): void;
|
|
471
|
+
|
|
472
|
+
/** Render issues as one human-readable multi-line message. */
|
|
473
|
+
export function formatValidationIssues(
|
|
474
|
+
issues: readonly ValidationIssue[],
|
|
475
|
+
context?: string,
|
|
476
|
+
): string;
|
|
477
|
+
|
|
478
|
+
/** The ChartBuddy engine version this package ships. */
|
|
479
|
+
export const version: string;
|
|
480
|
+
|
|
481
|
+
declare const _default: {
|
|
482
|
+
Insight: typeof Insight;
|
|
483
|
+
clearPersistedChart: typeof clearPersistedChart;
|
|
484
|
+
getInsights: typeof getInsights;
|
|
485
|
+
snapshotInsights: typeof snapshotInsights;
|
|
486
|
+
validateChartData: typeof validateChartData;
|
|
487
|
+
};
|
|
488
|
+
export default _default;
|