@allternit/ix 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/adapters/json-render.d.ts +5 -5
- package/dist/adapters/json-render.js +12 -12
- package/dist/collab/visual-editor.d.ts +1 -1
- package/dist/collab/visual-editor.js +4 -4
- package/dist/collab/visual-editor.js.map +1 -1
- package/dist/collab/yjs-adapter.d.ts +1 -1
- package/dist/collab/yjs-adapter.js +2 -2
- package/dist/collab/yjs-adapter.js.map +1 -1
- package/dist/collab/yjs-client.js +1 -1
- package/dist/collab/yjs-client.js.map +1 -1
- package/dist/collab/yjs-types.js +1 -1
- package/dist/collab/yjs-types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pipeline/llm-to-ix.d.ts +5 -5
- package/dist/pipeline/llm-to-ix.d.ts.map +1 -1
- package/dist/pipeline/llm-to-ix.js +6 -6
- package/dist/react/renderer.d.ts +2 -2
- package/dist/react/renderer.js +3 -3
- package/dist/react/renderer.js.map +1 -1
- package/dist/renderer/renderer.d.ts +1 -1
- package/dist/renderer/renderer.js +1 -1
- package/dist/runtime/capsule-runtime.d.ts +1 -1
- package/dist/runtime/capsule-runtime.js +1 -1
- package/dist/sdk/api.d.ts +3 -3
- package/dist/sdk/api.js +3 -3
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/react.d.ts +2 -2
- package/dist/sdk/react.js +2 -2
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -1
- package/dist/state/store.d.ts +1 -1
- package/dist/state/store.js +3 -3
- package/dist/state/store.js.map +1 -1
- package/dist/svelte/index.d.ts +1 -1
- package/dist/svelte/index.js +1 -1
- package/dist/svelte/renderer.d.ts +3 -3
- package/dist/svelte/renderer.js +4 -4
- package/dist/svelte/renderer.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/vue/renderer.d.ts +3 -3
- package/dist/vue/renderer.js +5 -5
- package/dist/vue/renderer.js.map +1 -1
- package/package.json +8 -8
- package/dist/adapters/json-render.d.ts.bak +0 -211
- package/dist/adapters/json-render.js.bak +0 -576
- package/dist/catalog/registry.d.ts.bak +0 -65
- package/dist/catalog/registry.js.bak +0 -388
- package/dist/collab/capsule-registry.d.ts.bak +0 -114
- package/dist/collab/capsule-registry.js.bak +0 -271
- package/dist/collab/index.d.ts.bak +0 -21
- package/dist/collab/index.js.bak +0 -32
- package/dist/collab/visual-editor.d.ts.bak +0 -199
- package/dist/collab/visual-editor.js.bak +0 -259
- package/dist/collab/yjs-adapter.d.ts.bak +0 -95
- package/dist/collab/yjs-adapter.js.bak +0 -282
- package/dist/collab/yjs-client.d.ts.bak +0 -101
- package/dist/collab/yjs-client.js.bak +0 -193
- package/dist/collab/yjs-protocols.d.ts.bak +0 -128
- package/dist/collab/yjs-protocols.js.bak +0 -245
- package/dist/collab/yjs-types.d.ts.bak +0 -201
- package/dist/collab/yjs-types.js.bak +0 -45
- package/dist/index.d.ts.bak +0 -38
- package/dist/index.js.bak +0 -48
- package/dist/pipeline/llm-to-ix.d.ts.bak +0 -249
- package/dist/pipeline/llm-to-ix.js.bak +0 -992
- package/dist/react/index.d.ts.bak +0 -18
- package/dist/react/index.js.bak +0 -18
- package/dist/react/renderer.d.ts.bak +0 -47
- package/dist/react/renderer.js.bak +0 -420
- package/dist/renderer/renderer.d.ts.bak +0 -55
- package/dist/renderer/renderer.js.bak +0 -232
- package/dist/runtime/capsule-runtime.d.ts.bak +0 -227
- package/dist/runtime/capsule-runtime.js.bak +0 -563
- package/dist/runtime/policy-gates.d.ts.bak +0 -116
- package/dist/runtime/policy-gates.js.bak +0 -317
- package/dist/schema/ui-ir.d.ts.bak +0 -26
- package/dist/schema/ui-ir.js.bak +0 -51
- package/dist/sdk/api.d.ts.bak +0 -101
- package/dist/sdk/api.js.bak +0 -177
- package/dist/sdk/index.d.ts.bak +0 -9
- package/dist/sdk/index.js.bak +0 -10
- package/dist/sdk/react.d.ts.bak +0 -63
- package/dist/sdk/react.js.bak +0 -161
- package/dist/state/index.d.ts.bak +0 -8
- package/dist/state/index.js.bak +0 -8
- package/dist/state/patch.d.ts.bak +0 -73
- package/dist/state/patch.js.bak +0 -437
- package/dist/state/store.d.ts.bak +0 -50
- package/dist/state/store.js.bak +0 -246
- package/dist/svelte/index.d.ts.bak +0 -15
- package/dist/svelte/index.js.bak +0 -15
- package/dist/svelte/renderer.d.ts.bak +0 -35
- package/dist/svelte/renderer.js.bak +0 -317
- package/dist/types/index.d.ts.bak +0 -349
- package/dist/types/index.js.bak +0 -152
- package/dist/vue/index.d.ts.bak +0 -18
- package/dist/vue/index.js.bak +0 -18
- package/dist/vue/renderer.d.ts.bak +0 -46
- package/dist/vue/renderer.js.bak +0 -302
package/dist/state/store.js.bak
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* State Store
|
|
3
|
-
*
|
|
4
|
-
* Scoped state management for A2R-IX with binding support.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Create state store
|
|
8
|
-
*/
|
|
9
|
-
export function createStateStore(config = {}) {
|
|
10
|
-
const state = new Map();
|
|
11
|
-
const subscribers = new Map();
|
|
12
|
-
const bindings = new Map();
|
|
13
|
-
const computedValues = new Map();
|
|
14
|
-
const computedCache = new Map();
|
|
15
|
-
const dirtyComputed = new Set();
|
|
16
|
-
// Initialize with initial values
|
|
17
|
-
if (config.initial) {
|
|
18
|
-
Object.entries(config.initial).forEach(([key, value]) => {
|
|
19
|
-
state.set(key, value);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
// Initialize variables with defaults
|
|
23
|
-
config.variables?.forEach((variable) => {
|
|
24
|
-
if (!state.has(variable.path) && variable.default !== undefined) {
|
|
25
|
-
state.set(variable.path, variable.default);
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
// Notify subscribers
|
|
29
|
-
function notify(path, value) {
|
|
30
|
-
const pathSubscribers = subscribers.get(path);
|
|
31
|
-
if (pathSubscribers) {
|
|
32
|
-
pathSubscribers.forEach((cb) => cb(value));
|
|
33
|
-
}
|
|
34
|
-
// Notify parent path subscribers
|
|
35
|
-
const parts = path.split('.');
|
|
36
|
-
while (parts.length > 1) {
|
|
37
|
-
parts.pop();
|
|
38
|
-
const parentPath = parts.join('.');
|
|
39
|
-
const parentSubscribers = subscribers.get(parentPath);
|
|
40
|
-
if (parentSubscribers) {
|
|
41
|
-
const parentValue = get(parentPath);
|
|
42
|
-
parentSubscribers.forEach((cb) => cb(parentValue));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// Mark computed values as dirty
|
|
46
|
-
computedValues.forEach((computed, name) => {
|
|
47
|
-
if (computed.deps.some((dep) => path.startsWith(dep) || dep.startsWith(path))) {
|
|
48
|
-
dirtyComputed.add(name);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
// Get value at path
|
|
53
|
-
function get(path) {
|
|
54
|
-
// Check if it's a computed value
|
|
55
|
-
if (computedValues.has(path)) {
|
|
56
|
-
return getComputed(path);
|
|
57
|
-
}
|
|
58
|
-
const parts = path.split('.');
|
|
59
|
-
let current = Object.fromEntries(state);
|
|
60
|
-
for (const part of parts) {
|
|
61
|
-
if (current && typeof current === 'object') {
|
|
62
|
-
current = current[part];
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return current;
|
|
69
|
-
}
|
|
70
|
-
// Get computed value
|
|
71
|
-
function getComputed(name) {
|
|
72
|
-
const computed = computedValues.get(name);
|
|
73
|
-
if (!computed)
|
|
74
|
-
return undefined;
|
|
75
|
-
// Return cached value if not dirty
|
|
76
|
-
if (!dirtyComputed.has(name) && computedCache.has(name)) {
|
|
77
|
-
return computedCache.get(name);
|
|
78
|
-
}
|
|
79
|
-
// Recompute
|
|
80
|
-
const value = computed.compute();
|
|
81
|
-
computedCache.set(name, value);
|
|
82
|
-
dirtyComputed.delete(name);
|
|
83
|
-
return value;
|
|
84
|
-
}
|
|
85
|
-
// Set value at path
|
|
86
|
-
function set(path, value) {
|
|
87
|
-
const parts = path.split('.');
|
|
88
|
-
if (parts.length === 1) {
|
|
89
|
-
state.set(path, value);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
// Handle nested paths
|
|
93
|
-
const rootKey = parts[0];
|
|
94
|
-
let root = state.get(rootKey);
|
|
95
|
-
if (!root || typeof root !== 'object') {
|
|
96
|
-
root = {};
|
|
97
|
-
state.set(rootKey, root);
|
|
98
|
-
}
|
|
99
|
-
let current = root;
|
|
100
|
-
for (let i = 1; i < parts.length - 1; i++) {
|
|
101
|
-
const part = parts[i];
|
|
102
|
-
if (!current[part] || typeof current[part] !== 'object') {
|
|
103
|
-
current[part] = {};
|
|
104
|
-
}
|
|
105
|
-
current = current[part];
|
|
106
|
-
}
|
|
107
|
-
current[parts[parts.length - 1]] = value;
|
|
108
|
-
state.set(rootKey, { ...root });
|
|
109
|
-
}
|
|
110
|
-
notify(path, value);
|
|
111
|
-
// Persist if enabled
|
|
112
|
-
if (config.persist && config.scopeId) {
|
|
113
|
-
persistState();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// Subscribe to path changes
|
|
117
|
-
function subscribe(path, callback) {
|
|
118
|
-
if (!subscribers.has(path)) {
|
|
119
|
-
subscribers.set(path, new Set());
|
|
120
|
-
}
|
|
121
|
-
subscribers.get(path).add(callback);
|
|
122
|
-
// Return unsubscribe function
|
|
123
|
-
return () => {
|
|
124
|
-
subscribers.get(path)?.delete(callback);
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
// Register computed value
|
|
128
|
-
function compute(name, deps, computeFn) {
|
|
129
|
-
computedValues.set(name, { deps, compute: computeFn });
|
|
130
|
-
// Subscribe to dependencies
|
|
131
|
-
deps.forEach((dep) => {
|
|
132
|
-
subscribe(dep, () => {
|
|
133
|
-
dirtyComputed.add(name);
|
|
134
|
-
notify(name, getComputed(name));
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
// Bind component prop to state
|
|
139
|
-
function bind(componentId, prop, statePath) {
|
|
140
|
-
if (!bindings.has(componentId)) {
|
|
141
|
-
bindings.set(componentId, new Map());
|
|
142
|
-
}
|
|
143
|
-
bindings.get(componentId).set(prop, statePath);
|
|
144
|
-
}
|
|
145
|
-
// Get bindings for component
|
|
146
|
-
function getBindings(componentId) {
|
|
147
|
-
const componentBindings = bindings.get(componentId);
|
|
148
|
-
if (!componentBindings)
|
|
149
|
-
return [];
|
|
150
|
-
return Array.from(componentBindings.entries()).map(([prop, statePath]) => ({
|
|
151
|
-
prop,
|
|
152
|
-
statePath,
|
|
153
|
-
}));
|
|
154
|
-
}
|
|
155
|
-
// Batch updates
|
|
156
|
-
function batch(updates) {
|
|
157
|
-
Object.entries(updates).forEach(([path, value]) => {
|
|
158
|
-
set(path, value);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
// Get snapshot
|
|
162
|
-
function snapshot() {
|
|
163
|
-
return Object.fromEntries(state);
|
|
164
|
-
}
|
|
165
|
-
// Restore from snapshot
|
|
166
|
-
function restore(data) {
|
|
167
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
168
|
-
state.set(key, value);
|
|
169
|
-
notify(key, value);
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
// Reset to initial
|
|
173
|
-
function reset() {
|
|
174
|
-
state.clear();
|
|
175
|
-
computedCache.clear();
|
|
176
|
-
dirtyComputed.clear();
|
|
177
|
-
if (config.initial) {
|
|
178
|
-
Object.entries(config.initial).forEach(([key, value]) => {
|
|
179
|
-
state.set(key, value);
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
// Notify all subscribers
|
|
183
|
-
subscribers.forEach((cbs, path) => {
|
|
184
|
-
const value = get(path);
|
|
185
|
-
cbs.forEach((cb) => cb(value));
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
// Persist to localStorage
|
|
189
|
-
function persistState() {
|
|
190
|
-
if (typeof localStorage === 'undefined')
|
|
191
|
-
return;
|
|
192
|
-
try {
|
|
193
|
-
const key = `a2r-ix-state-${config.scopeId}`;
|
|
194
|
-
localStorage.setItem(key, JSON.stringify(Object.fromEntries(state)));
|
|
195
|
-
}
|
|
196
|
-
catch (error) {
|
|
197
|
-
console.error('Failed to persist state:', error);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
// Load from localStorage
|
|
201
|
-
function loadPersistedState() {
|
|
202
|
-
if (typeof localStorage === 'undefined' || !config.scopeId)
|
|
203
|
-
return;
|
|
204
|
-
try {
|
|
205
|
-
const key = `a2r-ix-state-${config.scopeId}`;
|
|
206
|
-
const data = localStorage.getItem(key);
|
|
207
|
-
if (data) {
|
|
208
|
-
const parsed = JSON.parse(data);
|
|
209
|
-
Object.entries(parsed).forEach(([key, value]) => {
|
|
210
|
-
state.set(key, value);
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
catch (error) {
|
|
215
|
-
console.error('Failed to load persisted state:', error);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
// Load persisted state on init
|
|
219
|
-
if (config.persist && config.scopeId) {
|
|
220
|
-
loadPersistedState();
|
|
221
|
-
}
|
|
222
|
-
return {
|
|
223
|
-
get,
|
|
224
|
-
set,
|
|
225
|
-
subscribe,
|
|
226
|
-
compute,
|
|
227
|
-
bind,
|
|
228
|
-
getBindings,
|
|
229
|
-
batch,
|
|
230
|
-
snapshot,
|
|
231
|
-
restore,
|
|
232
|
-
reset,
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
// Global stores
|
|
236
|
-
const stores = new Map();
|
|
237
|
-
export function getStateStore(scopeId, config) {
|
|
238
|
-
if (!stores.has(scopeId)) {
|
|
239
|
-
stores.set(scopeId, createStateStore({ ...config, scopeId }));
|
|
240
|
-
}
|
|
241
|
-
return stores.get(scopeId);
|
|
242
|
-
}
|
|
243
|
-
export function clearStateStore(scopeId) {
|
|
244
|
-
stores.delete(scopeId);
|
|
245
|
-
}
|
|
246
|
-
//# sourceMappingURL=store.js.map
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Svelte Renderer
|
|
3
|
-
*
|
|
4
|
-
* Generates Svelte component code from A2R-IX UI IR.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { createSvelteRenderer, compileToSvelte } from '@allternit/ix/svelte';
|
|
9
|
-
*
|
|
10
|
-
* const svelteCode = compileToSvelte(uiDefinition);
|
|
11
|
-
* // Use with Svelte compiler
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
|
-
export { createSvelteRenderer, compileToSvelte, type SvelteRenderer, type SvelteRendererConfig, } from './renderer';
|
|
15
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/svelte/index.js.bak
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Svelte Renderer
|
|
3
|
-
*
|
|
4
|
-
* Generates Svelte component code from A2R-IX UI IR.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { createSvelteRenderer, compileToSvelte } from '@allternit/ix/svelte';
|
|
9
|
-
*
|
|
10
|
-
* const svelteCode = compileToSvelte(uiDefinition);
|
|
11
|
-
* // Use with Svelte compiler
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
|
-
export { createSvelteRenderer, compileToSvelte, } from './renderer';
|
|
15
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Svelte Renderer for A2R-IX
|
|
3
|
-
*
|
|
4
|
-
* Renders A2R-IX UI IR to Svelte components.
|
|
5
|
-
*/
|
|
6
|
-
import type { UIRoot, UIComponent } from '../types';
|
|
7
|
-
import type { StateStore } from '../state/store';
|
|
8
|
-
import type { ComponentCatalog } from '../catalog/registry';
|
|
9
|
-
export interface SvelteRendererConfig {
|
|
10
|
-
/** Component catalog */
|
|
11
|
-
catalog?: ComponentCatalog;
|
|
12
|
-
/** Initial state store */
|
|
13
|
-
stateStore?: StateStore;
|
|
14
|
-
/** Component mapping (type -> Svelte component) */
|
|
15
|
-
components?: Record<string, unknown>;
|
|
16
|
-
/** Event handler */
|
|
17
|
-
onEvent?: (name: string, payload: unknown) => void;
|
|
18
|
-
/** Error handler */
|
|
19
|
-
onError?: (error: Error, componentId?: string) => void;
|
|
20
|
-
}
|
|
21
|
-
export interface SvelteRenderer {
|
|
22
|
-
/** Generate Svelte component code from UI root */
|
|
23
|
-
generateComponent(root: UIRoot): string;
|
|
24
|
-
/** Generate Svelte template from component */
|
|
25
|
-
generateTemplate(component: UIComponent, depth?: number): string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Create Svelte renderer
|
|
29
|
-
*/
|
|
30
|
-
export declare function createSvelteRenderer(config: SvelteRendererConfig): SvelteRenderer;
|
|
31
|
-
/**
|
|
32
|
-
* Compile A2R-IX UI to Svelte component
|
|
33
|
-
*/
|
|
34
|
-
export declare function compileToSvelte(root: UIRoot, config?: SvelteRendererConfig): string;
|
|
35
|
-
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Svelte Renderer for A2R-IX
|
|
3
|
-
*
|
|
4
|
-
* Renders A2R-IX UI IR to Svelte components.
|
|
5
|
-
*/
|
|
6
|
-
import { createDefaultCatalog } from '../catalog/registry';
|
|
7
|
-
/**
|
|
8
|
-
* Create Svelte renderer
|
|
9
|
-
*/
|
|
10
|
-
export function createSvelteRenderer(config) {
|
|
11
|
-
const catalog = config.catalog ?? createDefaultCatalog();
|
|
12
|
-
const customComponents = config.components ?? {};
|
|
13
|
-
const store = config.stateStore;
|
|
14
|
-
/**
|
|
15
|
-
* Generate full Svelte component code
|
|
16
|
-
*/
|
|
17
|
-
function generateComponent(root) {
|
|
18
|
-
const script = generateScript(root);
|
|
19
|
-
const template = root.components.map((c) => generateTemplate(c)).join('\n');
|
|
20
|
-
const style = root.css ? `<style>\n${root.css}\n</style>` : '';
|
|
21
|
-
return `<script>
|
|
22
|
-
${script}
|
|
23
|
-
</script>
|
|
24
|
-
|
|
25
|
-
${template}
|
|
26
|
-
|
|
27
|
-
${style}`;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Generate script section
|
|
31
|
-
*/
|
|
32
|
-
function generateScript(root) {
|
|
33
|
-
const lines = [
|
|
34
|
-
'// Auto-generated A2R-IX Svelte component',
|
|
35
|
-
'',
|
|
36
|
-
'// State bindings',
|
|
37
|
-
];
|
|
38
|
-
// Generate state variable declarations
|
|
39
|
-
root.state.variables.forEach((variable) => {
|
|
40
|
-
const defaultValue = variable.default !== undefined
|
|
41
|
-
? JSON.stringify(variable.default)
|
|
42
|
-
: getDefaultForType(variable.type);
|
|
43
|
-
lines.push(`export let ${sanitizeName(variable.path)} = ${defaultValue};`);
|
|
44
|
-
});
|
|
45
|
-
// Generate computed values
|
|
46
|
-
lines.push('');
|
|
47
|
-
lines.push('// Computed values');
|
|
48
|
-
root.state.computed?.forEach((computed) => {
|
|
49
|
-
lines.push(`$: ${computed.name} = ${generateExpression(computed.compute)};`);
|
|
50
|
-
});
|
|
51
|
-
// Generate action handlers
|
|
52
|
-
lines.push('');
|
|
53
|
-
lines.push('// Action handlers');
|
|
54
|
-
root.actions.forEach((action) => {
|
|
55
|
-
lines.push(`function handle_${action.id}(event) {`);
|
|
56
|
-
lines.push(` dispatch('${action.id}', { event, ...${JSON.stringify(action.handler)} });`);
|
|
57
|
-
lines.push('}');
|
|
58
|
-
});
|
|
59
|
-
// Event dispatcher
|
|
60
|
-
if (root.actions.length > 0) {
|
|
61
|
-
lines.unshift("import { createEventDispatcher } from 'svelte';");
|
|
62
|
-
lines.unshift('');
|
|
63
|
-
lines.unshift('const dispatch = createEventDispatcher();');
|
|
64
|
-
}
|
|
65
|
-
return lines.join('\n');
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Generate template for a component
|
|
69
|
-
*/
|
|
70
|
-
function generateTemplate(component, depth = 0) {
|
|
71
|
-
const indent = ' '.repeat(depth);
|
|
72
|
-
// Handle condition
|
|
73
|
-
if (component.condition) {
|
|
74
|
-
const condition = generateExpression(component.condition);
|
|
75
|
-
const inner = generateSingleTemplate(component, depth + 1);
|
|
76
|
-
return `${indent}{#if ${condition}}\n${inner}\n${indent}{/if}`;
|
|
77
|
-
}
|
|
78
|
-
// Handle repeat
|
|
79
|
-
if (component.repeat) {
|
|
80
|
-
return generateRepeatTemplate(component, depth);
|
|
81
|
-
}
|
|
82
|
-
return generateSingleTemplate(component, depth);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Generate single component template (no condition/repeat)
|
|
86
|
-
*/
|
|
87
|
-
function generateSingleTemplate(component, depth) {
|
|
88
|
-
const indent = ' '.repeat(depth);
|
|
89
|
-
const tag = getComponentTag(component.type);
|
|
90
|
-
const props = generateProps(component);
|
|
91
|
-
const events = generateEvents(component);
|
|
92
|
-
const propString = [...props, ...events].join(' ');
|
|
93
|
-
if (component.children && component.children.length > 0) {
|
|
94
|
-
const children = component.children.map((c) => generateTemplate(c, depth + 1)).join('\n');
|
|
95
|
-
return `${indent}<${tag}${propString ? ' ' + propString : ''}>\n${children}\n${indent}</${tag}>`;
|
|
96
|
-
}
|
|
97
|
-
// Self-closing or with text content
|
|
98
|
-
const textContent = component.props?.children ? String(component.props.children) : '';
|
|
99
|
-
if (textContent) {
|
|
100
|
-
return `${indent}<${tag}${propString ? ' ' + propString : ''}>${textContent}</${tag}>`;
|
|
101
|
-
}
|
|
102
|
-
return `${indent}<${tag}${propString ? ' ' + propString : ''} />`;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Generate repeat template
|
|
106
|
-
*/
|
|
107
|
-
function generateRepeatTemplate(component, depth) {
|
|
108
|
-
const indent = ' '.repeat(depth);
|
|
109
|
-
const repeat = component.repeat;
|
|
110
|
-
const tag = getComponentTag(component.type);
|
|
111
|
-
const props = generateProps(component);
|
|
112
|
-
const events = generateEvents(component);
|
|
113
|
-
const propString = [...props, ...events].join(' ');
|
|
114
|
-
const asVar = sanitizeName(repeat.as);
|
|
115
|
-
const indexVar = repeat.indexAs ? sanitizeName(repeat.indexAs) : 'index';
|
|
116
|
-
let eachBlock = `${indent}{#each ${sanitizeName(repeat.items)} as ${asVar}, ${indexVar}`;
|
|
117
|
-
if (repeat.filter) {
|
|
118
|
-
const filterExpr = generateExpression(repeat.filter);
|
|
119
|
-
// Note: Svelte doesn't have built-in filter, we'd need to use a computed
|
|
120
|
-
eachBlock += ` (${filterExpr})`;
|
|
121
|
-
}
|
|
122
|
-
eachBlock += '}';
|
|
123
|
-
// Generate inner content
|
|
124
|
-
let innerContent;
|
|
125
|
-
if (component.children && component.children.length > 0) {
|
|
126
|
-
const children = component.children.map((c) => generateTemplate(c, depth + 1)).join('\n');
|
|
127
|
-
innerContent = `<${tag}${propString ? ' ' + propString : ''}>\n${children}\n${indent} </${tag}>`;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
innerContent = `<${tag}${propString ? ' ' + propString : ''} />`;
|
|
131
|
-
}
|
|
132
|
-
return `${eachBlock}\n${indent} ${innerContent}\n${indent}{/each}`;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Generate props string
|
|
136
|
-
*/
|
|
137
|
-
function generateProps(component) {
|
|
138
|
-
const props = [];
|
|
139
|
-
// Regular props
|
|
140
|
-
Object.entries(component.props || {}).forEach(([key, value]) => {
|
|
141
|
-
if (key !== 'children') {
|
|
142
|
-
if (typeof value === 'string') {
|
|
143
|
-
props.push(`${key}="${escapeHtml(value)}"`);
|
|
144
|
-
}
|
|
145
|
-
else if (typeof value === 'boolean') {
|
|
146
|
-
if (value)
|
|
147
|
-
props.push(key);
|
|
148
|
-
}
|
|
149
|
-
else if (typeof value === 'number') {
|
|
150
|
-
props.push(`${key}={${value}}`);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
props.push(`${key}={${JSON.stringify(value)}}`);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
// Bindings
|
|
158
|
-
component.bindings?.forEach((binding) => {
|
|
159
|
-
const stateVar = sanitizeName(binding.statePath);
|
|
160
|
-
if (binding.direction === 'two-way') {
|
|
161
|
-
props.push(`bind:${binding.prop}={${stateVar}}`);
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
props.push(`${binding.prop}={${stateVar}}`);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
return props;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Generate event handlers
|
|
171
|
-
*/
|
|
172
|
-
function generateEvents(component) {
|
|
173
|
-
const events = [];
|
|
174
|
-
component.events?.forEach((event) => {
|
|
175
|
-
const handler = `handle_${event.action}`;
|
|
176
|
-
const params = event.params ? `({ ...event.detail, ...${JSON.stringify(event.params)} })` : 'event';
|
|
177
|
-
events.push(`on:${getSvelteEventName(event.event)}={() => ${handler}(${params})}`);
|
|
178
|
-
});
|
|
179
|
-
return events;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Get component tag name
|
|
183
|
-
*/
|
|
184
|
-
function getComponentTag(type) {
|
|
185
|
-
// Map built-ins to HTML or custom components
|
|
186
|
-
const tagMap = {
|
|
187
|
-
Box: 'div',
|
|
188
|
-
Stack: 'div',
|
|
189
|
-
Text: 'span',
|
|
190
|
-
Heading: 'h1',
|
|
191
|
-
Paragraph: 'p',
|
|
192
|
-
Button: 'button',
|
|
193
|
-
Input: 'input',
|
|
194
|
-
TextArea: 'textarea',
|
|
195
|
-
Select: 'select',
|
|
196
|
-
Card: 'div',
|
|
197
|
-
Image: 'img',
|
|
198
|
-
Icon: 'span',
|
|
199
|
-
Badge: 'span',
|
|
200
|
-
List: 'ul',
|
|
201
|
-
Table: 'table',
|
|
202
|
-
};
|
|
203
|
-
return customComponents[type] ? type : tagMap[type] || type.toLowerCase();
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Convert event name to Svelte format
|
|
207
|
-
*/
|
|
208
|
-
function getSvelteEventName(event) {
|
|
209
|
-
// Remove 'on' prefix and lowercase
|
|
210
|
-
if (event.startsWith('on')) {
|
|
211
|
-
return event.slice(2).toLowerCase();
|
|
212
|
-
}
|
|
213
|
-
return event.toLowerCase();
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Generate expression string
|
|
217
|
-
*/
|
|
218
|
-
function generateExpression(expr) {
|
|
219
|
-
if (expr === null)
|
|
220
|
-
return 'null';
|
|
221
|
-
if (typeof expr === 'string')
|
|
222
|
-
return sanitizeName(expr);
|
|
223
|
-
if (typeof expr === 'number')
|
|
224
|
-
return String(expr);
|
|
225
|
-
if (typeof expr === 'boolean')
|
|
226
|
-
return String(expr);
|
|
227
|
-
// Handle expression objects
|
|
228
|
-
if (typeof expr === 'object') {
|
|
229
|
-
if ('$path' in expr) {
|
|
230
|
-
return sanitizeName(expr.$path);
|
|
231
|
-
}
|
|
232
|
-
if ('$expr' in expr) {
|
|
233
|
-
return expr.$expr;
|
|
234
|
-
}
|
|
235
|
-
if ('$cond' in expr) {
|
|
236
|
-
const [cond, trueVal, falseVal] = expr.$cond;
|
|
237
|
-
return `${generateExpression(cond)} ? ${generateExpression(trueVal)} : ${generateExpression(falseVal)}`;
|
|
238
|
-
}
|
|
239
|
-
if ('$and' in expr) {
|
|
240
|
-
const arr = expr.$and;
|
|
241
|
-
return arr.map(generateExpression).join(' && ');
|
|
242
|
-
}
|
|
243
|
-
if ('$or' in expr) {
|
|
244
|
-
const arr = expr.$or;
|
|
245
|
-
return arr.map(generateExpression).join(' || ');
|
|
246
|
-
}
|
|
247
|
-
if ('$not' in expr) {
|
|
248
|
-
return `!${generateExpression(expr.$not)}`;
|
|
249
|
-
}
|
|
250
|
-
if ('$eq' in expr) {
|
|
251
|
-
const [a, b] = expr.$eq;
|
|
252
|
-
return `${generateExpression(a)} === ${generateExpression(b)}`;
|
|
253
|
-
}
|
|
254
|
-
if ('$gt' in expr) {
|
|
255
|
-
const [a, b] = expr.$gt;
|
|
256
|
-
return `${generateExpression(a)} > ${generateExpression(b)}`;
|
|
257
|
-
}
|
|
258
|
-
if ('$lt' in expr) {
|
|
259
|
-
const [a, b] = expr.$lt;
|
|
260
|
-
return `${generateExpression(a)} < ${generateExpression(b)}`;
|
|
261
|
-
}
|
|
262
|
-
if ('$add' in expr) {
|
|
263
|
-
const [a, b] = expr.$add;
|
|
264
|
-
return `${generateExpression(a)} + ${generateExpression(b)}`;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return String(expr);
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Get default value for type
|
|
271
|
-
*/
|
|
272
|
-
function getDefaultForType(type) {
|
|
273
|
-
switch (type) {
|
|
274
|
-
case 'string':
|
|
275
|
-
return "''";
|
|
276
|
-
case 'number':
|
|
277
|
-
return '0';
|
|
278
|
-
case 'boolean':
|
|
279
|
-
return 'false';
|
|
280
|
-
case 'array':
|
|
281
|
-
return '[]';
|
|
282
|
-
case 'object':
|
|
283
|
-
return '{}';
|
|
284
|
-
default:
|
|
285
|
-
return 'undefined';
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Sanitize variable name
|
|
290
|
-
*/
|
|
291
|
-
function sanitizeName(path) {
|
|
292
|
-
return path.replace(/\./g, '_').replace(/[^a-zA-Z0-9_]/g, '');
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Escape HTML for attributes
|
|
296
|
-
*/
|
|
297
|
-
function escapeHtml(text) {
|
|
298
|
-
return text
|
|
299
|
-
.replace(/&/g, '&')
|
|
300
|
-
.replace(/</g, '<')
|
|
301
|
-
.replace(/>/g, '>')
|
|
302
|
-
.replace(/"/g, '"')
|
|
303
|
-
.replace(/'/g, ''');
|
|
304
|
-
}
|
|
305
|
-
return {
|
|
306
|
-
generateComponent,
|
|
307
|
-
generateTemplate,
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Compile A2R-IX UI to Svelte component
|
|
312
|
-
*/
|
|
313
|
-
export function compileToSvelte(root, config = {}) {
|
|
314
|
-
const renderer = createSvelteRenderer(config);
|
|
315
|
-
return renderer.generateComponent(root);
|
|
316
|
-
}
|
|
317
|
-
//# sourceMappingURL=renderer.js.map
|