lastriko 0.1.4 → 0.1.7

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 (54) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/integration/ws-flow.integration.test.js +38 -140
  3. package/dist/__tests__/integration/ws-flow.integration.test.js.map +1 -1
  4. package/dist/client/events.js +91 -63
  5. package/dist/client/events.js.map +1 -1
  6. package/dist/client/swap.d.ts +14 -1
  7. package/dist/client/swap.js +185 -7
  8. package/dist/client/swap.js.map +1 -1
  9. package/dist/client/ws.d.ts +1 -0
  10. package/dist/client/ws.js +127 -40
  11. package/dist/client/ws.js.map +1 -1
  12. package/dist/client/ws.test.js +5 -309
  13. package/dist/client/ws.test.js.map +1 -1
  14. package/dist/components/context.d.ts +13 -1
  15. package/dist/components/context.js +312 -1
  16. package/dist/components/context.js.map +1 -1
  17. package/dist/components/context.test.js +73 -116
  18. package/dist/components/context.test.js.map +1 -1
  19. package/dist/components/registry.d.ts +2 -2
  20. package/dist/components/registry.js +52 -4
  21. package/dist/components/registry.js.map +1 -1
  22. package/dist/components/types.d.ts +175 -3
  23. package/dist/engine/executor.js +11 -0
  24. package/dist/engine/executor.js.map +1 -1
  25. package/dist/engine/executor.test.js +19 -10
  26. package/dist/engine/executor.test.js.map +1 -1
  27. package/dist/engine/messages.d.ts +9 -1
  28. package/dist/engine/messages.js.map +1 -1
  29. package/dist/engine/messages.test.d.ts +1 -0
  30. package/dist/engine/messages.test.js +39 -0
  31. package/dist/engine/messages.test.js.map +1 -0
  32. package/dist/engine/renderer.js +211 -7
  33. package/dist/engine/renderer.js.map +1 -1
  34. package/dist/engine/renderer.test.js +218 -234
  35. package/dist/engine/renderer.test.js.map +1 -1
  36. package/dist/engine/server.d.ts +1 -0
  37. package/dist/engine/server.js +41 -5
  38. package/dist/engine/server.js.map +1 -1
  39. package/dist/engine/server.test.js +62 -4
  40. package/dist/engine/server.test.js.map +1 -1
  41. package/dist/engine/watcher.d.ts +17 -1
  42. package/dist/engine/watcher.js +42 -5
  43. package/dist/engine/watcher.js.map +1 -1
  44. package/dist/engine/watcher.test.d.ts +1 -0
  45. package/dist/engine/watcher.test.js +62 -0
  46. package/dist/engine/watcher.test.js.map +1 -0
  47. package/dist/engine/websocket.hub.test.js +24 -0
  48. package/dist/engine/websocket.hub.test.js.map +1 -1
  49. package/dist/engine/websocket.js +0 -1
  50. package/dist/engine/websocket.js.map +1 -1
  51. package/dist/index.d.ts +3 -1
  52. package/dist/index.js +1 -0
  53. package/dist/index.js.map +1 -1
  54. package/package.json +2 -1
@@ -1,130 +1,87 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { UIContext } from './context';
3
3
  import { createConnectionScope } from './registry';
4
- describe('uiContext', () => {
5
- it('creates stable ids per component type', () => {
6
- const scope = createConnectionScope('c1');
4
+ describe('uiContext Phase 3', () => {
5
+ it('creates and updates phase 3 input handles', () => {
6
+ const scope = createConnectionScope('p3-ctx-inputs');
7
7
  const ui = new UIContext(scope);
8
- const text1 = ui.text('hello');
9
- const text2 = ui.text('world');
10
- const button = ui.button('Run', () => { });
11
- const input = ui.textInput('Name');
12
- expect(text1.id).toBe('text-1');
13
- expect(text2.id).toBe('text-2');
14
- expect(button.id).toBe('button-1');
15
- expect(input.id).toBe('textInput-1');
8
+ const multi = ui.multiSelect('Tags', ['a', 'b', 'c'], { defaults: ['a', 'c'], maxSelections: 2 });
9
+ const color = ui.colorPicker('Color', { default: '#112233' });
10
+ const date = ui.dateInput('Date', { default: '2026-04-08' });
11
+ expect(multi.value).toEqual(['a', 'c']);
12
+ expect(color.value).toBe('#112233');
13
+ expect(date.value).toBe('2026-04-08');
14
+ multi.update({ value: ['b', 'c', 'a'] });
15
+ color.update({ value: '#abcdef' });
16
+ date.update({ value: '2026-05-01' });
17
+ expect(multi.value).toEqual(['b', 'c']);
18
+ expect(color.value).toBe('#abcdef');
19
+ expect(date.value).toBe('2026-05-01');
16
20
  });
17
- it('input change updates value atom and emits FRAGMENT', () => {
18
- const scope = createConnectionScope('c2');
21
+ it('creates advanced passive components', () => {
22
+ const scope = createConnectionScope('p3-ctx-passive');
19
23
  const ui = new UIContext(scope);
20
- const slider = ui.slider('Temperature', { min: 0, max: 2, default: 0.7 });
21
- slider.update({ value: 1.2 });
22
- expect(slider.value).toBe(1.2);
23
- expect(scope.outbox).toHaveLength(1);
24
- expect(scope.outbox[0]?.type).toBe('FRAGMENT');
24
+ ui.video('https://example.com/a.mp4', { src: 'https://example.com/a.mp4', autoplay: true });
25
+ ui.audio('https://example.com/a.mp3', { src: 'https://example.com/a.mp3', label: 'Audio demo' });
26
+ ui.diff('a\nb', 'a\nc');
27
+ ui.accordion([{ label: 'S1', defaultOpen: true, content: (s) => s.text('one') }]);
28
+ ui.filmStrip(['https://example.com/1.png']);
29
+ ui.beforeAfter('https://example.com/b.png', 'https://example.com/a.png');
30
+ const types = new Set(scope.listHandles().map((h) => h.type));
31
+ expect(types.has('video')).toBe(true);
32
+ expect(types.has('audio')).toBe(true);
33
+ expect(types.has('diff')).toBe(true);
34
+ expect(types.has('accordion')).toBe(true);
35
+ expect(types.has('filmStrip')).toBe(true);
36
+ expect(types.has('beforeAfter')).toBe(true);
25
37
  });
26
- it('table handles support prepend, row.update, remove', () => {
27
- const scope = createConnectionScope('c3');
38
+ it('supports fullscreen and modelCompare state updates', () => {
39
+ const scope = createConnectionScope('p3-ctx-stateful');
28
40
  const ui = new UIContext(scope);
29
- const table = ui.table([], { columns: ['name', 'status'] });
30
- const row = table.prepend({ name: 'exp-1', status: 'queued' });
31
- expect(table.rowCount).toBe(1);
32
- row.update({ status: 'done' });
33
- expect(table.props.rows[0]?.data.status).toBe('done');
34
- row.remove();
35
- expect(table.rowCount).toBe(0);
36
- });
37
- it('streamText emits STREAM_CHUNK sequence and done marker', () => {
38
- const scope = createConnectionScope('c4');
39
- const ui = new UIContext(scope);
40
- const stream = ui.streamText({ format: 'plain' });
41
- stream.append('Hello');
42
- stream.append(' world');
43
- stream.done();
44
- const chunks = scope.outbox.filter((message) => message.type === 'STREAM_CHUNK');
45
- expect(chunks).toHaveLength(3);
46
- expect((chunks[0]?.payload).chunk).toBe('Hello');
47
- expect((chunks[1]?.payload).chunk).toBe(' world');
48
- expect((chunks[2]?.payload).done).toBe(true);
49
- });
50
- it('chatUI stores and clears connection-scoped message history', () => {
51
- const scope = createConnectionScope('c5');
52
- const ui = new UIContext(scope);
53
- const chat = ui.chatUI();
54
- chat.addMessage('user', 'hi');
55
- chat.addMessage('assistant', 'hello');
56
- expect(chat.value).toHaveLength(2);
57
- expect(chat.lastMessage?.content).toBe('hello');
58
- chat.clear();
59
- expect(chat.value).toHaveLength(0);
60
- });
61
- it('promptEditor interpolate replaces template variables', () => {
62
- const scope = createConnectionScope('c6');
63
- const ui = new UIContext(scope);
64
- const prompt = ui.promptEditor({ default: 'Write a {{tone}} note about {{topic}}.' });
65
- const finalText = prompt.interpolate({ tone: 'formal', topic: 'safety' });
66
- expect(finalText).toBe('Write a formal note about safety.');
67
- });
68
- it('tabs handle supports setActive for enabled tabs only', () => {
69
- const scope = createConnectionScope('c7');
70
- const ui = new UIContext(scope);
71
- const tabs = ui.tabs([
72
- { label: 'One', content: (t) => t.text('first') },
73
- { label: 'Two', content: (t) => t.text('second'), disabled: true },
74
- ], { defaultTab: 'One' });
75
- expect(tabs.value).toBe('One');
76
- tabs.setActive('Two');
77
- expect(tabs.value).toBe('One');
78
- tabs.setActive('One');
79
- expect(tabs.value).toBe('One');
80
- expect(scope.outbox.filter((message) => message.type === 'FRAGMENT').length).toBeGreaterThan(0);
41
+ const fullscreen = ui.fullscreen((f) => {
42
+ f.text('full');
43
+ }, { trigger: 'manual' });
44
+ const model = ui.modelCompare([{ label: 'M1', model: 'x', provider: 'p' }], { prompt: 'hello' });
45
+ expect(model.value.results.M1).toBe('');
46
+ fullscreen.open();
47
+ expect(fullscreen.value).toBe(true);
48
+ fullscreen.close();
49
+ expect(fullscreen.value).toBe(false);
50
+ model.update({
51
+ value: {
52
+ results: { M1: 'ok' },
53
+ isStreaming: { M1: false },
54
+ errors: { M1: null },
55
+ latencies: { M1: 12 },
56
+ },
57
+ });
58
+ expect(model.results.M1).toBe('ok');
81
59
  });
82
- it('supports shell/grid helper methods and disconnect hook', () => {
83
- const scope = createConnectionScope('c8');
60
+ it('parameterPanel maps schema to child controls', () => {
61
+ const scope = createConnectionScope('p3-ctx-params');
84
62
  const ui = new UIContext(scope);
85
- let disconnected = false;
86
- ui.onDisconnect(() => {
87
- disconnected = true;
88
- });
89
- ui.shell({
90
- header: (h) => {
91
- h.text('header');
92
- },
93
- sidebar: (s) => {
94
- s.text('sidebar');
63
+ const params = ui.parameterPanel({
64
+ temperature: { type: 'number', min: 0, max: 2, default: 0.7 },
65
+ stream: { type: 'boolean', default: true },
66
+ model: { type: 'select', options: ['a', 'b'], default: 'a' },
67
+ note: { type: 'string', default: 'x' },
68
+ }, { title: 'Params', collapsible: true });
69
+ expect(params.value.temperature).toBe(0.7);
70
+ expect(params.value.stream).toBe(true);
71
+ expect(params.value.model).toBe('a');
72
+ expect(params.value.note).toBe('x');
73
+ params.update({
74
+ value: {
75
+ temperature: 1.1,
76
+ stream: false,
77
+ model: 'b',
78
+ note: 'updated',
95
79
  },
96
- main: (m) => {
97
- m.grid([
98
- (g1) => {
99
- g1.code('const x = 1', { lang: 'ts' });
100
- g1.json({ ok: true }, { label: 'payload' });
101
- },
102
- (g2) => {
103
- g2.alert('info');
104
- g2.loading('loading');
105
- },
106
- ], { cols: 2, gap: 8 });
107
- m.card('card', (c) => {
108
- c.divider({ label: 'sep' });
109
- c.spacer('sm');
110
- });
111
- },
112
- footer: (f) => {
113
- f.text('footer');
114
- },
115
- }, { sidebarPosition: 'right', sidebarWidth: '300px' });
116
- const handles = scope.listHandles();
117
- expect(handles.some((h) => h.type === 'shell')).toBe(true);
118
- expect(handles.some((h) => h.type === 'grid')).toBe(true);
119
- expect(handles.some((h) => h.type === 'code')).toBe(true);
120
- expect(handles.some((h) => h.type === 'json')).toBe(true);
121
- expect(handles.some((h) => h.type === 'card')).toBe(true);
122
- expect(handles.some((h) => h.type === 'divider')).toBe(true);
123
- expect(handles.some((h) => h.type === 'spacer')).toBe(true);
124
- expect(handles.some((h) => h.type === 'alert')).toBe(true);
125
- expect(handles.some((h) => h.type === 'loading')).toBe(true);
126
- scope.destroy();
127
- expect(disconnected).toBe(true);
80
+ });
81
+ expect(params.value.temperature).toBe(1.1);
82
+ expect(params.value.stream).toBe(false);
83
+ expect(params.value.model).toBe('b');
84
+ expect(params.value.note).toBe('updated');
128
85
  });
129
86
  });
130
87
  //# sourceMappingURL=context.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.test.js","sourceRoot":"","sources":["../../src/components/context.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.test.js","sourceRoot":"","sources":["../../src/components/context.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import type { ConnectionScope } from './types';
2
- export declare function createConnectionScope(id?: string, transport?: ConnectionScope['connection']): ConnectionScope;
1
+ import type { ConnectionScope, ServerConnection } from './types';
2
+ export declare function createConnectionScope(id?: string, transport?: ServerConnection): ConnectionScope;
@@ -10,6 +10,45 @@ export function createConnectionScope(id, transport = { send: () => { } }) {
10
10
  const roots = [];
11
11
  const cleanupFns = [];
12
12
  const outbox = [];
13
+ const batch = { timer: null, messages: [] };
14
+ const sendNow = (message) => {
15
+ outbox.push(message);
16
+ transport.send(message);
17
+ };
18
+ const flushBatch = () => {
19
+ if (batch.messages.length === 0) {
20
+ batch.timer = null;
21
+ return;
22
+ }
23
+ const payload = { messages: batch.messages.splice(0) };
24
+ batch.timer = null;
25
+ sendNow({ type: 'BATCH', payload });
26
+ };
27
+ const scheduleBatchFlush = () => {
28
+ if (batch.timer) {
29
+ return;
30
+ }
31
+ batch.timer = setTimeout(() => {
32
+ flushBatch();
33
+ }, 16);
34
+ };
35
+ const enqueueBatchEntry = (entry) => {
36
+ const isFragment = entry.type === 'FRAGMENT';
37
+ if (isFragment) {
38
+ const fragmentId = entry.payload.id;
39
+ const existing = batch.messages.findIndex((item) => item.type === 'FRAGMENT' && item.payload.id === fragmentId);
40
+ if (existing >= 0) {
41
+ batch.messages[existing] = entry;
42
+ }
43
+ else {
44
+ batch.messages.push(entry);
45
+ }
46
+ scheduleBatchFlush();
47
+ return;
48
+ }
49
+ batch.messages.push(entry);
50
+ scheduleBatchFlush();
51
+ };
13
52
  return {
14
53
  id: scopeId,
15
54
  connection: transport,
@@ -52,19 +91,28 @@ export function createConnectionScope(id, transport = { send: () => { } }) {
52
91
  }
53
92
  },
54
93
  send(message) {
55
- outbox.push(message);
56
- transport.send(message);
94
+ if (message.type === 'FRAGMENT' || message.type === 'STREAM_CHUNK') {
95
+ enqueueBatchEntry(message);
96
+ return;
97
+ }
98
+ sendNow(message);
57
99
  },
58
100
  pushFragment(handle) {
59
- this.send({
101
+ const fragment = {
60
102
  type: 'FRAGMENT',
61
103
  payload: { id: handle.id, html: renderComponent(handle) },
62
- });
104
+ };
105
+ this.send(fragment);
63
106
  },
64
107
  onCleanup(fn) {
65
108
  cleanupFns.push(fn);
66
109
  },
67
110
  clearTransientState() {
111
+ if (batch.timer) {
112
+ clearTimeout(batch.timer);
113
+ batch.timer = null;
114
+ }
115
+ batch.messages.length = 0;
68
116
  atoms.clear();
69
117
  handles.clear();
70
118
  counters.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { WritableAtom } from 'nanostores';
2
2
  import type { ServerToClientMessage, ThemeMode } from '../engine/messages';
3
- export type ComponentType = 'text' | 'button' | 'textInput' | 'numberInput' | 'slider' | 'toggle' | 'select' | 'fileUpload' | 'markdown' | 'image' | 'imageGrid' | 'code' | 'json' | 'table' | 'metric' | 'progress' | 'shell' | 'grid' | 'tabs' | 'card' | 'divider' | 'spacer' | 'alert' | 'loading' | 'streamText' | 'chatUI' | 'promptEditor';
3
+ export type ComponentType = 'text' | 'button' | 'textInput' | 'numberInput' | 'slider' | 'toggle' | 'select' | 'multiSelect' | 'colorPicker' | 'dateInput' | 'fileUpload' | 'markdown' | 'image' | 'imageGrid' | 'video' | 'audio' | 'code' | 'json' | 'diff' | 'table' | 'metric' | 'progress' | 'shell' | 'grid' | 'tabs' | 'accordion' | 'fullscreen' | 'card' | 'divider' | 'spacer' | 'alert' | 'loading' | 'streamText' | 'chatUI' | 'promptEditor' | 'modelCompare' | 'parameterPanel' | 'filmStrip' | 'beforeAfter';
4
4
  export type TableRow = Record<string, unknown>;
5
5
  export interface ComponentHandle<TProps, TValue = void> {
6
6
  readonly id: string;
@@ -74,12 +74,32 @@ export interface FileUploadOpts {
74
74
  helperText?: string;
75
75
  dragDrop?: boolean;
76
76
  }
77
+ export interface MultiSelectOpts {
78
+ defaults?: string[];
79
+ disabled?: boolean;
80
+ helperText?: string;
81
+ maxSelections?: number;
82
+ }
83
+ export interface ColorPickerOpts {
84
+ default?: string;
85
+ format?: 'hex' | 'rgb' | 'hsl';
86
+ disabled?: boolean;
87
+ helperText?: string;
88
+ swatches?: string[];
89
+ }
90
+ export interface DateInputOpts {
91
+ default?: string;
92
+ min?: string;
93
+ max?: string;
94
+ disabled?: boolean;
95
+ helperText?: string;
96
+ type?: 'date' | 'datetime-local' | 'time' | 'month';
97
+ }
77
98
  export interface UploadedFile {
78
99
  name: string;
79
100
  path: string;
80
101
  size: number;
81
102
  type: string;
82
- lastModified: number;
83
103
  }
84
104
  export interface TextProps {
85
105
  content: string;
@@ -118,6 +138,23 @@ export interface FileUploadProps extends FileUploadOpts {
118
138
  label: string;
119
139
  value: UploadedFile | UploadedFile[] | null;
120
140
  }
141
+ export interface MultiSelectProps extends MultiSelectOpts {
142
+ label: string;
143
+ options: Array<{
144
+ label: string;
145
+ value: string;
146
+ disabled?: boolean;
147
+ }>;
148
+ value: string[];
149
+ }
150
+ export interface ColorPickerProps extends ColorPickerOpts {
151
+ label: string;
152
+ value: string;
153
+ }
154
+ export interface DateInputProps extends DateInputOpts {
155
+ label: string;
156
+ value: string;
157
+ }
121
158
  export interface MarkdownProps {
122
159
  content: string;
123
160
  }
@@ -138,6 +175,23 @@ export interface ImageGridProps {
138
175
  gap?: number;
139
176
  minWidth?: number;
140
177
  }
178
+ export interface VideoProps {
179
+ src: string;
180
+ controls?: boolean;
181
+ autoplay?: boolean;
182
+ muted?: boolean;
183
+ loop?: boolean;
184
+ poster?: string;
185
+ width?: string;
186
+ caption?: string;
187
+ }
188
+ export interface AudioProps {
189
+ src: string;
190
+ controls?: boolean;
191
+ autoplay?: boolean;
192
+ loop?: boolean;
193
+ label?: string;
194
+ }
141
195
  export interface CodeProps {
142
196
  content: string;
143
197
  lang?: string;
@@ -146,6 +200,15 @@ export interface JsonProps {
146
200
  label?: string;
147
201
  data: unknown;
148
202
  }
203
+ export interface DiffProps {
204
+ before: string;
205
+ after: string;
206
+ mode?: 'split' | 'unified';
207
+ beforeLabel?: string;
208
+ afterLabel?: string;
209
+ lang?: string;
210
+ context?: number;
211
+ }
149
212
  export interface TableProps {
150
213
  columns: string[];
151
214
  rows: Array<{
@@ -189,6 +252,19 @@ export interface GridOpts {
189
252
  export interface TabsOpts {
190
253
  defaultTab?: string;
191
254
  }
255
+ export interface AccordionSection {
256
+ label: string;
257
+ content: (ctx: UIContext) => void;
258
+ defaultOpen?: boolean;
259
+ }
260
+ export interface AccordionOpts {
261
+ allowMultiple?: boolean;
262
+ }
263
+ export interface FullscreenOpts {
264
+ trigger?: 'button' | 'manual';
265
+ label?: string;
266
+ defaultOpen?: boolean;
267
+ }
192
268
  export interface ToastOpts {
193
269
  type?: 'info' | 'success' | 'warning' | 'error';
194
270
  duration?: number;
@@ -224,6 +300,74 @@ export interface ChatUIOptions {
224
300
  export interface ChatUIProps extends ChatUIOptions {
225
301
  messages: ChatMessage[];
226
302
  }
303
+ export interface ModelSpec {
304
+ label: string;
305
+ model: string;
306
+ provider: string;
307
+ color?: string;
308
+ }
309
+ export interface ModelCompareOpts {
310
+ prompt: string;
311
+ systemPrompt?: string;
312
+ temperature?: number;
313
+ maxTokens?: number;
314
+ streaming?: boolean;
315
+ }
316
+ export interface ModelCompareResults {
317
+ results: Record<string, string>;
318
+ isStreaming: Record<string, boolean>;
319
+ errors: Record<string, string | null>;
320
+ latencies: Record<string, number>;
321
+ }
322
+ export interface ModelCompareProps extends ModelCompareOpts {
323
+ models: ModelSpec[];
324
+ value: ModelCompareResults;
325
+ }
326
+ export type ParameterSchema = Record<string, ParameterDef>;
327
+ export interface ParameterDef {
328
+ type: 'number' | 'string' | 'boolean' | 'select';
329
+ label?: string;
330
+ default?: unknown;
331
+ min?: number;
332
+ max?: number;
333
+ step?: number;
334
+ options?: string[];
335
+ description?: string;
336
+ }
337
+ export interface ParameterPanelOpts {
338
+ title?: string;
339
+ collapsible?: boolean;
340
+ }
341
+ export interface ParameterPanelProps extends ParameterPanelOpts {
342
+ schema: ParameterSchema;
343
+ ids: string[];
344
+ value: Record<string, unknown>;
345
+ }
346
+ export interface FilmStripItem {
347
+ src: string;
348
+ alt?: string;
349
+ caption?: string;
350
+ thumbnail?: string;
351
+ }
352
+ export interface FilmStripOpts {
353
+ height?: number;
354
+ zoom?: boolean;
355
+ showCaptions?: boolean;
356
+ selectedIndex?: number;
357
+ }
358
+ export interface FilmStripProps extends FilmStripOpts {
359
+ images: FilmStripItem[];
360
+ }
361
+ export interface BeforeAfterOpts {
362
+ beforeLabel?: string;
363
+ afterLabel?: string;
364
+ initialPosition?: number;
365
+ orientation?: 'horizontal' | 'vertical';
366
+ }
367
+ export interface BeforeAfterProps extends BeforeAfterOpts {
368
+ before: string;
369
+ after: string;
370
+ }
227
371
  export interface PromptEditorOpts extends TextInputOpts {
228
372
  label?: string;
229
373
  variables?: string[];
@@ -246,6 +390,9 @@ export type SliderHandle = InputHandle<number, SliderProps>;
246
390
  export type ToggleHandle = InputHandle<boolean, ToggleProps>;
247
391
  export type SelectHandle = InputHandle<string, SelectProps>;
248
392
  export type FileUploadHandle = InputHandle<UploadedFile | UploadedFile[] | null, FileUploadProps>;
393
+ export type MultiSelectHandle = InputHandle<string[], MultiSelectProps>;
394
+ export type ColorPickerHandle = InputHandle<string, ColorPickerProps>;
395
+ export type DateInputHandle = InputHandle<string, DateInputProps>;
249
396
  export interface TableRowHandle {
250
397
  id: string;
251
398
  update(data: Partial<TableRow>): void;
@@ -271,6 +418,11 @@ export interface TabsHandle extends ComponentHandle<Record<string, unknown>, str
271
418
  readonly type: 'tabs';
272
419
  setActive(label: string): void;
273
420
  }
421
+ export interface FullscreenHandle extends ComponentHandle<Record<string, unknown>, boolean> {
422
+ readonly type: 'fullscreen';
423
+ open(): void;
424
+ close(): void;
425
+ }
274
426
  export interface StreamHandle extends Omit<ComponentHandle<StreamTextProps, string>, 'update'> {
275
427
  readonly type: 'streamText';
276
428
  readonly text: string;
@@ -291,7 +443,15 @@ export interface PromptEditorHandle extends InputHandle<string, PromptEditorProp
291
443
  readonly type: 'promptEditor';
292
444
  interpolate(vars: Record<string, string>): string;
293
445
  }
294
- export type AnyComponentHandle = TextHandle | ButtonHandle | TextInputHandle | NumberInputHandle | SliderHandle | ToggleHandle | SelectHandle | FileUploadHandle | TableHandle | MetricHandle | ProgressHandle | TabsHandle | StreamHandle | ChatHandle | PromptEditorHandle | ComponentHandle<MarkdownProps> | ComponentHandle<ImageProps> | ComponentHandle<ImageGridProps> | ComponentHandle<CodeProps> | ComponentHandle<JsonProps> | ComponentHandle<Record<string, unknown>, unknown>;
446
+ export interface ModelCompareHandle extends ComponentHandle<ModelCompareProps, ModelCompareResults> {
447
+ readonly type: 'modelCompare';
448
+ readonly results: Record<string, string>;
449
+ readonly isStreaming: Record<string, boolean>;
450
+ readonly errors: Record<string, string | null>;
451
+ readonly latencies: Record<string, number>;
452
+ }
453
+ export type ParameterPanelHandle = InputHandle<Record<string, unknown>, ParameterPanelProps>;
454
+ export type AnyComponentHandle = TextHandle | ButtonHandle | TextInputHandle | NumberInputHandle | SliderHandle | ToggleHandle | SelectHandle | MultiSelectHandle | ColorPickerHandle | DateInputHandle | FileUploadHandle | TableHandle | MetricHandle | ProgressHandle | TabsHandle | FullscreenHandle | StreamHandle | ChatHandle | PromptEditorHandle | ModelCompareHandle | ParameterPanelHandle | ComponentHandle<MarkdownProps> | ComponentHandle<ImageProps> | ComponentHandle<ImageGridProps> | ComponentHandle<VideoProps> | ComponentHandle<AudioProps> | ComponentHandle<CodeProps> | ComponentHandle<JsonProps> | ComponentHandle<DiffProps> | ComponentHandle<FilmStripProps> | ComponentHandle<BeforeAfterProps> | ComponentHandle<Record<string, unknown>, unknown>;
295
455
  export interface RenderNode {
296
456
  id: string;
297
457
  }
@@ -362,10 +522,18 @@ export interface UIContext {
362
522
  slider(label: string, opts: SliderOpts): SliderHandle;
363
523
  toggle(label: string, opts?: ToggleOpts): ToggleHandle;
364
524
  select(label: string, options: SelectOption[], opts?: SelectOpts): SelectHandle;
525
+ multiSelect(label: string, options: SelectOption[], opts?: MultiSelectOpts): MultiSelectHandle;
526
+ colorPicker(label: string, opts?: ColorPickerOpts): ColorPickerHandle;
527
+ dateInput(label: string, opts?: DateInputOpts): DateInputHandle;
365
528
  fileUpload(label: string, opts?: FileUploadOpts): FileUploadHandle;
529
+ video(src: string, opts?: VideoProps): void;
530
+ audio(src: string, opts?: AudioProps): void;
531
+ diff(before: string, after: string, opts?: Partial<DiffProps>): void;
366
532
  shell(regions: ShellRegions, opts?: ShellOpts): void;
367
533
  grid(areas: Array<(ctx: UIContext) => void>, opts?: GridOpts): void;
368
534
  tabs(tabs: TabDef[], opts?: TabsOpts): TabsHandle;
535
+ accordion(sections: AccordionSection[], opts?: AccordionOpts): void;
536
+ fullscreen(content: (ctx: UIContext) => void, opts?: FullscreenOpts): FullscreenHandle;
369
537
  card(titleOrContent: string | ((ctx: UIContext) => void), contentOrNothing?: (ctx: UIContext) => void): void;
370
538
  divider(opts?: {
371
539
  label?: string;
@@ -377,6 +545,10 @@ export interface UIContext {
377
545
  streamText(opts?: StreamTextOpts): StreamHandle;
378
546
  chatUI(opts?: ChatUIOptions): ChatHandle;
379
547
  promptEditor(opts?: PromptEditorOpts): PromptEditorHandle;
548
+ modelCompare(models: ModelSpec[], opts: ModelCompareOpts): ModelCompareHandle;
549
+ parameterPanel(schema: ParameterSchema, opts?: ParameterPanelOpts): ParameterPanelHandle;
550
+ filmStrip(images: Array<string | FilmStripItem>, opts?: FilmStripOpts): void;
551
+ beforeAfter(before: string, after: string, opts?: BeforeAfterOpts): void;
380
552
  onDisconnect(fn: () => void): void;
381
553
  }
382
554
  export interface ShellRegions {
@@ -25,6 +25,11 @@ export function handleClientEvent(scope, payload) {
25
25
  handle.update({ value: target });
26
26
  return;
27
27
  }
28
+ if (handle.type === 'parameterPanel') {
29
+ const panel = handle;
30
+ panel.update({});
31
+ return;
32
+ }
28
33
  scope.pushFragment(handle);
29
34
  return;
30
35
  }
@@ -49,6 +54,12 @@ export function handleClientEvent(scope, payload) {
49
54
  });
50
55
  return;
51
56
  }
57
+ if (handle.type === 'fullscreen') {
58
+ const fullscreen = handle;
59
+ const current = fullscreen.value;
60
+ fullscreen.update({ value: !current });
61
+ return;
62
+ }
52
63
  if (handle.type === 'table' && typeof payload.value === 'string') {
53
64
  const tableHandle = handle;
54
65
  const row = tableHandle.props.rows.find((entry) => entry.id === payload.value);