@artooi/ag-ui-web-component 0.26.0 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -1
- package/README.md +24 -4
- package/dist/ag-ui-web-component.bundle.js +21 -21
- package/dist/ag-ui-web-component.bundle.js.map +3 -3
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/index.js +36 -22
- package/dist/index.js.map +2 -2
- package/dist/tools/client_tool_registry.d.ts +10 -1
- package/dist/tools/client_tool_registry.d.ts.map +1 -1
- package/dist/ui/chart_block.d.ts.map +1 -1
- package/dist/ui/chart_spec_from.d.ts.map +1 -1
- package/dist/ui/chart_tool.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/ag_ui_chat.ts +34 -14
- package/src/tools/client_tool_registry.ts +11 -1
- package/src/ui/chart_block.ts +6 -1
- package/src/ui/chart_spec_from.ts +21 -2
- package/src/ui/chart_tool.ts +13 -5
- package/src/version.ts +1 -1
|
@@ -6,6 +6,15 @@ import type { Tool } from "@ag-ui/core";
|
|
|
6
6
|
* `handler` receives the parsed arguments and returns a result that is
|
|
7
7
|
* JSON-serialised into the AG-UI tool-result message sent back to the agent.
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Draws one call from its arguments alone.
|
|
11
|
+
*
|
|
12
|
+
* Named separately so the replay path can take *this* and never the tool that
|
|
13
|
+
* owns it: a function of this type cannot reach a `handler`, which is what
|
|
14
|
+
* makes "a reload never re-runs a tool's effect" a property of the code rather
|
|
15
|
+
* than a note asking maintainers to be careful.
|
|
16
|
+
*/
|
|
17
|
+
export type ChartRenderer = (args: Record<string, unknown>) => Node | null;
|
|
9
18
|
export interface ClientTool {
|
|
10
19
|
name: string;
|
|
11
20
|
description: string;
|
|
@@ -33,7 +42,7 @@ export interface ClientTool {
|
|
|
33
42
|
*
|
|
34
43
|
* Return `null` for arguments that say nothing worth drawing.
|
|
35
44
|
*/
|
|
36
|
-
render?:
|
|
45
|
+
render?: ChartRenderer;
|
|
37
46
|
}
|
|
38
47
|
/**
|
|
39
48
|
* Holds the frontend tools a host has declared on an `<ag-ui-chat>` element.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client_tool_registry.d.ts","sourceRoot":"","sources":["../../src/tools/client_tool_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;;OAIG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxF;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"client_tool_registry.d.ts","sourceRoot":"","sources":["../../src/tools/client_tool_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;AAE3E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;;OAIG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxF;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;;IAG7B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAE/B;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzB;IAED,yCAAyC;IACzC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAM5B;IAED,wDAAwD;IACxD,KAAK,IAAI,IAAI,EAAE,CAMd;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart_block.d.ts","sourceRoot":"","sources":["../../src/ui/chart_block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,2BAA2B;AAC3B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAEvE,wBAAwB;AACxB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AAoBD,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;
|
|
1
|
+
{"version":3,"file":"chart_block.d.ts","sourceRoot":"","sources":["../../src/ui/chart_block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,2BAA2B;AAC3B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAEvE,wBAAwB;AACxB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AAoBD,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AA6OD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,IAAI,CAoDlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart_spec_from.d.ts","sourceRoot":"","sources":["../../src/ui/chart_spec_from.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"chart_spec_from.d.ts","sourceRoot":"","sources":["../../src/ui/chart_spec_from.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA6E7D,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAqC9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart_tool.d.ts","sourceRoot":"","sources":["../../src/ui/chart_tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAInE,wDAAwD;AACxD,eAAO,MAAM,eAAe,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"chart_tool.d.ts","sourceRoot":"","sources":["../../src/ui/chart_tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAInE,wDAAwD;AACxD,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAgB9C,+BAA+B;AAC/B,wBAAgB,eAAe,IAAI,UAAU,CAuC5C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artooi/ag-ui-web-component",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.1",
|
|
4
4
|
"description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/src/core/ag_ui_chat.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import { fillTemplate } from "../skills/fill_template.js";
|
|
25
25
|
import { parseSkills } from "../skills/parse_skills.js";
|
|
26
26
|
import type { Skill } from "../skills/skill.js";
|
|
27
|
+
import type { ChartRenderer } from "../tools/client_tool_registry.js";
|
|
27
28
|
import { type ClientTool, ClientToolRegistry } from "../tools/client_tool_registry.js";
|
|
28
29
|
import { isDestructive } from "../tools/is_destructive.js";
|
|
29
30
|
import { isNavigates } from "../tools/is_navigates.js";
|
|
@@ -42,7 +43,7 @@ import { renderAttachmentChips } from "../ui/attachment_chips.js";
|
|
|
42
43
|
import { AttachmentTray } from "../ui/attachment_tray.js";
|
|
43
44
|
import { renderChart } from "../ui/chart_block.js";
|
|
44
45
|
import { chartSpecFrom } from "../ui/chart_spec_from.js";
|
|
45
|
-
import { createChartTool } from "../ui/chart_tool.js";
|
|
46
|
+
import { CHART_TOOL_NAME, createChartTool } from "../ui/chart_tool.js";
|
|
46
47
|
import { CheckpointMenu, type CheckpointVerb } from "../ui/checkpoint_menu.js";
|
|
47
48
|
import { type ConfirmationRequest, requestConfirmation } from "../ui/confirmation_card.js";
|
|
48
49
|
import { prettifyToolName } from "../ui/prettify_tool_name.js";
|
|
@@ -1840,9 +1841,15 @@ export class AgUiChat extends HTMLElement {
|
|
|
1840
1841
|
this.#cardElements.set(restored.id, this.#cardFor(restored).element);
|
|
1841
1842
|
// Only `render` is replayed, never `handler`. A restored transcript
|
|
1842
1843
|
// redraws what the call drew; it must not re-run what the call *did*.
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1844
|
+
// Only the renderer is handed over, never the tool. The guarantee that
|
|
1845
|
+
// a reload cannot re-run a tool's *effect* is worth more than a comment
|
|
1846
|
+
// saying so: this signature cannot reach `handler`, so a later
|
|
1847
|
+
// maintainer adding a "no render? fall back to the handler" convenience
|
|
1848
|
+
// here has to change the type first, which is exactly the moment the
|
|
1849
|
+
// question should be asked.
|
|
1850
|
+
const render = this.#resolveTool(restored.name)?.render;
|
|
1851
|
+
if (render !== undefined) {
|
|
1852
|
+
this.#renderToolOutput(render, restored);
|
|
1846
1853
|
}
|
|
1847
1854
|
}
|
|
1848
1855
|
return;
|
|
@@ -2653,7 +2660,9 @@ export class AgUiChat extends HTMLElement {
|
|
|
2653
2660
|
const result = await tool.handler(call.args, call.id);
|
|
2654
2661
|
// Drawn from the arguments rather than the result, so the live path and
|
|
2655
2662
|
// the replay path render the same thing from the same input.
|
|
2656
|
-
|
|
2663
|
+
if (tool.render !== undefined) {
|
|
2664
|
+
this.#renderToolOutput(tool.render, call);
|
|
2665
|
+
}
|
|
2657
2666
|
if (navigates) {
|
|
2658
2667
|
card.settle(TOOL_CALL_STATUS.DONE, this.#strings.navigating);
|
|
2659
2668
|
return { content: "", halt: true };
|
|
@@ -3053,12 +3062,21 @@ export class AgUiChat extends HTMLElement {
|
|
|
3053
3062
|
* arrives is not something to switch on for everybody.
|
|
3054
3063
|
*/
|
|
3055
3064
|
enableCharts(routes: readonly ("tool" | "activity")[] = ["tool", "activity"]): void {
|
|
3065
|
+
const first = !this.#chartActivity && !this.#toolRegistry.has(CHART_TOOL_NAME);
|
|
3056
3066
|
if (routes.includes("activity")) {
|
|
3057
3067
|
this.#chartActivity = true;
|
|
3058
3068
|
}
|
|
3059
3069
|
if (routes.includes("tool")) {
|
|
3060
3070
|
this.registerTool(createChartTool());
|
|
3061
3071
|
}
|
|
3072
|
+
// Called after the element is connected, the history has already replayed
|
|
3073
|
+
// and every chart in it was skipped -- charts were off at the time. That is
|
|
3074
|
+
// the ordinary way to call this (you have to query the element to call
|
|
3075
|
+
// anything on it), so redrawing rather than documenting an ordering rule is
|
|
3076
|
+
// the only answer that does not make the obvious usage wrong.
|
|
3077
|
+
if (first && this.isConnected) {
|
|
3078
|
+
this.reload();
|
|
3079
|
+
}
|
|
3062
3080
|
}
|
|
3063
3081
|
|
|
3064
3082
|
/**
|
|
@@ -3071,13 +3089,10 @@ export class AgUiChat extends HTMLElement {
|
|
|
3071
3089
|
* created inline, in the right place, so anchoring makes *when* the handler
|
|
3072
3090
|
* runs stop mattering.
|
|
3073
3091
|
*/
|
|
3074
|
-
#renderToolOutput(
|
|
3075
|
-
if (tool.render === undefined) {
|
|
3076
|
-
return;
|
|
3077
|
-
}
|
|
3092
|
+
#renderToolOutput(render: ChartRenderer, call: AgUiToolCall): void {
|
|
3078
3093
|
let node: Node | null;
|
|
3079
3094
|
try {
|
|
3080
|
-
node =
|
|
3095
|
+
node = render(call.args);
|
|
3081
3096
|
} catch (error) {
|
|
3082
3097
|
// `render` is consumer code and this runs inside the history replay, where
|
|
3083
3098
|
// a throw abandons the loop and takes every later turn of the transcript
|
|
@@ -3100,11 +3115,16 @@ export class AgUiChat extends HTMLElement {
|
|
|
3100
3115
|
/** Draw, or redraw in place, the chart for one activity message. */
|
|
3101
3116
|
#drawActivityChart(messageId: string, content: unknown): void {
|
|
3102
3117
|
const spec = chartSpecFrom(content);
|
|
3103
|
-
|
|
3104
|
-
return;
|
|
3105
|
-
}
|
|
3106
|
-
const block = renderChart(spec);
|
|
3118
|
+
const block = spec === null ? null : renderChart(spec);
|
|
3107
3119
|
if (block === null) {
|
|
3120
|
+
// The server superseded this chart with something undrawable. Leaving the
|
|
3121
|
+
// old one up is the worst available answer: it shows numbers that have
|
|
3122
|
+
// been retracted, reading as current, and a reload then drops the chart
|
|
3123
|
+
// entirely because the *stored* content is the version we could not draw.
|
|
3124
|
+
// Live and reload should agree, and both should say "gone" rather than
|
|
3125
|
+
// one of them lying.
|
|
3126
|
+
this.#activityBlocks.get(messageId)?.remove();
|
|
3127
|
+
this.#activityBlocks.delete(messageId);
|
|
3108
3128
|
return;
|
|
3109
3129
|
}
|
|
3110
3130
|
const existing = this.#activityBlocks.get(messageId);
|
|
@@ -7,6 +7,16 @@ import type { Tool } from "@ag-ui/core";
|
|
|
7
7
|
* `handler` receives the parsed arguments and returns a result that is
|
|
8
8
|
* JSON-serialised into the AG-UI tool-result message sent back to the agent.
|
|
9
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* Draws one call from its arguments alone.
|
|
12
|
+
*
|
|
13
|
+
* Named separately so the replay path can take *this* and never the tool that
|
|
14
|
+
* owns it: a function of this type cannot reach a `handler`, which is what
|
|
15
|
+
* makes "a reload never re-runs a tool's effect" a property of the code rather
|
|
16
|
+
* than a note asking maintainers to be careful.
|
|
17
|
+
*/
|
|
18
|
+
export type ChartRenderer = (args: Record<string, unknown>) => Node | null;
|
|
19
|
+
|
|
10
20
|
export interface ClientTool {
|
|
11
21
|
name: string;
|
|
12
22
|
description: string;
|
|
@@ -34,7 +44,7 @@ export interface ClientTool {
|
|
|
34
44
|
*
|
|
35
45
|
* Return `null` for arguments that say nothing worth drawing.
|
|
36
46
|
*/
|
|
37
|
-
render?:
|
|
47
|
+
render?: ChartRenderer;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
/**
|
package/src/ui/chart_block.ts
CHANGED
|
@@ -174,7 +174,12 @@ function drawStacked(svg: SVGSVGElement, spec: ChartSpec, min: number, max: numb
|
|
|
174
174
|
const running = spec.labels.map(() => 0);
|
|
175
175
|
spec.series.forEach((series, s) => {
|
|
176
176
|
series.points.forEach((value, i) => {
|
|
177
|
-
|
|
177
|
+
// `?? 0` rather than a cast: `renderChart` is exported, so a caller can
|
|
178
|
+
// hand it a series carrying more points than there are labels, which
|
|
179
|
+
// `chartSpecFrom` would have refused. The cast that used to be here
|
|
180
|
+
// claimed that could not happen and wrote `y="NaN"` into the DOM when it
|
|
181
|
+
// did.
|
|
182
|
+
const from = running[i] ?? 0;
|
|
178
183
|
const to = from + value;
|
|
179
184
|
running[i] = to;
|
|
180
185
|
const y = scaleY(to, min, max);
|
|
@@ -22,6 +22,17 @@ const KINDS: readonly ChartKind[] = ["bar", "line", "pie", "scatter", "stacked"]
|
|
|
22
22
|
*/
|
|
23
23
|
const MAX_POINTS = 20_000;
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Whether a spec's *labels* are cheap enough to draw.
|
|
27
|
+
*
|
|
28
|
+
* `MAX_POINTS` bounds the data; this bounds the DOM. Every label produces an
|
|
29
|
+
* axis text node whatever the series count, so a spec well inside the point
|
|
30
|
+
* budget can still emit tens of thousands of nodes and block the main thread —
|
|
31
|
+
* again on every reload, since it is in the transcript. Kept separate because
|
|
32
|
+
* the two limits answer different questions and a single number cannot.
|
|
33
|
+
*/
|
|
34
|
+
const MAX_LABELS = 2_000;
|
|
35
|
+
|
|
25
36
|
/**
|
|
26
37
|
* Largest magnitude a point may carry.
|
|
27
38
|
*
|
|
@@ -59,9 +70,17 @@ function asNumbers(value: unknown): number[] | null {
|
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
function asStrings(value: unknown): string[] | null {
|
|
62
|
-
if (!Array.isArray(value)
|
|
73
|
+
if (!Array.isArray(value)) {
|
|
63
74
|
return null;
|
|
64
75
|
}
|
|
76
|
+
// `every` over an index range rather than `Array.prototype.some`, which skips
|
|
77
|
+
// holes: a sparse array passed the old check and drew a chart with blank axis
|
|
78
|
+
// labels, which reads as a rendering bug rather than bad input.
|
|
79
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
80
|
+
if (typeof value[i] !== "string") {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
65
84
|
return value as string[];
|
|
66
85
|
}
|
|
67
86
|
|
|
@@ -94,7 +113,7 @@ export function chartSpecFrom(value: unknown): ChartSpec | null {
|
|
|
94
113
|
if (series.length === 0) {
|
|
95
114
|
return null;
|
|
96
115
|
}
|
|
97
|
-
if (series.length * labels.length > MAX_POINTS) {
|
|
116
|
+
if (series.length * labels.length > MAX_POINTS || labels.length > MAX_LABELS) {
|
|
98
117
|
return null;
|
|
99
118
|
}
|
|
100
119
|
|
package/src/ui/chart_tool.ts
CHANGED
|
@@ -20,6 +20,12 @@ function draw(args: Record<string, unknown>): HTMLDivElement | null {
|
|
|
20
20
|
return spec === null ? null : renderChart(spec);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/** Whether these arguments would produce a chart, without producing one. */
|
|
24
|
+
function drawable(args: Record<string, unknown>): boolean {
|
|
25
|
+
const spec = chartSpecFrom(args);
|
|
26
|
+
return spec !== null && spec.labels.length > 0 && spec.series.length > 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
const REJECTED =
|
|
24
30
|
"chart not rendered: expected labels (strings) and series, each with one finite number per label";
|
|
25
31
|
|
|
@@ -54,11 +60,13 @@ export function createChartTool(): ClientTool {
|
|
|
54
60
|
// Says what happened and nothing else; the drawing is `render`'s job. Told
|
|
55
61
|
// plainly when the arguments are unusable, because the model can fix that
|
|
56
62
|
// and retry — a silent no-op would leave it believing the chart is on screen.
|
|
57
|
-
// Answers on what
|
|
58
|
-
// pass validation and still have nothing to show
|
|
59
|
-
//
|
|
60
|
-
// chart is
|
|
61
|
-
|
|
63
|
+
// Answers on what will actually be drawn, not on what validated: a spec can
|
|
64
|
+
// pass validation and still have nothing to show, and reporting success
|
|
65
|
+
// then would leave the model believing a chart is on screen. Asks the
|
|
66
|
+
// question without building the chart, because `render` is about to build
|
|
67
|
+
// the same one a moment later and drawing it twice is pure waste on a spec
|
|
68
|
+
// large enough to matter.
|
|
69
|
+
handler: (args: Record<string, unknown>) => (drawable(args) ? "chart rendered" : REJECTED),
|
|
62
70
|
render: draw,
|
|
63
71
|
};
|
|
64
72
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION: string = "0.26.
|
|
1
|
+
export const VERSION: string = "0.26.1";
|