@allternit/ix 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +320 -0
- package/dist/adapters/json-render.d.ts +211 -0
- package/dist/adapters/json-render.d.ts.bak +211 -0
- package/dist/adapters/json-render.d.ts.map +1 -0
- package/dist/adapters/json-render.js +576 -0
- package/dist/adapters/json-render.js.bak +576 -0
- package/dist/adapters/json-render.js.map +1 -0
- package/dist/catalog/registry.d.ts +65 -0
- package/dist/catalog/registry.d.ts.bak +65 -0
- package/dist/catalog/registry.d.ts.map +1 -0
- package/dist/catalog/registry.js +388 -0
- package/dist/catalog/registry.js.bak +388 -0
- package/dist/catalog/registry.js.map +1 -0
- package/dist/collab/capsule-registry.d.ts +114 -0
- package/dist/collab/capsule-registry.d.ts.bak +114 -0
- package/dist/collab/capsule-registry.d.ts.map +1 -0
- package/dist/collab/capsule-registry.js +271 -0
- package/dist/collab/capsule-registry.js.bak +271 -0
- package/dist/collab/capsule-registry.js.map +1 -0
- package/dist/collab/index.d.ts +21 -0
- package/dist/collab/index.d.ts.bak +21 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +32 -0
- package/dist/collab/index.js.bak +32 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/collab/visual-editor.d.ts +199 -0
- package/dist/collab/visual-editor.d.ts.bak +199 -0
- package/dist/collab/visual-editor.d.ts.map +1 -0
- package/dist/collab/visual-editor.js +259 -0
- package/dist/collab/visual-editor.js.bak +259 -0
- package/dist/collab/visual-editor.js.map +1 -0
- package/dist/collab/yjs-adapter.d.ts +95 -0
- package/dist/collab/yjs-adapter.d.ts.bak +95 -0
- package/dist/collab/yjs-adapter.d.ts.map +1 -0
- package/dist/collab/yjs-adapter.js +282 -0
- package/dist/collab/yjs-adapter.js.bak +282 -0
- package/dist/collab/yjs-adapter.js.map +1 -0
- package/dist/collab/yjs-client.d.ts +101 -0
- package/dist/collab/yjs-client.d.ts.bak +101 -0
- package/dist/collab/yjs-client.d.ts.map +1 -0
- package/dist/collab/yjs-client.js +193 -0
- package/dist/collab/yjs-client.js.bak +193 -0
- package/dist/collab/yjs-client.js.map +1 -0
- package/dist/collab/yjs-protocols.d.ts +128 -0
- package/dist/collab/yjs-protocols.d.ts.bak +128 -0
- package/dist/collab/yjs-protocols.d.ts.map +1 -0
- package/dist/collab/yjs-protocols.js +245 -0
- package/dist/collab/yjs-protocols.js.bak +245 -0
- package/dist/collab/yjs-protocols.js.map +1 -0
- package/dist/collab/yjs-types.d.ts +201 -0
- package/dist/collab/yjs-types.d.ts.bak +201 -0
- package/dist/collab/yjs-types.d.ts.map +1 -0
- package/dist/collab/yjs-types.js +45 -0
- package/dist/collab/yjs-types.js.bak +45 -0
- package/dist/collab/yjs-types.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.bak +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.bak +48 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/llm-to-ix.d.ts +249 -0
- package/dist/pipeline/llm-to-ix.d.ts.bak +249 -0
- package/dist/pipeline/llm-to-ix.d.ts.map +1 -0
- package/dist/pipeline/llm-to-ix.js +992 -0
- package/dist/pipeline/llm-to-ix.js.bak +992 -0
- package/dist/pipeline/llm-to-ix.js.map +1 -0
- package/dist/react/index.d.ts +18 -0
- package/dist/react/index.d.ts.bak +18 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +18 -0
- package/dist/react/index.js.bak +18 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/renderer.d.ts +47 -0
- package/dist/react/renderer.d.ts.bak +47 -0
- package/dist/react/renderer.d.ts.map +1 -0
- package/dist/react/renderer.js +420 -0
- package/dist/react/renderer.js.bak +420 -0
- package/dist/react/renderer.js.map +1 -0
- package/dist/renderer/renderer.d.ts +55 -0
- package/dist/renderer/renderer.d.ts.bak +55 -0
- package/dist/renderer/renderer.d.ts.map +1 -0
- package/dist/renderer/renderer.js +232 -0
- package/dist/renderer/renderer.js.bak +232 -0
- package/dist/renderer/renderer.js.map +1 -0
- package/dist/runtime/capsule-runtime.d.ts +227 -0
- package/dist/runtime/capsule-runtime.d.ts.bak +227 -0
- package/dist/runtime/capsule-runtime.d.ts.map +1 -0
- package/dist/runtime/capsule-runtime.js +563 -0
- package/dist/runtime/capsule-runtime.js.bak +563 -0
- package/dist/runtime/capsule-runtime.js.map +1 -0
- package/dist/runtime/policy-gates.d.ts +116 -0
- package/dist/runtime/policy-gates.d.ts.bak +116 -0
- package/dist/runtime/policy-gates.d.ts.map +1 -0
- package/dist/runtime/policy-gates.js +317 -0
- package/dist/runtime/policy-gates.js.bak +317 -0
- package/dist/runtime/policy-gates.js.map +1 -0
- package/dist/schema/ui-ir.d.ts +26 -0
- package/dist/schema/ui-ir.d.ts.bak +26 -0
- package/dist/schema/ui-ir.d.ts.map +1 -0
- package/dist/schema/ui-ir.js +51 -0
- package/dist/schema/ui-ir.js.bak +51 -0
- package/dist/schema/ui-ir.js.map +1 -0
- package/dist/sdk/api.d.ts +101 -0
- package/dist/sdk/api.d.ts.bak +101 -0
- package/dist/sdk/api.d.ts.map +1 -0
- package/dist/sdk/api.js +177 -0
- package/dist/sdk/api.js.bak +177 -0
- package/dist/sdk/api.js.map +1 -0
- package/dist/sdk/index.d.ts +9 -0
- package/dist/sdk/index.d.ts.bak +9 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +10 -0
- package/dist/sdk/index.js.bak +10 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/react.d.ts +63 -0
- package/dist/sdk/react.d.ts.bak +63 -0
- package/dist/sdk/react.d.ts.map +1 -0
- package/dist/sdk/react.js +161 -0
- package/dist/sdk/react.js.bak +161 -0
- package/dist/sdk/react.js.map +1 -0
- package/dist/state/index.d.ts +8 -0
- package/dist/state/index.d.ts.bak +8 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +8 -0
- package/dist/state/index.js.bak +8 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/patch.d.ts +73 -0
- package/dist/state/patch.d.ts.bak +73 -0
- package/dist/state/patch.d.ts.map +1 -0
- package/dist/state/patch.js +437 -0
- package/dist/state/patch.js.bak +437 -0
- package/dist/state/patch.js.map +1 -0
- package/dist/state/store.d.ts +50 -0
- package/dist/state/store.d.ts.bak +50 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +246 -0
- package/dist/state/store.js.bak +246 -0
- package/dist/state/store.js.map +1 -0
- package/dist/svelte/index.d.ts +15 -0
- package/dist/svelte/index.d.ts.bak +15 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +15 -0
- package/dist/svelte/index.js.bak +15 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/svelte/renderer.d.ts +35 -0
- package/dist/svelte/renderer.d.ts.bak +35 -0
- package/dist/svelte/renderer.d.ts.map +1 -0
- package/dist/svelte/renderer.js +317 -0
- package/dist/svelte/renderer.js.bak +317 -0
- package/dist/svelte/renderer.js.map +1 -0
- package/dist/types/index.d.ts +349 -0
- package/dist/types/index.d.ts.bak +349 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +152 -0
- package/dist/types/index.js.bak +152 -0
- package/dist/types/index.js.map +1 -0
- package/dist/vue/index.d.ts +18 -0
- package/dist/vue/index.d.ts.bak +18 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +18 -0
- package/dist/vue/index.js.bak +18 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/vue/renderer.d.ts +46 -0
- package/dist/vue/renderer.d.ts.bak +46 -0
- package/dist/vue/renderer.d.ts.map +1 -0
- package/dist/vue/renderer.js +302 -0
- package/dist/vue/renderer.js.bak +302 -0
- package/dist/vue/renderer.js.map +1 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# @allternit/ix
|
|
2
|
+
|
|
3
|
+
A2R Interface eXecution - Declarative UI generation with Vercel Labs json-render compatibility.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
A2R-IX enables LLM-generated UI through a JSON Intermediate Representation (IR) with full compatibility for Vercel Labs json-render patterns. This allows AI agents to generate user interfaces declaratively, which are then rendered by the platform.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **UI IR Schema**: Structured declarative UI definitions
|
|
12
|
+
- **Component Catalog**: 15 built-in components with semantic versioning
|
|
13
|
+
- **State Store**: Scoped state management with persistence
|
|
14
|
+
- **JSON Patch Engine**: RFC 6902 compliant state synchronization
|
|
15
|
+
- **json-render Adapter**: Bidirectional compatibility with Vercel Labs format
|
|
16
|
+
- **React Renderer**: Full React component rendering
|
|
17
|
+
- **Vue Renderer**: Vue 3 component generation
|
|
18
|
+
- **Svelte Renderer**: Svelte component compilation
|
|
19
|
+
- **IX Capsule Runtime**: Sandboxed execution with P3.9 integration
|
|
20
|
+
- **Policy Gates**: Security controls (rate limiting, sanitization, validation)
|
|
21
|
+
- **LLM-to-IX Pipeline**: Multi-format conversion from LLM outputs
|
|
22
|
+
- **Real-time Collaboration**: Yjs/CRDT integration
|
|
23
|
+
- **Visual Editor**: Fluent API for building UI IR
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @allternit/ix
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Basic React Usage
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { createReactRenderer, createDefaultCatalog, createStateStore } from '@allternit/ix';
|
|
37
|
+
|
|
38
|
+
const renderer = createReactRenderer({
|
|
39
|
+
catalog: createDefaultCatalog(),
|
|
40
|
+
stateStore: createStateStore(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const ui = {
|
|
44
|
+
version: '1.0.0',
|
|
45
|
+
components: [
|
|
46
|
+
{
|
|
47
|
+
id: 'header',
|
|
48
|
+
type: 'Heading',
|
|
49
|
+
props: { children: 'Hello World', level: 1 },
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'input',
|
|
53
|
+
type: 'Input',
|
|
54
|
+
props: { placeholder: 'Enter name' },
|
|
55
|
+
bindings: [
|
|
56
|
+
{ prop: 'value', statePath: 'name', direction: 'two-way' },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
state: {
|
|
61
|
+
variables: [
|
|
62
|
+
{ path: 'name', type: 'string', default: '' },
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
actions: [],
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Render in React
|
|
69
|
+
function App() {
|
|
70
|
+
return <renderer.UIRoot root={ui} />;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Vue Renderer
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { createVueRenderer, compileToVue } from '@allternit/ix/vue';
|
|
78
|
+
|
|
79
|
+
// Generate Vue component definition
|
|
80
|
+
const vueComponent = compileToVue(uiDefinition);
|
|
81
|
+
|
|
82
|
+
// Use with Vue compiler or runtime
|
|
83
|
+
const { template, setup } = vueComponent;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Svelte Renderer
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { compileToSvelte } from '@allternit/ix/svelte';
|
|
90
|
+
|
|
91
|
+
// Generate Svelte component code
|
|
92
|
+
const svelteCode = compileToSvelte(uiDefinition);
|
|
93
|
+
// Use with Svelte compiler
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Visual Editor
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { ui } from '@allternit/ix';
|
|
100
|
+
|
|
101
|
+
// Build UI programmatically
|
|
102
|
+
const myUI = ui.create()
|
|
103
|
+
.state('count', 'number', 0)
|
|
104
|
+
.add(
|
|
105
|
+
ui.components.layout.Box({ padding: 4 })
|
|
106
|
+
.child(ui.components.typography.Heading('Counter', 1))
|
|
107
|
+
.child(
|
|
108
|
+
ui.components.input.Button('Increment')
|
|
109
|
+
.on('onClick', 'increment')
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
.build();
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Real-time Collaboration
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { createYjsAdapter } from '@allternit/ix/collab';
|
|
119
|
+
import * as Y from 'yjs';
|
|
120
|
+
import { WebsocketProvider } from 'y-websocket';
|
|
121
|
+
|
|
122
|
+
const doc = new Y.Doc();
|
|
123
|
+
const provider = new WebsocketProvider('ws://localhost:1234', 'room', doc);
|
|
124
|
+
|
|
125
|
+
const adapter = createYjsAdapter({
|
|
126
|
+
doc,
|
|
127
|
+
provider,
|
|
128
|
+
userId: 'user-1',
|
|
129
|
+
userInfo: { name: 'Alice', color: '#ff0000' },
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Collaborative state store
|
|
133
|
+
const store = adapter.getStore();
|
|
134
|
+
store.set('shared.value', 42); // Syncs to all connected clients
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### JSON-Render Compatibility
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { jsonRenderAdapter, llmToIX } from '@allternit/ix';
|
|
141
|
+
|
|
142
|
+
// From json-render to A2R-IX
|
|
143
|
+
const jsonRenderSchema = {
|
|
144
|
+
version: '1.0.0',
|
|
145
|
+
root: {
|
|
146
|
+
type: 'Fragment',
|
|
147
|
+
children: [
|
|
148
|
+
{ type: 'Text', props: { children: 'Hello' } },
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const a2rUi = jsonRenderAdapter.fromJsonRender(jsonRenderSchema);
|
|
154
|
+
|
|
155
|
+
// Auto-detect and convert
|
|
156
|
+
const result = llmToIX.convert(jsonRenderSchema);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### IX Capsule Runtime
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import {
|
|
163
|
+
createIXCapsule,
|
|
164
|
+
globalCapsuleRegistry,
|
|
165
|
+
createRateLimitGate,
|
|
166
|
+
createPropSanitizationGate,
|
|
167
|
+
} from '@allternit/ix';
|
|
168
|
+
|
|
169
|
+
// Create capsule with security policies
|
|
170
|
+
const capsule = globalCapsuleRegistry.create({
|
|
171
|
+
id: 'my-capsule',
|
|
172
|
+
ui: a2rUi,
|
|
173
|
+
stateStore: createStateStore(),
|
|
174
|
+
policyGates: [
|
|
175
|
+
createRateLimitGate({ maxActionsPerMinute: 60 }),
|
|
176
|
+
createPropSanitizationGate({ allowHTML: false }),
|
|
177
|
+
],
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Subscribe to events
|
|
181
|
+
capsule.subscribe((event) => {
|
|
182
|
+
console.log('Capsule event:', event);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Apply state patches
|
|
186
|
+
capsule.applyPatch([
|
|
187
|
+
{ op: 'replace', path: '/count', value: 10 },
|
|
188
|
+
]);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Architecture
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
A2R-IX
|
|
195
|
+
├── types/ # TypeScript interfaces
|
|
196
|
+
├── schema/ # UI IR schema definitions
|
|
197
|
+
├── catalog/ # Component registry with semver
|
|
198
|
+
├── state/ # Store + JSON Patch engine (RFC 6902)
|
|
199
|
+
├── adapters/ # Format converters (json-render)
|
|
200
|
+
├── react/ # React renderer
|
|
201
|
+
├── vue/ # Vue renderer
|
|
202
|
+
├── svelte/ # Svelte renderer
|
|
203
|
+
├── runtime/ # Capsule runtime + policy gates
|
|
204
|
+
├── sdk/ # API client + React hooks
|
|
205
|
+
├── pipeline/ # LLM-to-IX conversion
|
|
206
|
+
└── collab/ # Yjs/CRDT + Visual Editor
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Component Catalog
|
|
210
|
+
|
|
211
|
+
Built-in components:
|
|
212
|
+
|
|
213
|
+
| Component | Category | Props |
|
|
214
|
+
|-----------|----------|-------|
|
|
215
|
+
| Box | layout | padding, margin, width, height, display, gap |
|
|
216
|
+
| Stack | layout | direction, spacing, align, justify |
|
|
217
|
+
| Text | typography | variant, size, weight, color, align |
|
|
218
|
+
| Heading | typography | level, color |
|
|
219
|
+
| Button | input | variant, size, disabled, onClick |
|
|
220
|
+
| Input | input | value, placeholder, type, onChange |
|
|
221
|
+
| TextArea | input | value, rows, onChange |
|
|
222
|
+
| Select | input | value, options, onChange |
|
|
223
|
+
| Card | display | padding, elevation, borderRadius |
|
|
224
|
+
| List | display | items, renderItem, emptyText |
|
|
225
|
+
| Table | display | data, columns, onRowClick |
|
|
226
|
+
|
|
227
|
+
## API Reference
|
|
228
|
+
|
|
229
|
+
### State Management
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { createStateStore, applyPatch } from '@allternit/ix';
|
|
233
|
+
|
|
234
|
+
const store = createStateStore({
|
|
235
|
+
initial: { count: 0 },
|
|
236
|
+
persist: true,
|
|
237
|
+
scopeId: 'my-app',
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Subscribe to changes
|
|
241
|
+
const unsubscribe = store.subscribe('count', (value) => {
|
|
242
|
+
console.log('Count:', value);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Apply JSON Patch
|
|
246
|
+
const patch = [
|
|
247
|
+
{ op: 'replace', path: '/count', value: 5 },
|
|
248
|
+
];
|
|
249
|
+
applyPatchToStore(store, patch);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Policy Gates
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import {
|
|
256
|
+
createRateLimitGate,
|
|
257
|
+
createActionAllowlistGate,
|
|
258
|
+
createStateValidationGate,
|
|
259
|
+
composePolicyGates,
|
|
260
|
+
} from '@allternit/ix';
|
|
261
|
+
|
|
262
|
+
const policies = composePolicyGates(
|
|
263
|
+
createRateLimitGate({ maxActionsPerMinute: 60 }),
|
|
264
|
+
createActionAllowlistGate(['submit', 'cancel']),
|
|
265
|
+
createStateValidationGate({
|
|
266
|
+
email: {
|
|
267
|
+
type: 'string',
|
|
268
|
+
required: true,
|
|
269
|
+
validate: (v) => v.includes('@') || 'Invalid email',
|
|
270
|
+
},
|
|
271
|
+
})
|
|
272
|
+
);
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### LLM-to-IX Pipeline
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { llmToIX } from '@allternit/ix';
|
|
279
|
+
|
|
280
|
+
// From JSX-like string
|
|
281
|
+
const result = llmToIX.fromJSX(`
|
|
282
|
+
<Card>
|
|
283
|
+
<Heading level={2}>Sign Up</Heading>
|
|
284
|
+
<Input $value={email} placeholder="Email" />
|
|
285
|
+
<Button onClick="submit">Submit</Button>
|
|
286
|
+
</Card>
|
|
287
|
+
`);
|
|
288
|
+
|
|
289
|
+
// Auto-detect format
|
|
290
|
+
const detected = llmToIX.convert(unknownInput);
|
|
291
|
+
console.log(detected.confidence); // 0.0 - 1.0
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Implementation Status
|
|
295
|
+
|
|
296
|
+
### Week 1 ✅
|
|
297
|
+
- UI IR Schema (UIRoot, UIComponent, UIState, UIAction)
|
|
298
|
+
- Component Catalog (15 built-ins, semver support)
|
|
299
|
+
- State Store (scoped state, persistence, bindings)
|
|
300
|
+
- JSON Patch Engine (RFC 6902, full implementation)
|
|
301
|
+
- json-render Adapter (bidirectional conversion)
|
|
302
|
+
|
|
303
|
+
### Weeks 2-3 ✅
|
|
304
|
+
- React Renderer (complete with all built-ins)
|
|
305
|
+
- IX Capsule Runtime (sandboxed execution)
|
|
306
|
+
- Policy Gates (7 gate types + composition)
|
|
307
|
+
- LLM-to-IX Pipeline (multi-format conversion)
|
|
308
|
+
- Rust API Integration (Axum routes)
|
|
309
|
+
- TypeScript SDK (API client + React hooks)
|
|
310
|
+
|
|
311
|
+
### Option 4: Enhancements ✅
|
|
312
|
+
- Vue Renderer (component generation)
|
|
313
|
+
- Svelte Renderer (component compilation)
|
|
314
|
+
- Yjs/CRDT Integration (real-time collaboration)
|
|
315
|
+
- Visual Editor (fluent API for UI building)
|
|
316
|
+
- Awareness API (cursor positions, selections)
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel Labs json-render Adapter
|
|
3
|
+
*
|
|
4
|
+
* Converts between A2R-IX UI IR and Vercel Labs json-render format.
|
|
5
|
+
*
|
|
6
|
+
* json-render is a declarative UI format where components are expressed as JSON.
|
|
7
|
+
* This adapter enables A2R-IX to render UIs generated by LLMs trained on
|
|
8
|
+
* json-render patterns.
|
|
9
|
+
*
|
|
10
|
+
* @see https://github.com/vercel-labs/json-render
|
|
11
|
+
*/
|
|
12
|
+
import type { UIRoot } from '../types';
|
|
13
|
+
/**
|
|
14
|
+
* json-render node format
|
|
15
|
+
*/
|
|
16
|
+
export interface JsonRenderNode {
|
|
17
|
+
/** Component type */
|
|
18
|
+
type: string;
|
|
19
|
+
/** Component props */
|
|
20
|
+
props?: Record<string, unknown>;
|
|
21
|
+
/** Child nodes */
|
|
22
|
+
children?: JsonRenderNode[];
|
|
23
|
+
/** Text content (for text nodes) */
|
|
24
|
+
text?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* json-render component registry entry
|
|
28
|
+
*/
|
|
29
|
+
export interface JsonRenderComponent {
|
|
30
|
+
/** Component name */
|
|
31
|
+
name: string;
|
|
32
|
+
/** React component or element type */
|
|
33
|
+
component: string;
|
|
34
|
+
/** Prop mapping (json-render prop -> component prop) */
|
|
35
|
+
propMapping?: Record<string, string>;
|
|
36
|
+
/** Transform props before passing */
|
|
37
|
+
transformProps?: (props: Record<string, unknown>) => Record<string, unknown>;
|
|
38
|
+
/** Whether component accepts children */
|
|
39
|
+
acceptsChildren?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* json-render schema
|
|
43
|
+
*/
|
|
44
|
+
export interface JsonRenderSchema {
|
|
45
|
+
/** Schema version */
|
|
46
|
+
version: string;
|
|
47
|
+
/** Component tree */
|
|
48
|
+
root: JsonRenderNode;
|
|
49
|
+
/** State definitions */
|
|
50
|
+
state?: Record<string, {
|
|
51
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
52
|
+
default?: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
/** Event handlers */
|
|
55
|
+
events?: Record<string, {
|
|
56
|
+
type: string;
|
|
57
|
+
target?: string;
|
|
58
|
+
payload?: unknown;
|
|
59
|
+
}>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Custom handler function type
|
|
63
|
+
*/
|
|
64
|
+
export type CustomHandlerFn = (context: {
|
|
65
|
+
state: Record<string, unknown>;
|
|
66
|
+
params?: Record<string, unknown>;
|
|
67
|
+
event?: unknown;
|
|
68
|
+
}) => void | Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Handler registry entry metadata
|
|
71
|
+
*/
|
|
72
|
+
export interface HandlerRegistryEntry {
|
|
73
|
+
/** Handler name/identifier */
|
|
74
|
+
name: string;
|
|
75
|
+
/** Handler function */
|
|
76
|
+
handler: CustomHandlerFn;
|
|
77
|
+
/** Handler description */
|
|
78
|
+
description?: string;
|
|
79
|
+
/** Handler version */
|
|
80
|
+
version?: string;
|
|
81
|
+
/** Handler tags for discovery */
|
|
82
|
+
tags?: string[];
|
|
83
|
+
/** Input schema for validation */
|
|
84
|
+
inputSchema?: Record<string, unknown>;
|
|
85
|
+
/** Output schema */
|
|
86
|
+
outputSchema?: Record<string, unknown>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Global handler registry for custom action handlers
|
|
90
|
+
*
|
|
91
|
+
* GAP-59: Custom Handler System
|
|
92
|
+
* Implements a singleton registry for dynamic handler registration
|
|
93
|
+
*/
|
|
94
|
+
declare class HandlerRegistry {
|
|
95
|
+
private handlers;
|
|
96
|
+
private tagsIndex;
|
|
97
|
+
/**
|
|
98
|
+
* Register a custom handler
|
|
99
|
+
* @param entry Handler registry entry
|
|
100
|
+
*/
|
|
101
|
+
register(entry: HandlerRegistryEntry): void;
|
|
102
|
+
/**
|
|
103
|
+
* Unregister a handler
|
|
104
|
+
* @param name Handler name
|
|
105
|
+
*/
|
|
106
|
+
unregister(name: string): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Get a handler by name
|
|
109
|
+
* @param name Handler name
|
|
110
|
+
*/
|
|
111
|
+
get(name: string): HandlerRegistryEntry | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Check if a handler exists
|
|
114
|
+
* @param name Handler name
|
|
115
|
+
*/
|
|
116
|
+
has(name: string): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Execute a handler by name
|
|
119
|
+
* @param name Handler name
|
|
120
|
+
* @param context Execution context
|
|
121
|
+
*/
|
|
122
|
+
execute(name: string, context: {
|
|
123
|
+
state: Record<string, unknown>;
|
|
124
|
+
params?: Record<string, unknown>;
|
|
125
|
+
event?: unknown;
|
|
126
|
+
}): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* GAP-61: Handler Discovery
|
|
129
|
+
* Find handlers by tags
|
|
130
|
+
* @param tags Tags to search for
|
|
131
|
+
*/
|
|
132
|
+
findByTags(tags: string[]): HandlerRegistryEntry[];
|
|
133
|
+
/**
|
|
134
|
+
* GAP-61: Handler Discovery
|
|
135
|
+
* Search handlers by name pattern or description
|
|
136
|
+
* @param query Search query
|
|
137
|
+
*/
|
|
138
|
+
search(query: string): HandlerRegistryEntry[];
|
|
139
|
+
/**
|
|
140
|
+
* Get all registered handlers
|
|
141
|
+
*/
|
|
142
|
+
listAll(): HandlerRegistryEntry[];
|
|
143
|
+
/**
|
|
144
|
+
* Get all available tags
|
|
145
|
+
*/
|
|
146
|
+
getAllTags(): string[];
|
|
147
|
+
/**
|
|
148
|
+
* Clear all handlers
|
|
149
|
+
*/
|
|
150
|
+
clear(): void;
|
|
151
|
+
/**
|
|
152
|
+
* Get registry statistics
|
|
153
|
+
*/
|
|
154
|
+
getStats(): {
|
|
155
|
+
total: number;
|
|
156
|
+
tags: number;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** Global handler registry instance */
|
|
160
|
+
export declare const globalHandlerRegistry: HandlerRegistry;
|
|
161
|
+
/**
|
|
162
|
+
* Convert A2R-IX UIRoot to json-render format
|
|
163
|
+
*/
|
|
164
|
+
export declare function convertToJsonRender(root: UIRoot): JsonRenderSchema;
|
|
165
|
+
/**
|
|
166
|
+
* Convert json-render format to A2R-IX UIRoot
|
|
167
|
+
*/
|
|
168
|
+
export declare function convertFromJsonRender(schema: JsonRenderSchema): UIRoot;
|
|
169
|
+
/**
|
|
170
|
+
* json-render adapter configuration
|
|
171
|
+
*/
|
|
172
|
+
export declare const jsonRenderAdapter: {
|
|
173
|
+
name: string;
|
|
174
|
+
version: string;
|
|
175
|
+
/**
|
|
176
|
+
* Standard json-render components mapped to A2R-IX catalog
|
|
177
|
+
*/
|
|
178
|
+
components: Record<string, string>;
|
|
179
|
+
/**
|
|
180
|
+
* Convert from json-render
|
|
181
|
+
*/
|
|
182
|
+
fromJsonRender: typeof convertFromJsonRender;
|
|
183
|
+
/**
|
|
184
|
+
* Convert to json-render
|
|
185
|
+
*/
|
|
186
|
+
toJsonRender: typeof convertToJsonRender;
|
|
187
|
+
/**
|
|
188
|
+
* Check if value is a valid json-render schema
|
|
189
|
+
*/
|
|
190
|
+
isValidSchema(value: unknown): value is JsonRenderSchema;
|
|
191
|
+
/**
|
|
192
|
+
* Check if node is a valid json-render node
|
|
193
|
+
*/
|
|
194
|
+
isValidNode(value: unknown): value is JsonRenderNode;
|
|
195
|
+
/**
|
|
196
|
+
* GAP-59/61: Handler Registry Access
|
|
197
|
+
* Get the global handler registry for custom action handlers
|
|
198
|
+
*/
|
|
199
|
+
readonly handlerRegistry: HandlerRegistry;
|
|
200
|
+
/**
|
|
201
|
+
* GAP-60: Execute custom handler
|
|
202
|
+
* Execute a registered custom handler by name
|
|
203
|
+
*/
|
|
204
|
+
executeHandler(name: string, context: {
|
|
205
|
+
state: Record<string, unknown>;
|
|
206
|
+
params?: Record<string, unknown>;
|
|
207
|
+
event?: unknown;
|
|
208
|
+
}): Promise<void>;
|
|
209
|
+
};
|
|
210
|
+
export {};
|
|
211
|
+
//# sourceMappingURL=json-render.d.ts.map
|