@jxsuite/compiler 0.22.1 → 0.23.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/dist/compiler.js +170 -170
- package/package.json +3 -3
- package/src/shared.js +21 -2
- package/src/targets/compile-client.js +30 -0
- package/src/targets/compile-element.js +39 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Jx static HTML compiler, island detector, and site builder",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@apidevtools/json-schema-ref-parser": "^15.3.5",
|
|
41
|
-
"@jxsuite/parser": "^0.
|
|
42
|
-
"@jxsuite/runtime": "^0.
|
|
41
|
+
"@jxsuite/parser": "^0.23.0",
|
|
42
|
+
"@jxsuite/runtime": "^0.23.0",
|
|
43
43
|
"remark-gfm": "^4.0.1",
|
|
44
44
|
"remark-stringify": "^11.0.0",
|
|
45
45
|
"sharp": "^0.34.5",
|
package/src/shared.js
CHANGED
|
@@ -6,9 +6,17 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { camelToKebab, toCSSText, RESERVED_KEYS } from "@jxsuite/runtime";
|
|
9
|
+
import { compileExpression, isMutating, evaluateExpression } from "@jxsuite/runtime/expression";
|
|
9
10
|
|
|
10
11
|
// Re-export runtime utilities used by submodules
|
|
11
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
camelToKebab,
|
|
14
|
+
toCSSText,
|
|
15
|
+
RESERVED_KEYS,
|
|
16
|
+
compileExpression,
|
|
17
|
+
isMutating,
|
|
18
|
+
evaluateExpression,
|
|
19
|
+
};
|
|
12
20
|
|
|
13
21
|
// CDN defaults
|
|
14
22
|
export const DEFAULT_REACTIVITY_SRC = "https://esm.sh/@vue/reactivity@3.5.32";
|
|
@@ -231,7 +239,7 @@ export function buildInitialScope(defs = {}, parentScope = null) {
|
|
|
231
239
|
setOwnScopeValue(scope, key, cloneValue(d.default));
|
|
232
240
|
continue;
|
|
233
241
|
}
|
|
234
|
-
if (!d.$prototype && !isSchemaOnly(d)) {
|
|
242
|
+
if (!d.$prototype && !("$expression" in d) && !isSchemaOnly(d)) {
|
|
235
243
|
setOwnScopeValue(scope, key, cloneValue(d));
|
|
236
244
|
}
|
|
237
245
|
}
|
|
@@ -243,6 +251,17 @@ export function buildInitialScope(defs = {}, parentScope = null) {
|
|
|
243
251
|
}
|
|
244
252
|
if (!def || typeof def !== "object") continue;
|
|
245
253
|
const d = /** @type {JxStateObject & JxPrototypeDef} */ (def);
|
|
254
|
+
if ("$expression" in d) {
|
|
255
|
+
const node = /** @type {any} */ (d).$expression;
|
|
256
|
+
if (isMutating(node.operator)) {
|
|
257
|
+
setOwnScopeValue(scope, key, (/** @type {any} */ s, /** @type {any} */ event) =>
|
|
258
|
+
evaluateExpression(node, s, event),
|
|
259
|
+
);
|
|
260
|
+
} else {
|
|
261
|
+
defineLazyScopeValue(scope, key, () => evaluateExpression(node, scope, null));
|
|
262
|
+
}
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
246
265
|
if (d.$prototype === "Function") {
|
|
247
266
|
if (d.body) {
|
|
248
267
|
const fn = new Function("state", ...(d.parameters ?? d.arguments ?? []), d.body);
|
|
@@ -23,6 +23,8 @@ import {
|
|
|
23
23
|
escapeHtml,
|
|
24
24
|
DEFAULT_REACTIVITY_SRC,
|
|
25
25
|
DEFAULT_LIT_HTML_SRC,
|
|
26
|
+
compileExpression,
|
|
27
|
+
isMutating,
|
|
26
28
|
} from "../shared.js";
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -85,6 +87,19 @@ export function compileClient(raw, opts) {
|
|
|
85
87
|
|
|
86
88
|
const d = /** @type {JxMutableNode} */ (def);
|
|
87
89
|
|
|
90
|
+
// $expression: Shape 5
|
|
91
|
+
if ("$expression" in d) {
|
|
92
|
+
const node = /** @type {any} */ (d).$expression;
|
|
93
|
+
if (isMutating(node.operator)) {
|
|
94
|
+
const compiled = compileExpression(node, { statePrefix: "state", eventParam: "e" });
|
|
95
|
+
onEntries.push([key, { args: ["state", "e"], body: compiled }]);
|
|
96
|
+
} else {
|
|
97
|
+
const compiled = compileExpression(node, { statePrefix: "state", eventParam: "e" });
|
|
98
|
+
computedEntries.push([key, `() => ${compiled}`]);
|
|
99
|
+
}
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
88
103
|
// $prototype: "Function"
|
|
89
104
|
if (d.$prototype === "Function") {
|
|
90
105
|
const args = d.parameters ?? d.arguments;
|
|
@@ -274,6 +289,15 @@ function buildClientNode(def, raw, context, bindings, handlers, counter) {
|
|
|
274
289
|
bindAttrs.push(`@${eventName}="${key}"`);
|
|
275
290
|
handlers.set(key, { args: v.parameters ?? v.arguments ?? ["state", "event"], body: v.body });
|
|
276
291
|
needsBind = true;
|
|
292
|
+
} else if (val && typeof val === "object" && "$expression" in /** @type {any} */ (val)) {
|
|
293
|
+
const key = `_h${counter.h++}`;
|
|
294
|
+
bindAttrs.push(`@${eventName}="${key}"`);
|
|
295
|
+
const compiled = compileExpression(/** @type {any} */ (val).$expression, {
|
|
296
|
+
statePrefix: "state",
|
|
297
|
+
eventParam: "e",
|
|
298
|
+
});
|
|
299
|
+
handlers.set(key, { args: ["state", "e"], body: compiled });
|
|
300
|
+
needsBind = true;
|
|
277
301
|
}
|
|
278
302
|
}
|
|
279
303
|
|
|
@@ -500,6 +524,12 @@ function emitLitMapTemplate(def) {
|
|
|
500
524
|
) {
|
|
501
525
|
const body = mapRefsToLit(/** @type {string} */ (/** @type {JxMutableNode} */ (val).body));
|
|
502
526
|
attrs += " @" + eventName + "=${(e) => { " + body + " }}";
|
|
527
|
+
} else if (val && typeof val === "object" && "$expression" in /** @type {any} */ (val)) {
|
|
528
|
+
const compiled = compileExpression(/** @type {any} */ (val).$expression, {
|
|
529
|
+
statePrefix: "state",
|
|
530
|
+
eventParam: "e",
|
|
531
|
+
});
|
|
532
|
+
attrs += " @" + eventName + "=${(e) => { state.$map = { item, index }; " + compiled + "; }}";
|
|
503
533
|
}
|
|
504
534
|
}
|
|
505
535
|
|
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { camelToKebab, RESERVED_KEYS } from "@jxsuite/runtime";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
escapeHtml,
|
|
11
|
+
tagNameToClassName,
|
|
12
|
+
isSchemaOnly,
|
|
13
|
+
collectStyles,
|
|
14
|
+
compileExpression,
|
|
15
|
+
isMutating,
|
|
16
|
+
} from "../shared.js";
|
|
10
17
|
|
|
11
18
|
/**
|
|
12
19
|
* Compile a Jx custom element document to a JS module string.
|
|
@@ -230,7 +237,14 @@ export function emitElementModule(doc, className, elementImports) {
|
|
|
230
237
|
|
|
231
238
|
for (const [key, def] of Object.entries(defs)) {
|
|
232
239
|
const d = /** @type {JxMutableNode} */ (def);
|
|
233
|
-
if (d && typeof d === "object" && !Array.isArray(d) &&
|
|
240
|
+
if (d && typeof d === "object" && !Array.isArray(d) && "$expression" in d) {
|
|
241
|
+
const node = /** @type {any} */ (d).$expression;
|
|
242
|
+
if (isMutating(node.operator)) {
|
|
243
|
+
functionEntries.push([key, d]);
|
|
244
|
+
} else {
|
|
245
|
+
computedEntries.push([key, d]);
|
|
246
|
+
}
|
|
247
|
+
} else if (d && typeof d === "object" && !Array.isArray(d) && d.$prototype === "Function") {
|
|
234
248
|
if (typeof d.body === "string" && d.body.includes("return")) {
|
|
235
249
|
computedEntries.push([key, d]);
|
|
236
250
|
} else {
|
|
@@ -255,7 +269,10 @@ export function emitElementModule(doc, className, elementImports) {
|
|
|
255
269
|
// Emit functions: this.state.fnName = (state) => { body } or imported $src function
|
|
256
270
|
for (const [key, def] of functionEntries) {
|
|
257
271
|
lines.push("");
|
|
258
|
-
if (def
|
|
272
|
+
if ("$expression" in def) {
|
|
273
|
+
const compiled = compileExpression(def.$expression, { statePrefix: "s", eventParam: "e" });
|
|
274
|
+
lines.push(` this.state.${key} = (s, e) => { ${compiled}; };`);
|
|
275
|
+
} else if (def.$src) {
|
|
259
276
|
// $src function — wrap imported function so it receives state
|
|
260
277
|
const args = def.parameters ?? def.arguments ?? ["state"];
|
|
261
278
|
const paramList = args.join(", ");
|
|
@@ -272,7 +289,13 @@ export function emitElementModule(doc, className, elementImports) {
|
|
|
272
289
|
// Emit computed signals — $src or inline body
|
|
273
290
|
for (const [key, def] of computedEntries) {
|
|
274
291
|
lines.push("");
|
|
275
|
-
if (def
|
|
292
|
+
if ("$expression" in def) {
|
|
293
|
+
const compiled = compileExpression(def.$expression, {
|
|
294
|
+
statePrefix: "this.state",
|
|
295
|
+
eventParam: "e",
|
|
296
|
+
});
|
|
297
|
+
lines.push(` this.state.${key} = computed(() => ${compiled});`);
|
|
298
|
+
} else if (def.$src) {
|
|
276
299
|
lines.push(` this.state.${key} = computed(() => ${key}(this.state));`);
|
|
277
300
|
} else {
|
|
278
301
|
lines.push(` this.state.${key} = computed(() => {`);
|
|
@@ -491,6 +514,12 @@ function emitLitNode(def, indent) {
|
|
|
491
514
|
parts.push(
|
|
492
515
|
`@${eventName}="\${(e) => ${refToExpr(/** @type {string} */ (/** @type {JxMutableNode} */ (val).$ref))}(s, e)}"`,
|
|
493
516
|
);
|
|
517
|
+
} else if (val && typeof val === "object" && "$expression" in /** @type {any} */ (val)) {
|
|
518
|
+
const compiled = compileExpression(/** @type {any} */ (val).$expression, {
|
|
519
|
+
statePrefix: "s",
|
|
520
|
+
eventParam: "e",
|
|
521
|
+
});
|
|
522
|
+
parts.push(`@${eventName}="\${(e) => { ${compiled}; }}"`);
|
|
494
523
|
} else if (
|
|
495
524
|
val &&
|
|
496
525
|
typeof val === "object" &&
|
|
@@ -561,6 +590,12 @@ function emitMappedArray(arrayDef, indent) {
|
|
|
561
590
|
parts.push(
|
|
562
591
|
`@${eventName}="\${(e) => ${refToExpr(/** @type {string} */ (/** @type {JxMutableNode} */ (val).$ref))}(s, e)}"`,
|
|
563
592
|
);
|
|
593
|
+
} else if (val && typeof val === "object" && "$expression" in /** @type {any} */ (val)) {
|
|
594
|
+
const compiled = compileExpression(/** @type {any} */ (val).$expression, {
|
|
595
|
+
statePrefix: "s",
|
|
596
|
+
eventParam: "e",
|
|
597
|
+
});
|
|
598
|
+
parts.push(`@${eventName}="\${(e) => { ${compiled}; }}"`);
|
|
564
599
|
}
|
|
565
600
|
}
|
|
566
601
|
|