@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
|
@@ -0,0 +1,576 @@
|
|
|
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
|
+
/**
|
|
13
|
+
* Global handler registry for custom action handlers
|
|
14
|
+
*
|
|
15
|
+
* GAP-59: Custom Handler System
|
|
16
|
+
* Implements a singleton registry for dynamic handler registration
|
|
17
|
+
*/
|
|
18
|
+
class HandlerRegistry {
|
|
19
|
+
handlers = new Map();
|
|
20
|
+
tagsIndex = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Register a custom handler
|
|
23
|
+
* @param entry Handler registry entry
|
|
24
|
+
*/
|
|
25
|
+
register(entry) {
|
|
26
|
+
if (!entry.name || typeof entry.handler !== 'function') {
|
|
27
|
+
throw new Error('Handler must have a name and a function');
|
|
28
|
+
}
|
|
29
|
+
// Store handler
|
|
30
|
+
this.handlers.set(entry.name, entry);
|
|
31
|
+
// Index by tags
|
|
32
|
+
if (entry.tags) {
|
|
33
|
+
for (const tag of entry.tags) {
|
|
34
|
+
if (!this.tagsIndex.has(tag)) {
|
|
35
|
+
this.tagsIndex.set(tag, new Set());
|
|
36
|
+
}
|
|
37
|
+
this.tagsIndex.get(tag).add(entry.name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Unregister a handler
|
|
43
|
+
* @param name Handler name
|
|
44
|
+
*/
|
|
45
|
+
unregister(name) {
|
|
46
|
+
const entry = this.handlers.get(name);
|
|
47
|
+
if (!entry)
|
|
48
|
+
return false;
|
|
49
|
+
// Remove from tags index
|
|
50
|
+
if (entry.tags) {
|
|
51
|
+
for (const tag of entry.tags) {
|
|
52
|
+
this.tagsIndex.get(tag)?.delete(name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return this.handlers.delete(name);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get a handler by name
|
|
59
|
+
* @param name Handler name
|
|
60
|
+
*/
|
|
61
|
+
get(name) {
|
|
62
|
+
return this.handlers.get(name);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if a handler exists
|
|
66
|
+
* @param name Handler name
|
|
67
|
+
*/
|
|
68
|
+
has(name) {
|
|
69
|
+
return this.handlers.has(name);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Execute a handler by name
|
|
73
|
+
* @param name Handler name
|
|
74
|
+
* @param context Execution context
|
|
75
|
+
*/
|
|
76
|
+
async execute(name, context) {
|
|
77
|
+
const entry = this.handlers.get(name);
|
|
78
|
+
if (!entry) {
|
|
79
|
+
throw new Error(`Handler not found: ${name}`);
|
|
80
|
+
}
|
|
81
|
+
await entry.handler(context);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* GAP-61: Handler Discovery
|
|
85
|
+
* Find handlers by tags
|
|
86
|
+
* @param tags Tags to search for
|
|
87
|
+
*/
|
|
88
|
+
findByTags(tags) {
|
|
89
|
+
const matchingNames = new Set();
|
|
90
|
+
for (const tag of tags) {
|
|
91
|
+
const names = this.tagsIndex.get(tag);
|
|
92
|
+
if (names) {
|
|
93
|
+
for (const name of names) {
|
|
94
|
+
matchingNames.add(name);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return Array.from(matchingNames)
|
|
99
|
+
.map(name => this.handlers.get(name))
|
|
100
|
+
.filter(Boolean);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* GAP-61: Handler Discovery
|
|
104
|
+
* Search handlers by name pattern or description
|
|
105
|
+
* @param query Search query
|
|
106
|
+
*/
|
|
107
|
+
search(query) {
|
|
108
|
+
const lowerQuery = query.toLowerCase();
|
|
109
|
+
return Array.from(this.handlers.values()).filter(entry => entry.name.toLowerCase().includes(lowerQuery) ||
|
|
110
|
+
entry.description?.toLowerCase().includes(lowerQuery) ||
|
|
111
|
+
entry.tags?.some(tag => tag.toLowerCase().includes(lowerQuery)));
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get all registered handlers
|
|
115
|
+
*/
|
|
116
|
+
listAll() {
|
|
117
|
+
return Array.from(this.handlers.values());
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get all available tags
|
|
121
|
+
*/
|
|
122
|
+
getAllTags() {
|
|
123
|
+
return Array.from(this.tagsIndex.keys());
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Clear all handlers
|
|
127
|
+
*/
|
|
128
|
+
clear() {
|
|
129
|
+
this.handlers.clear();
|
|
130
|
+
this.tagsIndex.clear();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get registry statistics
|
|
134
|
+
*/
|
|
135
|
+
getStats() {
|
|
136
|
+
return {
|
|
137
|
+
total: this.handlers.size,
|
|
138
|
+
tags: this.tagsIndex.size,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/** Global handler registry instance */
|
|
143
|
+
export const globalHandlerRegistry = new HandlerRegistry();
|
|
144
|
+
/**
|
|
145
|
+
* GAP-60: Replace Placeholder Handlers
|
|
146
|
+
* Create an action handler from json-render event config
|
|
147
|
+
*/
|
|
148
|
+
function createActionHandlerFromEvent(config) {
|
|
149
|
+
switch (config.type) {
|
|
150
|
+
case 'setState':
|
|
151
|
+
return {
|
|
152
|
+
type: 'setState',
|
|
153
|
+
path: config.target || '',
|
|
154
|
+
value: { $path: 'event.value' },
|
|
155
|
+
};
|
|
156
|
+
case 'emit':
|
|
157
|
+
return {
|
|
158
|
+
type: 'emitEvent',
|
|
159
|
+
name: config.target || '',
|
|
160
|
+
payload: config.payload,
|
|
161
|
+
};
|
|
162
|
+
case 'navigate':
|
|
163
|
+
return {
|
|
164
|
+
type: 'navigate',
|
|
165
|
+
to: config.target || '',
|
|
166
|
+
};
|
|
167
|
+
case 'validate':
|
|
168
|
+
return {
|
|
169
|
+
type: 'validate',
|
|
170
|
+
paths: config.target?.split(',') || [],
|
|
171
|
+
};
|
|
172
|
+
default:
|
|
173
|
+
// GAP-60: Custom handlers - lookup in registry or create named reference
|
|
174
|
+
if (config.target && globalHandlerRegistry.has(config.target)) {
|
|
175
|
+
return {
|
|
176
|
+
type: 'custom',
|
|
177
|
+
fn: config.target,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Create a reference to a custom handler that can be resolved at runtime
|
|
181
|
+
return {
|
|
182
|
+
type: 'custom',
|
|
183
|
+
fn: config.target || `handler_${generateId()}`,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Convert A2R-IX UIRoot to json-render format
|
|
189
|
+
*/
|
|
190
|
+
export function convertToJsonRender(root) {
|
|
191
|
+
return {
|
|
192
|
+
version: root.version,
|
|
193
|
+
root: {
|
|
194
|
+
type: 'Fragment',
|
|
195
|
+
children: root.components.map(convertComponentToJsonRender),
|
|
196
|
+
},
|
|
197
|
+
state: convertStateToJsonRender(root.state),
|
|
198
|
+
events: convertActionsToJsonRender(root.actions),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Convert A2R-IX UIComponent to json-render node
|
|
203
|
+
*/
|
|
204
|
+
function convertComponentToJsonRender(component) {
|
|
205
|
+
const node = {
|
|
206
|
+
type: component.type,
|
|
207
|
+
};
|
|
208
|
+
// Convert props
|
|
209
|
+
if (component.props && Object.keys(component.props).length > 0) {
|
|
210
|
+
node.props = { ...component.props };
|
|
211
|
+
}
|
|
212
|
+
// Convert bindings to props
|
|
213
|
+
if (component.bindings) {
|
|
214
|
+
node.props = node.props || {};
|
|
215
|
+
component.bindings.forEach((binding) => {
|
|
216
|
+
if (binding.direction === 'two-way') {
|
|
217
|
+
// json-render uses onChange for two-way bindings
|
|
218
|
+
node.props[`on${capitalize(binding.prop)}Change`] = {
|
|
219
|
+
$action: 'setState',
|
|
220
|
+
path: binding.statePath,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// One-way binding
|
|
225
|
+
node.props[binding.prop] = { $state: binding.statePath };
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// Convert events to props
|
|
230
|
+
if (component.events) {
|
|
231
|
+
node.props = node.props || {};
|
|
232
|
+
component.events.forEach((event) => {
|
|
233
|
+
node.props[event.event] = {
|
|
234
|
+
$action: event.action,
|
|
235
|
+
params: event.params,
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// Convert children
|
|
240
|
+
if (component.children && component.children.length > 0) {
|
|
241
|
+
node.children = component.children.map(convertComponentToJsonRender);
|
|
242
|
+
}
|
|
243
|
+
// Convert repeat to children with mapping
|
|
244
|
+
if (component.repeat) {
|
|
245
|
+
node.props = node.props || {};
|
|
246
|
+
node.props.$for = {
|
|
247
|
+
items: component.repeat.items,
|
|
248
|
+
as: component.repeat.as,
|
|
249
|
+
index: component.repeat.indexAs,
|
|
250
|
+
filter: component.repeat.filter,
|
|
251
|
+
sort: component.repeat.sort,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// Convert condition
|
|
255
|
+
if (component.condition) {
|
|
256
|
+
node.props = node.props || {};
|
|
257
|
+
node.props.$if = component.condition;
|
|
258
|
+
}
|
|
259
|
+
// Convert style
|
|
260
|
+
if (component.style) {
|
|
261
|
+
node.props = node.props || {};
|
|
262
|
+
node.props.style = component.style;
|
|
263
|
+
}
|
|
264
|
+
// Convert className
|
|
265
|
+
if (component.className) {
|
|
266
|
+
node.props = node.props || {};
|
|
267
|
+
node.props.className = component.className;
|
|
268
|
+
}
|
|
269
|
+
return node;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Convert A2R-IX state to json-render state
|
|
273
|
+
*/
|
|
274
|
+
function convertStateToJsonRender(state) {
|
|
275
|
+
const result = {};
|
|
276
|
+
state.variables.forEach((variable) => {
|
|
277
|
+
result[variable.path] = {
|
|
278
|
+
type: variable.type === 'any' ? 'string' : variable.type,
|
|
279
|
+
default: variable.default,
|
|
280
|
+
};
|
|
281
|
+
});
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Convert A2R-IX actions to json-render events
|
|
286
|
+
*/
|
|
287
|
+
function convertActionsToJsonRender(actions) {
|
|
288
|
+
const result = {};
|
|
289
|
+
actions.forEach((action) => {
|
|
290
|
+
switch (action.handler.type) {
|
|
291
|
+
case 'setState':
|
|
292
|
+
result[action.id] = {
|
|
293
|
+
type: 'setState',
|
|
294
|
+
target: action.handler.path,
|
|
295
|
+
};
|
|
296
|
+
break;
|
|
297
|
+
case 'emitEvent':
|
|
298
|
+
result[action.id] = {
|
|
299
|
+
type: 'emit',
|
|
300
|
+
target: action.handler.name,
|
|
301
|
+
payload: action.handler.payload,
|
|
302
|
+
};
|
|
303
|
+
break;
|
|
304
|
+
case 'navigate':
|
|
305
|
+
result[action.id] = {
|
|
306
|
+
type: 'navigate',
|
|
307
|
+
target: action.handler.to,
|
|
308
|
+
};
|
|
309
|
+
break;
|
|
310
|
+
case 'validate':
|
|
311
|
+
result[action.id] = {
|
|
312
|
+
type: 'validate',
|
|
313
|
+
target: action.handler.paths.join(','),
|
|
314
|
+
};
|
|
315
|
+
break;
|
|
316
|
+
case 'custom':
|
|
317
|
+
// GAP-60: Use the actual custom handler function reference
|
|
318
|
+
result[action.id] = {
|
|
319
|
+
type: 'custom',
|
|
320
|
+
target: action.handler.fn,
|
|
321
|
+
};
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Convert json-render format to A2R-IX UIRoot
|
|
329
|
+
*/
|
|
330
|
+
export function convertFromJsonRender(schema) {
|
|
331
|
+
return {
|
|
332
|
+
version: schema.version,
|
|
333
|
+
components: convertJsonRenderNodeToComponent(schema.root),
|
|
334
|
+
state: convertJsonRenderStateToState(schema.state || {}),
|
|
335
|
+
actions: convertJsonRenderEventsToActions(schema.events || {}),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Convert json-render node to A2R-IX UIComponent(s)
|
|
340
|
+
*/
|
|
341
|
+
function convertJsonRenderNodeToComponent(node) {
|
|
342
|
+
// Handle Fragment wrapper
|
|
343
|
+
if (node.type === 'Fragment' && node.children) {
|
|
344
|
+
return node.children.map((child) => convertSingleNodeToComponent(child));
|
|
345
|
+
}
|
|
346
|
+
return [convertSingleNodeToComponent(node)];
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Convert single json-render node to A2R-IX UIComponent
|
|
350
|
+
*/
|
|
351
|
+
function convertSingleNodeToComponent(node) {
|
|
352
|
+
const component = {
|
|
353
|
+
id: generateId(),
|
|
354
|
+
type: node.type,
|
|
355
|
+
props: {},
|
|
356
|
+
};
|
|
357
|
+
if (node.props) {
|
|
358
|
+
// Extract special props
|
|
359
|
+
const { $for, $if, style, className, ...regularProps } = node.props;
|
|
360
|
+
// Regular props
|
|
361
|
+
component.props = regularProps;
|
|
362
|
+
// Style
|
|
363
|
+
if (style) {
|
|
364
|
+
component.style = style;
|
|
365
|
+
}
|
|
366
|
+
// ClassName
|
|
367
|
+
if (className) {
|
|
368
|
+
component.className = className;
|
|
369
|
+
}
|
|
370
|
+
// Convert bindings from props with $state
|
|
371
|
+
Object.entries(regularProps).forEach(([key, value]) => {
|
|
372
|
+
if (typeof value === 'object' && value !== null && '$state' in value) {
|
|
373
|
+
component.bindings = component.bindings || [];
|
|
374
|
+
component.bindings.push({
|
|
375
|
+
prop: key,
|
|
376
|
+
statePath: value.$state,
|
|
377
|
+
direction: 'one-way',
|
|
378
|
+
});
|
|
379
|
+
delete component.props[key];
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
// Convert for/repeat
|
|
383
|
+
if ($for) {
|
|
384
|
+
const forObj = $for;
|
|
385
|
+
component.repeat = {
|
|
386
|
+
items: forObj.items,
|
|
387
|
+
as: forObj.as,
|
|
388
|
+
indexAs: forObj.index,
|
|
389
|
+
filter: forObj.filter,
|
|
390
|
+
sort: forObj.sort,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
// Convert condition
|
|
394
|
+
if ($if) {
|
|
395
|
+
component.condition = $if;
|
|
396
|
+
}
|
|
397
|
+
// Convert event handlers
|
|
398
|
+
Object.entries(regularProps).forEach(([key, value]) => {
|
|
399
|
+
if (typeof value === 'object' && value !== null && '$action' in value) {
|
|
400
|
+
component.events = component.events || [];
|
|
401
|
+
component.events.push({
|
|
402
|
+
event: key,
|
|
403
|
+
action: value.$action,
|
|
404
|
+
params: value.params,
|
|
405
|
+
});
|
|
406
|
+
delete component.props[key];
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
// Convert children
|
|
411
|
+
if (node.children) {
|
|
412
|
+
component.children = node.children.map(convertSingleNodeToComponent);
|
|
413
|
+
}
|
|
414
|
+
// Text content
|
|
415
|
+
if (node.text) {
|
|
416
|
+
component.props = component.props || {};
|
|
417
|
+
component.props.children = node.text;
|
|
418
|
+
}
|
|
419
|
+
return component;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Convert json-render state to A2R-IX UIState
|
|
423
|
+
*/
|
|
424
|
+
function convertJsonRenderStateToState(state) {
|
|
425
|
+
return {
|
|
426
|
+
variables: Object.entries(state).map(([path, config]) => ({
|
|
427
|
+
path,
|
|
428
|
+
type: config.type,
|
|
429
|
+
default: config.default,
|
|
430
|
+
})),
|
|
431
|
+
computed: [],
|
|
432
|
+
initial: Object.entries(state).reduce((acc, [path, config]) => {
|
|
433
|
+
if (config.default !== undefined) {
|
|
434
|
+
acc[path] = config.default;
|
|
435
|
+
}
|
|
436
|
+
return acc;
|
|
437
|
+
}, {}),
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Convert json-render events to A2R-IX UIActions
|
|
442
|
+
*
|
|
443
|
+
* GAP-60: Replace Placeholder Handlers
|
|
444
|
+
* Uses createActionHandlerFromEvent for proper handler resolution
|
|
445
|
+
*/
|
|
446
|
+
function convertJsonRenderEventsToActions(events) {
|
|
447
|
+
return Object.entries(events).map(([id, config]) => {
|
|
448
|
+
const action = {
|
|
449
|
+
id,
|
|
450
|
+
type: config.type,
|
|
451
|
+
handler: createActionHandlerFromEvent(config),
|
|
452
|
+
};
|
|
453
|
+
// Refine action type based on handler type
|
|
454
|
+
if (action.handler.type === 'setState') {
|
|
455
|
+
action.type = 'setState';
|
|
456
|
+
}
|
|
457
|
+
else if (action.handler.type === 'emitEvent') {
|
|
458
|
+
action.type = 'emitEvent';
|
|
459
|
+
}
|
|
460
|
+
else if (action.handler.type === 'navigate') {
|
|
461
|
+
action.type = 'navigate';
|
|
462
|
+
}
|
|
463
|
+
else if (action.handler.type === 'validate') {
|
|
464
|
+
action.type = 'validate';
|
|
465
|
+
}
|
|
466
|
+
else if (action.handler.type === 'custom') {
|
|
467
|
+
action.type = 'custom';
|
|
468
|
+
}
|
|
469
|
+
return action;
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Generate unique ID
|
|
474
|
+
*/
|
|
475
|
+
function generateId() {
|
|
476
|
+
return `comp_${Math.random().toString(36).substr(2, 9)}`;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Capitalize string
|
|
480
|
+
*/
|
|
481
|
+
function capitalize(str) {
|
|
482
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* json-render adapter configuration
|
|
486
|
+
*/
|
|
487
|
+
export const jsonRenderAdapter = {
|
|
488
|
+
name: 'json-render',
|
|
489
|
+
version: '1.0.0',
|
|
490
|
+
/**
|
|
491
|
+
* Standard json-render components mapped to A2R-IX catalog
|
|
492
|
+
*/
|
|
493
|
+
components: {
|
|
494
|
+
// Layout
|
|
495
|
+
Box: 'layout',
|
|
496
|
+
Stack: 'layout',
|
|
497
|
+
Grid: 'layout',
|
|
498
|
+
Flex: 'layout',
|
|
499
|
+
Container: 'layout',
|
|
500
|
+
// Typography
|
|
501
|
+
Text: 'typography',
|
|
502
|
+
Heading: 'typography',
|
|
503
|
+
Paragraph: 'typography',
|
|
504
|
+
Label: 'typography',
|
|
505
|
+
Link: 'typography',
|
|
506
|
+
// Input
|
|
507
|
+
Input: 'input',
|
|
508
|
+
TextArea: 'input',
|
|
509
|
+
Select: 'input',
|
|
510
|
+
Checkbox: 'input',
|
|
511
|
+
Radio: 'input',
|
|
512
|
+
Switch: 'input',
|
|
513
|
+
Slider: 'input',
|
|
514
|
+
DatePicker: 'input',
|
|
515
|
+
FileInput: 'input',
|
|
516
|
+
// Display
|
|
517
|
+
Image: 'display',
|
|
518
|
+
Icon: 'display',
|
|
519
|
+
Badge: 'display',
|
|
520
|
+
Card: 'display',
|
|
521
|
+
List: 'display',
|
|
522
|
+
Table: 'display',
|
|
523
|
+
Tabs: 'display',
|
|
524
|
+
Accordion: 'display',
|
|
525
|
+
Modal: 'display',
|
|
526
|
+
Tooltip: 'display',
|
|
527
|
+
Progress: 'display',
|
|
528
|
+
Chart: 'display',
|
|
529
|
+
Avatar: 'display',
|
|
530
|
+
Divider: 'display',
|
|
531
|
+
Spacer: 'display',
|
|
532
|
+
},
|
|
533
|
+
/**
|
|
534
|
+
* Convert from json-render
|
|
535
|
+
*/
|
|
536
|
+
fromJsonRender: convertFromJsonRender,
|
|
537
|
+
/**
|
|
538
|
+
* Convert to json-render
|
|
539
|
+
*/
|
|
540
|
+
toJsonRender: convertToJsonRender,
|
|
541
|
+
/**
|
|
542
|
+
* Check if value is a valid json-render schema
|
|
543
|
+
*/
|
|
544
|
+
isValidSchema(value) {
|
|
545
|
+
if (!value || typeof value !== 'object')
|
|
546
|
+
return false;
|
|
547
|
+
const schema = value;
|
|
548
|
+
return (typeof schema.version === 'string' &&
|
|
549
|
+
schema.root !== undefined &&
|
|
550
|
+
typeof schema.root.type === 'string');
|
|
551
|
+
},
|
|
552
|
+
/**
|
|
553
|
+
* Check if node is a valid json-render node
|
|
554
|
+
*/
|
|
555
|
+
isValidNode(value) {
|
|
556
|
+
if (!value || typeof value !== 'object')
|
|
557
|
+
return false;
|
|
558
|
+
const node = value;
|
|
559
|
+
return typeof node.type === 'string';
|
|
560
|
+
},
|
|
561
|
+
/**
|
|
562
|
+
* GAP-59/61: Handler Registry Access
|
|
563
|
+
* Get the global handler registry for custom action handlers
|
|
564
|
+
*/
|
|
565
|
+
get handlerRegistry() {
|
|
566
|
+
return globalHandlerRegistry;
|
|
567
|
+
},
|
|
568
|
+
/**
|
|
569
|
+
* GAP-60: Execute custom handler
|
|
570
|
+
* Execute a registered custom handler by name
|
|
571
|
+
*/
|
|
572
|
+
async executeHandler(name, context) {
|
|
573
|
+
return globalHandlerRegistry.execute(name, context);
|
|
574
|
+
},
|
|
575
|
+
};
|
|
576
|
+
//# sourceMappingURL=json-render.js.map
|