@constela/runtime 0.19.1 → 0.19.3
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 +38 -0
- package/dist/index.js +45 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -243,6 +243,44 @@ Features:
|
|
|
243
243
|
- Dual theme support (light/dark)
|
|
244
244
|
- Built-in copy button
|
|
245
245
|
|
|
246
|
+
### Component Local State
|
|
247
|
+
|
|
248
|
+
Components can have their own independent local state and actions:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"components": {
|
|
253
|
+
"Counter": {
|
|
254
|
+
"localState": {
|
|
255
|
+
"count": { "type": "number", "initial": 0 }
|
|
256
|
+
},
|
|
257
|
+
"localActions": [
|
|
258
|
+
{
|
|
259
|
+
"name": "increment",
|
|
260
|
+
"steps": [{ "do": "update", "target": "count", "operation": "increment" }]
|
|
261
|
+
}
|
|
262
|
+
],
|
|
263
|
+
"view": {
|
|
264
|
+
"kind": "element",
|
|
265
|
+
"tag": "button",
|
|
266
|
+
"props": { "onClick": { "event": "click", "action": "increment" } },
|
|
267
|
+
"children": [
|
|
268
|
+
{ "kind": "text", "value": { "expr": "state", "name": "count" } }
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Features:
|
|
277
|
+
- Each instance has independent state
|
|
278
|
+
- Local actions operate on local state only
|
|
279
|
+
- `state` expressions check local state first, then fall back to global
|
|
280
|
+
- Supported steps: `set`, `update`, `setPath`
|
|
281
|
+
|
|
282
|
+
Use cases: Accordions, dropdowns, form fields, toggles, tooltips
|
|
283
|
+
|
|
246
284
|
### Hydration
|
|
247
285
|
|
|
248
286
|
Server-rendered HTML is hydrated on the client without DOM reconstruction:
|
package/dist/index.js
CHANGED
|
@@ -1337,6 +1337,9 @@ async function executeStep(step, ctx) {
|
|
|
1337
1337
|
case "focus":
|
|
1338
1338
|
await executeFocusStep(step, ctx);
|
|
1339
1339
|
break;
|
|
1340
|
+
case "generate":
|
|
1341
|
+
await executeGenerateStep(step, ctx);
|
|
1342
|
+
break;
|
|
1340
1343
|
}
|
|
1341
1344
|
}
|
|
1342
1345
|
async function executeSetStep(target, value, ctx) {
|
|
@@ -1834,6 +1837,48 @@ async function executeFocusStep(step, ctx) {
|
|
|
1834
1837
|
}
|
|
1835
1838
|
}
|
|
1836
1839
|
}
|
|
1840
|
+
async function executeGenerateStep(step, ctx) {
|
|
1841
|
+
const { createDslGenerator } = await import("@constela/ai");
|
|
1842
|
+
const evalCtx = createEvalContext(ctx);
|
|
1843
|
+
const promptValue = evaluate(step.prompt, evalCtx);
|
|
1844
|
+
try {
|
|
1845
|
+
const generator = createDslGenerator({
|
|
1846
|
+
provider: step.provider
|
|
1847
|
+
});
|
|
1848
|
+
const result = await generator.generate({
|
|
1849
|
+
prompt: promptValue,
|
|
1850
|
+
output: step.output
|
|
1851
|
+
});
|
|
1852
|
+
ctx.locals[step.result] = result.dsl;
|
|
1853
|
+
if (!result.validated && result.errors && result.errors.length > 0) {
|
|
1854
|
+
ctx.locals["error"] = {
|
|
1855
|
+
message: `AI generated DSL validation failed: ${result.errors.join(", ")}`,
|
|
1856
|
+
name: "ValidationError"
|
|
1857
|
+
};
|
|
1858
|
+
if (step.onError) {
|
|
1859
|
+
for (const errorStep of step.onError) {
|
|
1860
|
+
await executeStep(errorStep, ctx);
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
if (step.onSuccess) {
|
|
1866
|
+
for (const successStep of step.onSuccess) {
|
|
1867
|
+
await executeStep(successStep, ctx);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
} catch (err) {
|
|
1871
|
+
ctx.locals["error"] = {
|
|
1872
|
+
message: err instanceof Error ? err.message : String(err),
|
|
1873
|
+
name: err instanceof Error ? err.name : "Error"
|
|
1874
|
+
};
|
|
1875
|
+
if (step.onError) {
|
|
1876
|
+
for (const errorStep of step.onError) {
|
|
1877
|
+
await executeStep(errorStep, ctx);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1837
1882
|
|
|
1838
1883
|
// ../../node_modules/.pnpm/marked@17.0.1/node_modules/marked/lib/marked.esm.js
|
|
1839
1884
|
function L() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constela/runtime",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.3",
|
|
4
4
|
"description": "Runtime DOM renderer for Constela UI framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
"dompurify": "^3.3.1",
|
|
19
19
|
"marked": "^17.0.1",
|
|
20
20
|
"shiki": "^3.20.0",
|
|
21
|
-
"@constela/
|
|
22
|
-
"@constela/core": "0.
|
|
21
|
+
"@constela/ai": "1.0.0",
|
|
22
|
+
"@constela/core": "0.16.0",
|
|
23
|
+
"@constela/compiler": "0.14.5"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@types/dompurify": "^3.2.0",
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
"tsup": "^8.0.0",
|
|
30
31
|
"typescript": "^5.3.0",
|
|
31
32
|
"vitest": "^2.0.0",
|
|
32
|
-
"@constela/server": "
|
|
33
|
+
"@constela/server": "12.0.0"
|
|
33
34
|
},
|
|
34
35
|
"engines": {
|
|
35
36
|
"node": ">=20.0.0"
|