@happyvertical/smrt-svelte 0.55.9 → 0.55.11
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/AGENTS.md +2 -1
- package/agents/cookbook-shell.md +176 -0
- package/agents/overview-presentation.md +8 -0
- package/agents/overview-surfaces.md +133 -17
- package/agents/screens.md +5 -0
- package/agents/workspace.md +6 -0
- package/dist/components/activity/ActivityList.svelte +35 -0
- package/dist/components/activity/ActivityList.svelte.d.ts +11 -0
- package/dist/components/activity/ActivityList.svelte.d.ts.map +1 -0
- package/dist/components/activity/index.d.ts +3 -0
- package/dist/components/activity/index.d.ts.map +1 -0
- package/dist/components/activity/index.js +1 -0
- package/dist/components/activity/safe-href.d.ts +3 -0
- package/dist/components/activity/safe-href.d.ts.map +1 -0
- package/dist/components/activity/safe-href.js +12 -0
- package/dist/components/activity/types.d.ts +9 -0
- package/dist/components/activity/types.d.ts.map +1 -0
- package/dist/components/activity/types.js +1 -0
- package/dist/components/cookbook/CookbookApp.svelte +236 -0
- package/dist/components/cookbook/CookbookApp.svelte.d.ts +5 -0
- package/dist/components/cookbook/CookbookApp.svelte.d.ts.map +1 -0
- package/dist/components/cookbook/CookbookSectionOverview.svelte +71 -0
- package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts +20 -0
- package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts.map +1 -0
- package/dist/components/cookbook/CookbookSectionPage.svelte +133 -0
- package/dist/components/cookbook/CookbookSectionPage.svelte.d.ts +5 -0
- package/dist/components/cookbook/CookbookSectionPage.svelte.d.ts.map +1 -0
- package/dist/components/cookbook/brand-theme.d.ts +11 -0
- package/dist/components/cookbook/brand-theme.d.ts.map +1 -0
- package/dist/components/cookbook/brand-theme.js +24 -0
- package/dist/components/cookbook/build.d.ts +8 -0
- package/dist/components/cookbook/build.d.ts.map +1 -0
- package/dist/components/cookbook/build.js +277 -0
- package/dist/components/cookbook/catalog.d.ts +37 -0
- package/dist/components/cookbook/catalog.d.ts.map +1 -0
- package/dist/components/cookbook/catalog.js +99 -0
- package/dist/components/cookbook/context.d.ts +23 -0
- package/dist/components/cookbook/context.d.ts.map +1 -0
- package/dist/components/cookbook/context.js +15 -0
- package/dist/components/cookbook/index.d.ts +22 -0
- package/dist/components/cookbook/index.d.ts.map +1 -0
- package/dist/components/cookbook/index.js +20 -0
- package/dist/components/cookbook/page.d.ts +23 -0
- package/dist/components/cookbook/page.d.ts.map +1 -0
- package/dist/components/cookbook/page.js +32 -0
- package/dist/components/cookbook/registry.d.ts +37 -0
- package/dist/components/cookbook/registry.d.ts.map +1 -0
- package/dist/components/cookbook/registry.js +38 -0
- package/dist/components/cookbook/sections.d.ts +60 -0
- package/dist/components/cookbook/sections.d.ts.map +1 -0
- package/dist/components/cookbook/sections.js +88 -0
- package/dist/components/cookbook/server.d.ts +61 -0
- package/dist/components/cookbook/server.d.ts.map +1 -0
- package/dist/components/cookbook/server.js +108 -0
- package/dist/components/cookbook/theme.d.ts +21 -0
- package/dist/components/cookbook/theme.d.ts.map +1 -0
- package/dist/components/cookbook/theme.js +53 -0
- package/dist/components/cookbook/types.d.ts +204 -0
- package/dist/components/cookbook/types.d.ts.map +1 -0
- package/dist/components/cookbook/types.js +1 -0
- package/dist/components/notifications/LocalizedNotifications.fixture.svelte +16 -0
- package/dist/components/notifications/LocalizedNotifications.fixture.svelte.d.ts +11 -0
- package/dist/components/notifications/LocalizedNotifications.fixture.svelte.d.ts.map +1 -0
- package/dist/components/notifications/NotificationBell.svelte +136 -0
- package/dist/components/notifications/NotificationBell.svelte.d.ts +13 -0
- package/dist/components/notifications/NotificationBell.svelte.d.ts.map +1 -0
- package/dist/components/notifications/index.d.ts +3 -0
- package/dist/components/notifications/index.d.ts.map +1 -0
- package/dist/components/notifications/index.js +1 -0
- package/dist/components/notifications/types.d.ts +27 -0
- package/dist/components/notifications/types.d.ts.map +1 -0
- package/dist/components/notifications/types.js +1 -0
- package/dist/components/overview/OverviewAssistantUndo.svelte +77 -0
- package/dist/components/overview/OverviewAssistantUndo.svelte.d.ts +13 -0
- package/dist/components/overview/OverviewAssistantUndo.svelte.d.ts.map +1 -0
- package/dist/components/overview/OverviewGrid.svelte +5 -2
- package/dist/components/overview/OverviewGrid.svelte.d.ts.map +1 -1
- package/dist/components/overview/assistant-surface.d.ts +90 -0
- package/dist/components/overview/assistant-surface.d.ts.map +1 -0
- package/dist/components/overview/assistant-surface.js +65 -0
- package/dist/components/overview/assistant.svelte.d.ts +115 -0
- package/dist/components/overview/assistant.svelte.d.ts.map +1 -0
- package/dist/components/overview/assistant.svelte.js +260 -0
- package/dist/components/overview/controller.svelte.d.ts +8 -0
- package/dist/components/overview/controller.svelte.d.ts.map +1 -1
- package/dist/components/overview/controller.svelte.js +76 -13
- package/dist/components/overview/grid-types.d.ts +6 -2
- package/dist/components/overview/grid-types.d.ts.map +1 -1
- package/dist/components/overview/index.d.ts +2 -0
- package/dist/components/overview/index.d.ts.map +1 -1
- package/dist/components/overview/index.js +2 -0
- package/dist/components/overview/operations.d.ts +169 -0
- package/dist/components/overview/operations.d.ts.map +1 -0
- package/dist/components/overview/operations.js +358 -0
- package/dist/components/overview/server.d.ts +2 -0
- package/dist/components/overview/server.d.ts.map +1 -1
- package/dist/components/overview/server.js +2 -0
- package/dist/components/workspace/admin-shell/settings-delta.d.ts +21 -0
- package/dist/components/workspace/admin-shell/settings-delta.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/settings-delta.js +142 -0
- package/dist/components/workspace/index.d.ts +1 -0
- package/dist/components/workspace/index.d.ts.map +1 -1
- package/dist/components/workspace/index.js +1 -0
- package/dist/components/workspace/server/index.d.ts +6 -2
- package/dist/components/workspace/server/index.d.ts.map +1 -1
- package/dist/components/workspace/server/index.js +5 -2
- package/dist/i18n/server.d.ts +1 -0
- package/dist/i18n/server.d.ts.map +1 -1
- package/dist/i18n/server.js +1 -0
- package/dist/i18n/strings.notifications.d.ts +12 -0
- package/dist/i18n/strings.notifications.d.ts.map +1 -0
- package/dist/i18n/strings.notifications.js +13 -0
- package/dist/i18n/strings.overview.d.ts +9 -0
- package/dist/i18n/strings.overview.d.ts.map +1 -1
- package/dist/i18n/strings.overview.js +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +31 -14
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The overview assistant in the browser (#3727 phase 4): the structured
|
|
3
|
+
* operations an in-page assistant (the AssistantDock) applies to a mounted
|
|
4
|
+
* overview, with a single-step Undo.
|
|
5
|
+
*
|
|
6
|
+
* A batch is planned with {@link planOverviewOperations} against the
|
|
7
|
+
* controller's definition and current override, so it is atomic (one invalid
|
|
8
|
+
* operation rejects the batch and nothing changes) and can only produce an
|
|
9
|
+
* override the save endpoint accepts. A valid batch lands through
|
|
10
|
+
* `controller.restore`, so the grid updates live and the host's `onchange`
|
|
11
|
+
* persists it like any other edit. The override before the batch is kept for
|
|
12
|
+
* Undo; Undo restores it exactly, and refuses once the overview changed in
|
|
13
|
+
* between (it would discard that edit).
|
|
14
|
+
*
|
|
15
|
+
* The browser tools (`overview_describe`, `overview_apply`, `overview_undo`)
|
|
16
|
+
* register on the page's WebMCP registry through `useWebMcpTool`, the same
|
|
17
|
+
* path every bespoke page tool takes, so the dock offers and runs them like
|
|
18
|
+
* any other page tool (a `write` waits for the person's Allow unless the host
|
|
19
|
+
* policy says otherwise). The browser session is the principal: the
|
|
20
|
+
* controller only holds this viewer's override, and `canCustomize` gates every
|
|
21
|
+
* apply and undo.
|
|
22
|
+
*/
|
|
23
|
+
import { useWebMcpTool } from '../../web/webmcp.svelte.js';
|
|
24
|
+
import { describeOverview, OVERVIEW_MAX_OPERATIONS, OVERVIEW_OPERATION_SCHEMA, planOverviewOperations, } from './operations.js';
|
|
25
|
+
const TOOL_PREFIX = /^[a-z][a-z0-9_]{0,40}$/;
|
|
26
|
+
let batchSeq = 0;
|
|
27
|
+
function sameJson(a, b) {
|
|
28
|
+
return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
|
|
29
|
+
}
|
|
30
|
+
function defaultMessage(batch) {
|
|
31
|
+
void batch;
|
|
32
|
+
return 'The assistant updated this overview.';
|
|
33
|
+
}
|
|
34
|
+
export class OverviewAssistant {
|
|
35
|
+
controller;
|
|
36
|
+
#options;
|
|
37
|
+
#prefix;
|
|
38
|
+
#last = $state.raw(null);
|
|
39
|
+
#toastId = null;
|
|
40
|
+
constructor(controller, options = {}) {
|
|
41
|
+
const prefix = options.toolPrefix ?? 'overview';
|
|
42
|
+
if (!TOOL_PREFIX.test(prefix)) {
|
|
43
|
+
throw new Error(`createOverviewAssistant: invalid toolPrefix "${prefix}"`);
|
|
44
|
+
}
|
|
45
|
+
this.controller = controller;
|
|
46
|
+
this.#options = options;
|
|
47
|
+
this.#prefix = prefix;
|
|
48
|
+
}
|
|
49
|
+
/** The last applied batch while it can still be undone. */
|
|
50
|
+
get lastBatch() {
|
|
51
|
+
return this.#last;
|
|
52
|
+
}
|
|
53
|
+
/** Text for the Undo affordance. */
|
|
54
|
+
message(batch) {
|
|
55
|
+
return (this.#options.message ?? defaultMessage)(batch);
|
|
56
|
+
}
|
|
57
|
+
get undoLabel() {
|
|
58
|
+
return this.#options.undoLabel ?? 'Undo';
|
|
59
|
+
}
|
|
60
|
+
/** What the overview allows and shows now. */
|
|
61
|
+
describe() {
|
|
62
|
+
return describeOverview({
|
|
63
|
+
definition: this.controller.definition,
|
|
64
|
+
registry: this.controller.registry,
|
|
65
|
+
override: this.controller.committedOverride,
|
|
66
|
+
canCustomize: this.controller.canCustomize,
|
|
67
|
+
translate: this.#options.translate,
|
|
68
|
+
maxOperations: this.#options.maxOperations,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Apply a batch atomically; the grid updates through the controller. */
|
|
72
|
+
apply(operations) {
|
|
73
|
+
const controller = this.controller;
|
|
74
|
+
if (!controller.canCustomize) {
|
|
75
|
+
return { ok: false, reason: 'not_allowed', issues: [] };
|
|
76
|
+
}
|
|
77
|
+
// What the controller last committed, even if the host has not fed it
|
|
78
|
+
// back yet.
|
|
79
|
+
const before = controller.committedOverride;
|
|
80
|
+
const plan = planOverviewOperations({
|
|
81
|
+
definition: controller.definition,
|
|
82
|
+
registry: controller.registry,
|
|
83
|
+
override: before,
|
|
84
|
+
operations,
|
|
85
|
+
maxOperations: this.#options.maxOperations,
|
|
86
|
+
});
|
|
87
|
+
if (!plan.ok)
|
|
88
|
+
return { ok: false, reason: 'invalid', issues: plan.issues };
|
|
89
|
+
if (plan.unchanged) {
|
|
90
|
+
return { ok: true, batchId: null, results: plan.results };
|
|
91
|
+
}
|
|
92
|
+
const restored = controller.restore(plan.override);
|
|
93
|
+
if (!restored.ok) {
|
|
94
|
+
if (restored.reason === 'unchanged') {
|
|
95
|
+
return { ok: true, batchId: null, results: plan.results };
|
|
96
|
+
}
|
|
97
|
+
return { ok: false, reason: 'not_allowed', issues: [] };
|
|
98
|
+
}
|
|
99
|
+
const counts = {};
|
|
100
|
+
for (const result of plan.results) {
|
|
101
|
+
counts[result.op] = (counts[result.op] ?? 0) + 1;
|
|
102
|
+
}
|
|
103
|
+
batchSeq += 1;
|
|
104
|
+
const batch = {
|
|
105
|
+
id: `b${batchSeq}`,
|
|
106
|
+
results: plan.results,
|
|
107
|
+
counts,
|
|
108
|
+
before,
|
|
109
|
+
after: plan.override,
|
|
110
|
+
};
|
|
111
|
+
this.#last = batch;
|
|
112
|
+
this.#showToast(batch);
|
|
113
|
+
this.#options.onapply?.(batch);
|
|
114
|
+
return { ok: true, batchId: batch.id, results: plan.results };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Restore the override from before the last batch. Refused when the
|
|
118
|
+
* overview changed after that batch (the person edited it), or when `id`
|
|
119
|
+
* names another batch.
|
|
120
|
+
*/
|
|
121
|
+
undo(id) {
|
|
122
|
+
const batch = this.#last;
|
|
123
|
+
if (!batch || (id !== undefined && id !== batch.id)) {
|
|
124
|
+
return { ok: false, reason: 'nothing_to_undo' };
|
|
125
|
+
}
|
|
126
|
+
const controller = this.controller;
|
|
127
|
+
if (!controller.canCustomize)
|
|
128
|
+
return { ok: false, reason: 'not_allowed' };
|
|
129
|
+
if (!sameJson(controller.committedOverride, batch.after)) {
|
|
130
|
+
this.dismiss();
|
|
131
|
+
return { ok: false, reason: 'changed_since' };
|
|
132
|
+
}
|
|
133
|
+
const restored = controller.restore(batch.before);
|
|
134
|
+
if (!restored.ok && restored.reason !== 'unchanged') {
|
|
135
|
+
return { ok: false, reason: 'not_allowed' };
|
|
136
|
+
}
|
|
137
|
+
this.dismiss();
|
|
138
|
+
return { ok: true };
|
|
139
|
+
}
|
|
140
|
+
/** Forget the last batch (hides the Undo affordance). */
|
|
141
|
+
dismiss() {
|
|
142
|
+
this.#last = null;
|
|
143
|
+
if (this.#toastId)
|
|
144
|
+
this.#options.toaster?.dismiss(this.#toastId);
|
|
145
|
+
this.#toastId = null;
|
|
146
|
+
}
|
|
147
|
+
#showToast(batch) {
|
|
148
|
+
const toaster = this.#options.toaster;
|
|
149
|
+
if (!toaster)
|
|
150
|
+
return;
|
|
151
|
+
if (this.#toastId)
|
|
152
|
+
toaster.dismiss(this.#toastId);
|
|
153
|
+
this.#toastId = toaster.show({
|
|
154
|
+
message: this.message(batch),
|
|
155
|
+
variant: 'info',
|
|
156
|
+
duration: 10_000,
|
|
157
|
+
action: { label: this.undoLabel, run: () => void this.undo(batch.id) },
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/** The browser tool specs (register with `useOverviewAssistantTools`). */
|
|
161
|
+
tools() {
|
|
162
|
+
const p = this.#prefix;
|
|
163
|
+
const json = (value) => JSON.stringify(value);
|
|
164
|
+
return [
|
|
165
|
+
{
|
|
166
|
+
name: `${p}_describe`,
|
|
167
|
+
description: 'Describe this overview page: the widget types it allows (with their option fields, allowed values and span range) and the widgets it shows now, in order. Call before changing it; never invent types, option keys or models.',
|
|
168
|
+
inputSchema: {
|
|
169
|
+
type: 'object',
|
|
170
|
+
properties: {},
|
|
171
|
+
additionalProperties: false,
|
|
172
|
+
},
|
|
173
|
+
annotations: { readOnlyHint: true },
|
|
174
|
+
execute: () => json(this.describe()),
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: `${p}_apply`,
|
|
178
|
+
description: 'Change this overview with a batch of structured operations (add, configure, move, resize, remove). The batch is all-or-nothing: if any operation is invalid nothing changes and the issues are returned to fix. The person can undo the batch.',
|
|
179
|
+
inputSchema: {
|
|
180
|
+
type: 'object',
|
|
181
|
+
required: ['operations'],
|
|
182
|
+
additionalProperties: false,
|
|
183
|
+
properties: {
|
|
184
|
+
operations: {
|
|
185
|
+
type: 'array',
|
|
186
|
+
minItems: 1,
|
|
187
|
+
maxItems: this.#options.maxOperations ?? OVERVIEW_MAX_OPERATIONS,
|
|
188
|
+
items: OVERVIEW_OPERATION_SCHEMA,
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
annotations: {
|
|
193
|
+
readOnlyHint: false,
|
|
194
|
+
destructiveHint: false,
|
|
195
|
+
idempotentHint: false,
|
|
196
|
+
openWorldHint: false,
|
|
197
|
+
},
|
|
198
|
+
execute: (args) => {
|
|
199
|
+
const result = this.apply(args.operations);
|
|
200
|
+
if (result.ok) {
|
|
201
|
+
return json({
|
|
202
|
+
ok: true,
|
|
203
|
+
changed: result.batchId !== null,
|
|
204
|
+
undoToken: result.batchId,
|
|
205
|
+
applied: result.results,
|
|
206
|
+
widgets: this.describe().widgets,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return json({
|
|
210
|
+
ok: false,
|
|
211
|
+
error: result.reason === 'not_allowed'
|
|
212
|
+
? 'You may not change this overview.'
|
|
213
|
+
: 'The batch was rejected and nothing changed. Fix the listed operations and call again.',
|
|
214
|
+
issues: result.issues,
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: `${p}_undo`,
|
|
220
|
+
description: 'Undo the last batch you applied to this overview (pass its undoToken). Single step; refused if the overview changed since.',
|
|
221
|
+
inputSchema: {
|
|
222
|
+
type: 'object',
|
|
223
|
+
required: ['undoToken'],
|
|
224
|
+
additionalProperties: false,
|
|
225
|
+
properties: { undoToken: { type: 'string' } },
|
|
226
|
+
},
|
|
227
|
+
annotations: {
|
|
228
|
+
readOnlyHint: false,
|
|
229
|
+
destructiveHint: false,
|
|
230
|
+
idempotentHint: false,
|
|
231
|
+
openWorldHint: false,
|
|
232
|
+
},
|
|
233
|
+
execute: (args) => {
|
|
234
|
+
const token = typeof args.undoToken === 'string' ? args.undoToken : '';
|
|
235
|
+
const result = this.undo(token);
|
|
236
|
+
return json(result.ok
|
|
237
|
+
? { ok: true, widgets: this.describe().widgets }
|
|
238
|
+
: { ok: false, error: result.reason });
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/** Create the browser overview assistant for a controller. */
|
|
245
|
+
export function createOverviewAssistant(controller, options) {
|
|
246
|
+
return new OverviewAssistant(controller, options);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Register the assistant's browser tools on the page's WebMCP registry for
|
|
250
|
+
* the calling component's lifetime. Call during component initialization.
|
|
251
|
+
* `apply` and `undo` are `write` tools: the nearest Provider's
|
|
252
|
+
* `webmcp.effects` must allow `write`, or only `describe` is exposed.
|
|
253
|
+
*/
|
|
254
|
+
export function useOverviewAssistantTools(assistant, options = {}) {
|
|
255
|
+
for (const spec of assistant.tools()) {
|
|
256
|
+
useWebMcpTool(() => spec, {
|
|
257
|
+
...(options.effects ? { effects: options.effects } : {}),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
@@ -47,6 +47,14 @@ export declare class OverviewController {
|
|
|
47
47
|
get base(): OverviewDocument;
|
|
48
48
|
/** The canonical override currently applied; `null` when on defaults. */
|
|
49
49
|
get override(): OverviewOverride | null;
|
|
50
|
+
/**
|
|
51
|
+
* The override this controller last committed: {@link override}, or, while
|
|
52
|
+
* a host-owned getter still answers the value from before the last edit
|
|
53
|
+
* (the host has not fed it back yet), the value handed to `onchange`. An
|
|
54
|
+
* Undo compares against this so a pending save is not mistaken for a
|
|
55
|
+
* change made elsewhere.
|
|
56
|
+
*/
|
|
57
|
+
get committedOverride(): OverviewOverride | null;
|
|
50
58
|
/** What was dropped or reported while resolving. */
|
|
51
59
|
get issues(): readonly OverviewIssue[];
|
|
52
60
|
/** True when the viewer has changed anything from the defaults. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/overview/controller.svelte.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,sCAAsC;AACtC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,qBAAqB,CAAC;CAC/B;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACxB;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACF,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,iBAAiB,GACjB,OAAO,GACP,WAAW,CAAC;IAChB,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC9B,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,cAAc,GAAG,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC;IAC7D;;;;OAIG;IACH,UAAU,CAAC,EAAE,CACX,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAUD,qBAAa,kBAAkB;;
|
|
1
|
+
{"version":3,"file":"controller.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/overview/controller.svelte.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,sCAAsC;AACtC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,qBAAqB,CAAC;CAC/B;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACxB;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACF,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,iBAAiB,GACjB,OAAO,GACP,WAAW,CAAC;IAChB,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC9B,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,cAAc,GAAG,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC;IAC7D;;;;OAIG;IACH,UAAU,CAAC,EAAE,CACX,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAUD,qBAAa,kBAAkB;;gBA4BjB,OAAO,EAAE,yBAAyB;IAqB9C,IAAI,UAAU,IAAI,kBAAkB,CAEnC;IAED,IAAI,QAAQ,IAAI,cAAc,CAE7B;IAED,wCAAwC;IACxC,IAAI,QAAQ,IAAI,gBAAgB,CAE/B;IAED,8BAA8B;IAC9B,IAAI,IAAI,IAAI,gBAAgB,CAE3B;IAED,yEAAyE;IACzE,IAAI,QAAQ,IAAI,gBAAgB,GAAG,IAAI,CAEtC;IAED;;;;;;OAMG;IACH,IAAI,iBAAiB,IAAI,gBAAgB,GAAG,IAAI,CAO/C;IA4CD,oDAAoD;IACpD,IAAI,MAAM,IAAI,SAAS,aAAa,EAAE,CAErC;IAED,mEAAmE;IACnE,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,iDAAiD;IACjD,IAAI,IAAI,IAAI,OAAO,CAGlB;IAED,2EAA2E;IAC3E,IAAI,OAAO,IAAI,gBAAgB,EAAE,CAShC;IAED,oEAAoE;IACpE,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,mBAAmB;IAwClD,8EAA8E;IAC9E,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,gBAAgB;IAoClE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB;IAUpC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB;IAWnD,kEAAkE;IAClE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB;IAelD,2EAA2E;IAC3E,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,gBAAgB;IAwBlE,4EAA4E;IAC5E,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB;IAmBzC,sEAAsE;IACtE,KAAK,IAAI,gBAAgB;IAWzB;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB;IAkB5C,+CAA+C;IAC/C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAMxB;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAuDZ,6EAA6E;IAC7E,OAAO,IAAI,IAAI;CAIhB;AAMD,iEAAiE;AACjE,wBAAgB,cAAc,CAC5B,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CAEpB"}
|
|
@@ -22,7 +22,20 @@ export class OverviewController {
|
|
|
22
22
|
#local = $state.raw(null);
|
|
23
23
|
#entries = $state.raw({});
|
|
24
24
|
#pending = new Map();
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Overrides handed to `onchange` that a host-owned getter has not fed back
|
|
27
|
+
* yet, oldest first, and what the getter answered before the oldest of
|
|
28
|
+
* them (`prior`). Hosts acknowledge in order.
|
|
29
|
+
*/
|
|
30
|
+
#outstanding = null;
|
|
31
|
+
#resolved = $derived.by(() => {
|
|
32
|
+
const resolved = resolveOverview(this.#options.definition, this.#options.override ? this.#options.override() : this.#local, this.#registry);
|
|
33
|
+
// Every host feed-back passes here (the grid reads `document`), so a
|
|
34
|
+
// pending edit is retired as soon as the getter moves off its prior
|
|
35
|
+
// value, even if nothing reads `committedOverride` in between.
|
|
36
|
+
this.#retire(diffOverview(resolved.base, resolved.document));
|
|
37
|
+
return resolved;
|
|
38
|
+
});
|
|
26
39
|
constructor(options) {
|
|
27
40
|
this.#options = options;
|
|
28
41
|
this.#registry = options.registry ?? defaultWidgetRegistry;
|
|
@@ -60,6 +73,61 @@ export class OverviewController {
|
|
|
60
73
|
get override() {
|
|
61
74
|
return diffOverview(this.#resolved.base, this.#resolved.document);
|
|
62
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* The override this controller last committed: {@link override}, or, while
|
|
78
|
+
* a host-owned getter still answers the value from before the last edit
|
|
79
|
+
* (the host has not fed it back yet), the value handed to `onchange`. An
|
|
80
|
+
* Undo compares against this so a pending save is not mistaken for a
|
|
81
|
+
* change made elsewhere.
|
|
82
|
+
*/
|
|
83
|
+
get committedOverride() {
|
|
84
|
+
const current = this.override;
|
|
85
|
+
this.#retire(current);
|
|
86
|
+
const outstanding = this.#outstanding;
|
|
87
|
+
return outstanding
|
|
88
|
+
? outstanding.values.at(-1)
|
|
89
|
+
: current;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Acknowledge what the host getter now answers. Still the value from before
|
|
93
|
+
* the oldest outstanding emission: nothing was fed back yet. Equal to an
|
|
94
|
+
* outstanding emission: that one and every older one are acknowledged (in
|
|
95
|
+
* order), and the getter's value becomes the prior of the rest. Anything
|
|
96
|
+
* else is a change made elsewhere: the queue is dropped, so the mask only
|
|
97
|
+
* ever covers this controller's own unacknowledged saves.
|
|
98
|
+
*/
|
|
99
|
+
#retire(current) {
|
|
100
|
+
const outstanding = this.#outstanding;
|
|
101
|
+
if (!outstanding || sameJson(current, outstanding.prior))
|
|
102
|
+
return;
|
|
103
|
+
const index = outstanding.values.findIndex((value) => sameJson(value, current));
|
|
104
|
+
if (index < 0 || index === outstanding.values.length - 1) {
|
|
105
|
+
this.#outstanding = null;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.#outstanding = {
|
|
109
|
+
prior: current,
|
|
110
|
+
values: outstanding.values.slice(index + 1),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Hand a canonical override to the host, queueing it until fed back. */
|
|
114
|
+
#emit(override) {
|
|
115
|
+
if (this.#options.override) {
|
|
116
|
+
const current = this.override;
|
|
117
|
+
this.#retire(current);
|
|
118
|
+
const outstanding = this.#outstanding;
|
|
119
|
+
this.#outstanding = outstanding
|
|
120
|
+
? {
|
|
121
|
+
prior: outstanding.prior,
|
|
122
|
+
values: [...outstanding.values, override],
|
|
123
|
+
}
|
|
124
|
+
: { prior: current, values: [override] };
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this.#local = override;
|
|
128
|
+
}
|
|
129
|
+
void this.#options.onchange?.(override);
|
|
130
|
+
}
|
|
63
131
|
/** What was dropped or reported while resolving. */
|
|
64
132
|
get issues() {
|
|
65
133
|
return this.#resolved.issues;
|
|
@@ -103,12 +171,10 @@ export class OverviewController {
|
|
|
103
171
|
definition: this.#options.definition,
|
|
104
172
|
});
|
|
105
173
|
const override = diffOverview(this.#resolved.base, sanitized.document);
|
|
106
|
-
if (sameJson(override, this.
|
|
174
|
+
if (sameJson(override, this.committedOverride)) {
|
|
107
175
|
return { ok: false, reason: 'unchanged' };
|
|
108
176
|
}
|
|
109
|
-
|
|
110
|
-
this.#local = override;
|
|
111
|
-
void this.#options.onchange?.(override);
|
|
177
|
+
this.#emit(override);
|
|
112
178
|
// The derived document reflects a host-owned override only after the host
|
|
113
179
|
// feeds it back, so sync against what was just committed.
|
|
114
180
|
this.#syncWidgets(sanitized.document.widgets);
|
|
@@ -227,11 +293,10 @@ export class OverviewController {
|
|
|
227
293
|
const denied = this.#gate();
|
|
228
294
|
if (denied)
|
|
229
295
|
return denied;
|
|
230
|
-
if (
|
|
296
|
+
if (isEmptyOverride(this.committedOverride)) {
|
|
231
297
|
return { ok: false, reason: 'unchanged' };
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
void this.#options.onchange?.(null);
|
|
298
|
+
}
|
|
299
|
+
this.#emit(null);
|
|
235
300
|
this.#syncWidgets(this.#resolved.base.widgets);
|
|
236
301
|
return { ok: true, id: '' };
|
|
237
302
|
}
|
|
@@ -246,12 +311,10 @@ export class OverviewController {
|
|
|
246
311
|
const { override: parsed } = parseOverviewOverride(override);
|
|
247
312
|
const next = resolveOverview(this.#options.definition, parsed, this.#registry);
|
|
248
313
|
const canonical = diffOverview(next.base, next.document);
|
|
249
|
-
if (sameJson(canonical, this.
|
|
314
|
+
if (sameJson(canonical, this.committedOverride)) {
|
|
250
315
|
return { ok: false, reason: 'unchanged' };
|
|
251
316
|
}
|
|
252
|
-
|
|
253
|
-
this.#local = canonical;
|
|
254
|
-
void this.#options.onchange?.(canonical);
|
|
317
|
+
this.#emit(canonical);
|
|
255
318
|
this.#syncWidgets(next.document.widgets);
|
|
256
319
|
return { ok: true, id: '' };
|
|
257
320
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Component } from 'svelte';
|
|
1
|
+
import type { Component, Snippet } from 'svelte';
|
|
2
2
|
import type { OverviewController } from './controller.svelte.js';
|
|
3
|
-
import type { OverviewOptions, RegisteredWidget, WidgetComponentProps } from './types.js';
|
|
3
|
+
import type { OverviewOptions, OverviewWidget, RegisteredWidget, WidgetComponentProps } from './types.js';
|
|
4
4
|
/** A model the option editor offers for `model` fields. */
|
|
5
5
|
export interface OverviewModelChoice {
|
|
6
6
|
value: string;
|
|
@@ -25,6 +25,10 @@ export interface OverviewGridProps {
|
|
|
25
25
|
label?: string;
|
|
26
26
|
/** Heading level of widget titles (default 2). */
|
|
27
27
|
headingLevel?: 2 | 3 | 4;
|
|
28
|
+
/** Optional title content; the grid retains the heading element and accessible id. */
|
|
29
|
+
heading?: Snippet<[widget: OverviewWidget, title: string]>;
|
|
30
|
+
/** Tile presentation outside edit mode (default card). Editing retains its frame. */
|
|
31
|
+
presentation?: 'card' | 'plain';
|
|
28
32
|
/** Models offered by `model` option fields (else a text box). */
|
|
29
33
|
models?: readonly OverviewModelChoice[];
|
|
30
34
|
/** Host renderer for icon names that are not built in. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-types.d.ts","sourceRoot":"","sources":["../../../src/components/overview/grid-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"grid-types.d.ts","sourceRoot":"","sources":["../../../src/components/overview/grid-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,2DAA2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,+BAA+B;AAC/B,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,UAAU,EAAE,kBAAkB,CAAC;IAC/B;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAClE;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,sFAAsF;IACtF,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,iEAAiE;IACjE,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACxC,0DAA0D;IAC1D,aAAa,CAAC,EAAE,SAAS,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oCAAoC;AACpC,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,+DAA+D;IAC/D,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACxC,+DAA+D;IAC/D,MAAM,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,iBAAiB,EAAE,GAAG,IAAI,CAAC;IACjE,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB"}
|
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
* editor. The Svelte-free model, registry and server load contract are also
|
|
7
7
|
* published on `@happyvertical/smrt-svelte/overview/server`.
|
|
8
8
|
*/
|
|
9
|
+
export { createOverviewAssistant, OverviewAssistant, type OverviewAssistantApplyResult, type OverviewAssistantBatch, type OverviewAssistantOptions, type OverviewAssistantUndoResult, useOverviewAssistantTools, } from './assistant.svelte.js';
|
|
9
10
|
export { createOverview, OverviewController, type OverviewControllerOptions, type OverviewOpResult, type OverviewWidgetEntry, } from './controller.svelte.js';
|
|
10
11
|
export { type FormatWidgetValueOptions, formatWidgetValue, type WidgetValueFormat, } from './format.js';
|
|
11
12
|
export type { OverviewFormIssue, OverviewGridProps, OverviewModelChoice, WidgetOptionsFormProps, } from './grid-types.js';
|
|
12
13
|
export { type BlockNode, type InlineNode, parseMarkdown, safeHref, } from './markdown.js';
|
|
14
|
+
export { default as OverviewAssistantUndo } from './OverviewAssistantUndo.svelte';
|
|
13
15
|
export { default as OverviewGrid } from './OverviewGrid.svelte';
|
|
14
16
|
export { spanFromKey, spanFromPointer } from './resize.js';
|
|
15
17
|
export * from './server.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/overview/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,aAAa,EACb,QAAQ,GACT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EACL,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/overview/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,KAAK,4BAA4B,EACjC,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,aAAa,EACb,QAAQ,GACT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EACL,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* editor. The Svelte-free model, registry and server load contract are also
|
|
7
7
|
* published on `@happyvertical/smrt-svelte/overview/server`.
|
|
8
8
|
*/
|
|
9
|
+
export { createOverviewAssistant, OverviewAssistant, useOverviewAssistantTools, } from './assistant.svelte.js';
|
|
9
10
|
export { createOverview, OverviewController, } from './controller.svelte.js';
|
|
10
11
|
export { formatWidgetValue, } from './format.js';
|
|
11
12
|
export { parseMarkdown, safeHref, } from './markdown.js';
|
|
13
|
+
export { default as OverviewAssistantUndo } from './OverviewAssistantUndo.svelte';
|
|
12
14
|
export { default as OverviewGrid } from './OverviewGrid.svelte';
|
|
13
15
|
export { spanFromKey, spanFromPointer } from './resize.js';
|
|
14
16
|
export * from './server.js';
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured overview operations (#3727 phase 4): the batch an assistant (or
|
|
3
|
+
* any other non-UI caller) applies to an overview, and the description it
|
|
4
|
+
* reads first.
|
|
5
|
+
*
|
|
6
|
+
* An operation is data, never code: `add`, `configure`, `move`, `resize` and
|
|
7
|
+
* `remove`, with the same option vocabulary the grid's own editor uses. A batch
|
|
8
|
+
* is planned against the page's definition and the current override with the
|
|
9
|
+
* phase-1 model and then checked with {@link checkOverviewOverride}, so it can
|
|
10
|
+
* only produce an override the save endpoint would accept. A batch is atomic:
|
|
11
|
+
* one invalid operation rejects the whole batch and nothing is returned to
|
|
12
|
+
* apply. Nothing here loads data or runs a query.
|
|
13
|
+
*
|
|
14
|
+
* Svelte-free; on both `./overview` and `./overview/server`.
|
|
15
|
+
*/
|
|
16
|
+
import type { WidgetRegistry } from './registry.js';
|
|
17
|
+
import { type OverviewDefinition, type OverviewDocument, type OverviewOptions, type OverviewOptionValue, type OverviewOverride, type OverviewWidget, type RegisteredWidget, type WidgetOptionField, type WidgetOptionIssue } from './types.js';
|
|
18
|
+
/** Most operations one batch may carry. */
|
|
19
|
+
export declare const OVERVIEW_MAX_OPERATIONS = 20;
|
|
20
|
+
/** Add a widget at the end (or at `index`). */
|
|
21
|
+
export interface OverviewAddOperation {
|
|
22
|
+
op: 'add';
|
|
23
|
+
type: string;
|
|
24
|
+
span?: number;
|
|
25
|
+
options?: OverviewOptions;
|
|
26
|
+
/** Position once added (default: the end). */
|
|
27
|
+
index?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Change a widget's options. The given keys are merged onto the current
|
|
31
|
+
* options; a `null` value clears that key back to its default.
|
|
32
|
+
*/
|
|
33
|
+
export interface OverviewConfigureOperation {
|
|
34
|
+
op: 'configure';
|
|
35
|
+
id: string;
|
|
36
|
+
options: Record<string, OverviewOptionValue>;
|
|
37
|
+
}
|
|
38
|
+
/** Move a widget so it sits at `index` once it is taken out of the list. */
|
|
39
|
+
export interface OverviewMoveOperation {
|
|
40
|
+
op: 'move';
|
|
41
|
+
id: string;
|
|
42
|
+
index: number;
|
|
43
|
+
}
|
|
44
|
+
/** Set a widget's column span. */
|
|
45
|
+
export interface OverviewResizeOperation {
|
|
46
|
+
op: 'resize';
|
|
47
|
+
id: string;
|
|
48
|
+
span: number;
|
|
49
|
+
}
|
|
50
|
+
/** Remove a widget. */
|
|
51
|
+
export interface OverviewRemoveOperation {
|
|
52
|
+
op: 'remove';
|
|
53
|
+
id: string;
|
|
54
|
+
}
|
|
55
|
+
export type OverviewOperation = OverviewAddOperation | OverviewConfigureOperation | OverviewMoveOperation | OverviewResizeOperation | OverviewRemoveOperation;
|
|
56
|
+
export type OverviewOperationKind = OverviewOperation['op'];
|
|
57
|
+
export declare const OVERVIEW_OPERATION_KINDS: readonly OverviewOperationKind[];
|
|
58
|
+
export type OverviewOperationIssueCode = 'malformed' | 'too_many_operations' | 'unknown_widget' | 'unknown_type' | 'type_not_allowed' | 'invalid_options' | 'invalid_span' | 'invalid_index' | 'limit' | 'rejected';
|
|
59
|
+
/** Why one operation (or the batch) was rejected. */
|
|
60
|
+
export interface OverviewOperationIssue {
|
|
61
|
+
/** Zero-based position of the operation in the batch; `null` for the batch. */
|
|
62
|
+
index: number | null;
|
|
63
|
+
op: string | null;
|
|
64
|
+
widgetId: string | null;
|
|
65
|
+
code: OverviewOperationIssueCode;
|
|
66
|
+
/** Developer- and model-facing detail; not localized. */
|
|
67
|
+
message: string;
|
|
68
|
+
/** Option-level problems when `code` is `invalid_options`. */
|
|
69
|
+
options?: WidgetOptionIssue[];
|
|
70
|
+
}
|
|
71
|
+
/** What one applied operation did. */
|
|
72
|
+
export interface OverviewOperationResult {
|
|
73
|
+
index: number;
|
|
74
|
+
op: OverviewOperationKind;
|
|
75
|
+
/** The widget it touched (the new id for an `add`). */
|
|
76
|
+
id: string;
|
|
77
|
+
}
|
|
78
|
+
export type OverviewPlan = {
|
|
79
|
+
ok: true;
|
|
80
|
+
/** The canonical override to persist (`null` = back to defaults). */
|
|
81
|
+
override: OverviewOverride | null;
|
|
82
|
+
/** The document the override resolves to. */
|
|
83
|
+
document: OverviewDocument;
|
|
84
|
+
results: OverviewOperationResult[];
|
|
85
|
+
/** True when the batch changes nothing. */
|
|
86
|
+
unchanged: boolean;
|
|
87
|
+
} | {
|
|
88
|
+
ok: false;
|
|
89
|
+
issues: OverviewOperationIssue[];
|
|
90
|
+
};
|
|
91
|
+
export interface PlanOverviewOperationsInput {
|
|
92
|
+
definition: OverviewDefinition;
|
|
93
|
+
registry: WidgetRegistry;
|
|
94
|
+
/** The current override (untrusted JSON; `null` for none). */
|
|
95
|
+
override: unknown;
|
|
96
|
+
/** The operations (untrusted JSON from a model). */
|
|
97
|
+
operations: unknown;
|
|
98
|
+
/** Batch cap (default {@link OVERVIEW_MAX_OPERATIONS}). */
|
|
99
|
+
maxOperations?: number;
|
|
100
|
+
}
|
|
101
|
+
/** Widget types an overview allows, in registration order. */
|
|
102
|
+
export declare function allowedWidgetTypes(definition: OverviewDefinition, registry: WidgetRegistry): RegisteredWidget[];
|
|
103
|
+
/**
|
|
104
|
+
* Plan a batch of operations against an overview. Total: never throws, never
|
|
105
|
+
* mutates its input. On success, persist (or `controller.restore`) the
|
|
106
|
+
* returned `override`; on failure nothing may be applied.
|
|
107
|
+
*/
|
|
108
|
+
export declare function planOverviewOperations(input: PlanOverviewOperationsInput): OverviewPlan;
|
|
109
|
+
/** One option field, as a caller that builds operations reads it. */
|
|
110
|
+
export interface OverviewOptionDescription {
|
|
111
|
+
key: string;
|
|
112
|
+
type: WidgetOptionField['type'];
|
|
113
|
+
label: string;
|
|
114
|
+
help?: string;
|
|
115
|
+
required?: boolean;
|
|
116
|
+
default?: OverviewOptionValue;
|
|
117
|
+
min?: number;
|
|
118
|
+
max?: number;
|
|
119
|
+
maxLength?: number;
|
|
120
|
+
/** `enum`: the closed set of values. */
|
|
121
|
+
choices?: string[];
|
|
122
|
+
/** `model`: the models this page allows (absent = any model name). */
|
|
123
|
+
models?: string[];
|
|
124
|
+
}
|
|
125
|
+
/** A widget type the page allows. */
|
|
126
|
+
export interface OverviewWidgetTypeDescription {
|
|
127
|
+
type: string;
|
|
128
|
+
title: string;
|
|
129
|
+
description?: string;
|
|
130
|
+
version: number;
|
|
131
|
+
span: {
|
|
132
|
+
default: number;
|
|
133
|
+
min: number;
|
|
134
|
+
max: number;
|
|
135
|
+
};
|
|
136
|
+
options: OverviewOptionDescription[];
|
|
137
|
+
}
|
|
138
|
+
/** What an overview allows and what it shows now. JSON. */
|
|
139
|
+
export interface OverviewDescription {
|
|
140
|
+
id: string;
|
|
141
|
+
canCustomize: boolean;
|
|
142
|
+
customized: boolean;
|
|
143
|
+
maxWidgets: number;
|
|
144
|
+
maxOperations: number;
|
|
145
|
+
widgetTypes: OverviewWidgetTypeDescription[];
|
|
146
|
+
/** The current arrangement, in display order. */
|
|
147
|
+
widgets: Array<OverviewWidget & {
|
|
148
|
+
index: number;
|
|
149
|
+
title: string;
|
|
150
|
+
}>;
|
|
151
|
+
}
|
|
152
|
+
export interface DescribeOverviewInput {
|
|
153
|
+
definition: OverviewDefinition;
|
|
154
|
+
registry: WidgetRegistry;
|
|
155
|
+
override: unknown;
|
|
156
|
+
canCustomize: boolean;
|
|
157
|
+
/** Turns titles, labels and help that are i18n keys into text. */
|
|
158
|
+
translate?: (key: string) => string;
|
|
159
|
+
maxOperations?: number;
|
|
160
|
+
}
|
|
161
|
+
/** Describe an overview for a caller that builds operations (an assistant). */
|
|
162
|
+
export declare function describeOverview(input: DescribeOverviewInput): OverviewDescription;
|
|
163
|
+
/**
|
|
164
|
+
* JSON schema of one operation, for a tool's `inputSchema` / `parameters`.
|
|
165
|
+
* Option values are JSON primitives; the per-type fields come from
|
|
166
|
+
* {@link describeOverview}.
|
|
167
|
+
*/
|
|
168
|
+
export declare const OVERVIEW_OPERATION_SCHEMA: Record<string, unknown>;
|
|
169
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../../src/components/overview/operations.ts"],"names":[],"mappings":"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"}
|