@lokascript/compilation-service 2.0.0 → 2.2.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/{chunk-HMLY7DHA.js → chunk-GBPMR66W.js} +8 -1
- package/dist/{chunk-ODJIDVMN.js → chunk-PVQF6QYP.js} +5 -118
- package/dist/chunk-PVQF6QYP.js.map +1 -0
- package/dist/{chunk-JDOSUTCM.js → chunk-ZQ3GX55O.js} +2 -2
- package/dist/{core-parser-adapter-VCJB52SO-MDHRIVZ7.js → core-parser-adapter-VCJB52SO-7T2PARW4.js} +3 -3
- package/dist/{dist-ICUX26U7.js → dist-A6VWPCPB.js} +498 -15
- package/dist/dist-A6VWPCPB.js.map +1 -0
- package/dist/{dist-JOIDNRL3.js → dist-CYO3JGTJ.js} +32925 -24218
- package/dist/dist-CYO3JGTJ.js.map +1 -0
- package/dist/http.cjs +13467 -4407
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +2 -1
- package/dist/http.d.ts +2 -1
- package/dist/http.js +2 -2
- package/dist/index.cjs +13472 -4409
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -23
- package/dist/index.d.ts +4 -23
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/{semantic-adapter-7HTMTO75-MFFBR7K3.js → semantic-adapter-7HTMTO75-WVF6UAHI.js} +2 -2
- package/dist/{service-891L1MYk.d.cts → service-qk1aChG9.d.cts} +6 -25
- package/dist/{service-891L1MYk.d.ts → service-qk1aChG9.d.ts} +6 -25
- package/package.json +4 -2
- package/dist/chunk-ODJIDVMN.js.map +0 -1
- package/dist/dist-ICUX26U7.js.map +0 -1
- package/dist/dist-JOIDNRL3.js.map +0 -1
- /package/dist/{chunk-HMLY7DHA.js.map → chunk-GBPMR66W.js.map} +0 -0
- /package/dist/{chunk-JDOSUTCM.js.map → chunk-ZQ3GX55O.js.map} +0 -0
- /package/dist/{core-parser-adapter-VCJB52SO-MDHRIVZ7.js.map → core-parser-adapter-VCJB52SO-7T2PARW4.js.map} +0 -0
- /package/dist/{semantic-adapter-7HTMTO75-MFFBR7K3.js.map → semantic-adapter-7HTMTO75-WVF6UAHI.js.map} +0 -0
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CoreParserAdapter,
|
|
3
3
|
createCoreParserAdapter
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZQ3GX55O.js";
|
|
5
5
|
import {
|
|
6
6
|
SemanticParserAdapter,
|
|
7
7
|
createSemanticAdapter
|
|
8
8
|
} from "./chunk-CY26COTT.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-GBPMR66W.js";
|
|
10
10
|
|
|
11
11
|
// ../aot-compiler/dist/index.js
|
|
12
|
+
import {
|
|
13
|
+
isExplicitSyntax,
|
|
14
|
+
parseExplicit,
|
|
15
|
+
fromProtocolJSON,
|
|
16
|
+
semanticNodeToRuntimeAST
|
|
17
|
+
} from "@lokascript/framework";
|
|
12
18
|
var DEFAULT_OPTIONS = {
|
|
13
19
|
attributeNames: ["_", "data-hs", "data-hyperscript"],
|
|
14
20
|
includeScriptTags: true,
|
|
@@ -683,6 +689,166 @@ function analyze(ast) {
|
|
|
683
689
|
const analyzer = new Analyzer();
|
|
684
690
|
return analyzer.analyze(ast);
|
|
685
691
|
}
|
|
692
|
+
var CLASS_COMMANDS = /* @__PURE__ */ new Set(["add", "remove", "toggle"]);
|
|
693
|
+
function extractClassOp(node) {
|
|
694
|
+
if (node.type !== "command") return null;
|
|
695
|
+
const cmd = node;
|
|
696
|
+
if (!CLASS_COMMANDS.has(cmd.name)) return null;
|
|
697
|
+
const args = cmd.args ?? [];
|
|
698
|
+
if (args.length === 0) return null;
|
|
699
|
+
const arg = args[0];
|
|
700
|
+
if (arg.type !== "selector") return null;
|
|
701
|
+
const selector = arg.value;
|
|
702
|
+
if (!selector.startsWith(".")) return null;
|
|
703
|
+
const className = selector.slice(1);
|
|
704
|
+
if (!className) return null;
|
|
705
|
+
return {
|
|
706
|
+
command: cmd.name,
|
|
707
|
+
className,
|
|
708
|
+
hasExplicitTarget: !!cmd.target
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
function isSameTarget(a, b) {
|
|
712
|
+
if (a.type !== "command" || b.type !== "command") return false;
|
|
713
|
+
const cmdA = a;
|
|
714
|
+
const cmdB = b;
|
|
715
|
+
if (!cmdA.target && !cmdB.target) return true;
|
|
716
|
+
if (cmdA.target && cmdB.target) {
|
|
717
|
+
return getTargetKey(cmdA.target) === getTargetKey(cmdB.target);
|
|
718
|
+
}
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
function getTargetKey(target) {
|
|
722
|
+
if (target.type === "selector") {
|
|
723
|
+
return `selector:${target.value}`;
|
|
724
|
+
}
|
|
725
|
+
if (target.type === "identifier") {
|
|
726
|
+
return `identifier:${target.value}`;
|
|
727
|
+
}
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
function resolveTarget(cmd) {
|
|
731
|
+
if (!cmd.target) return "_ctx.me";
|
|
732
|
+
if (cmd.target.type === "selector") {
|
|
733
|
+
const sel = cmd.target.value;
|
|
734
|
+
if (sel.startsWith("#") && !sel.includes(" ") && !sel.includes(".")) {
|
|
735
|
+
return `document.getElementById('${sel.slice(1)}')`;
|
|
736
|
+
}
|
|
737
|
+
return `document.querySelector('${sel}')`;
|
|
738
|
+
}
|
|
739
|
+
if (cmd.target.type === "identifier") {
|
|
740
|
+
const val = cmd.target.value;
|
|
741
|
+
if (val === "me") return "_ctx.me";
|
|
742
|
+
return val;
|
|
743
|
+
}
|
|
744
|
+
return "_ctx.me";
|
|
745
|
+
}
|
|
746
|
+
function createBatchNode(run) {
|
|
747
|
+
const adds = [];
|
|
748
|
+
const removes = [];
|
|
749
|
+
const toggles = [];
|
|
750
|
+
for (const node of run) {
|
|
751
|
+
const op = extractClassOp(node);
|
|
752
|
+
switch (op.command) {
|
|
753
|
+
case "add":
|
|
754
|
+
adds.push(op.className);
|
|
755
|
+
break;
|
|
756
|
+
case "remove":
|
|
757
|
+
removes.push(op.className);
|
|
758
|
+
break;
|
|
759
|
+
case "toggle":
|
|
760
|
+
toggles.push(op.className);
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
const target = resolveTarget(run[0]);
|
|
765
|
+
return {
|
|
766
|
+
type: "batchedClassOps",
|
|
767
|
+
target,
|
|
768
|
+
adds,
|
|
769
|
+
removes,
|
|
770
|
+
toggles
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
function batchBody(nodes) {
|
|
774
|
+
const result = [];
|
|
775
|
+
let currentRun = [];
|
|
776
|
+
function flushRun() {
|
|
777
|
+
if (currentRun.length >= 2) {
|
|
778
|
+
result.push(createBatchNode(currentRun));
|
|
779
|
+
} else if (currentRun.length === 1) {
|
|
780
|
+
result.push(currentRun[0]);
|
|
781
|
+
}
|
|
782
|
+
currentRun = [];
|
|
783
|
+
}
|
|
784
|
+
for (const node of nodes) {
|
|
785
|
+
const op = extractClassOp(node);
|
|
786
|
+
if (op) {
|
|
787
|
+
if (currentRun.length > 0 && isSameTarget(currentRun[0], node)) {
|
|
788
|
+
currentRun.push(node);
|
|
789
|
+
} else {
|
|
790
|
+
flushRun();
|
|
791
|
+
currentRun = [node];
|
|
792
|
+
}
|
|
793
|
+
} else {
|
|
794
|
+
flushRun();
|
|
795
|
+
result.push(node);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
flushRun();
|
|
799
|
+
return result;
|
|
800
|
+
}
|
|
801
|
+
function walkAndBatch(node) {
|
|
802
|
+
switch (node.type) {
|
|
803
|
+
case "event": {
|
|
804
|
+
const event = node;
|
|
805
|
+
if (event.body && event.body.length > 0) {
|
|
806
|
+
return { ...event, body: batchBody(event.body).map(walkAndBatch) };
|
|
807
|
+
}
|
|
808
|
+
return node;
|
|
809
|
+
}
|
|
810
|
+
case "if": {
|
|
811
|
+
const ifNode = node;
|
|
812
|
+
const result = { ...ifNode };
|
|
813
|
+
result.thenBranch = batchBody(ifNode.thenBranch).map(walkAndBatch);
|
|
814
|
+
if (ifNode.elseBranch) {
|
|
815
|
+
result.elseBranch = batchBody(ifNode.elseBranch).map(walkAndBatch);
|
|
816
|
+
}
|
|
817
|
+
if (ifNode.elseIfBranches) {
|
|
818
|
+
result.elseIfBranches = ifNode.elseIfBranches.map((branch) => ({
|
|
819
|
+
condition: branch.condition,
|
|
820
|
+
body: batchBody(branch.body).map(walkAndBatch)
|
|
821
|
+
}));
|
|
822
|
+
}
|
|
823
|
+
return result;
|
|
824
|
+
}
|
|
825
|
+
case "repeat": {
|
|
826
|
+
const repeat = node;
|
|
827
|
+
return { ...repeat, body: batchBody(repeat.body).map(walkAndBatch) };
|
|
828
|
+
}
|
|
829
|
+
case "foreach": {
|
|
830
|
+
const forEach = node;
|
|
831
|
+
return { ...forEach, body: batchBody(forEach.body).map(walkAndBatch) };
|
|
832
|
+
}
|
|
833
|
+
case "while": {
|
|
834
|
+
const whileNode = node;
|
|
835
|
+
return { ...whileNode, body: batchBody(whileNode.body).map(walkAndBatch) };
|
|
836
|
+
}
|
|
837
|
+
default:
|
|
838
|
+
return node;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
var ClassBatchingPass = class {
|
|
842
|
+
constructor() {
|
|
843
|
+
this.name = "class-batching";
|
|
844
|
+
}
|
|
845
|
+
shouldRun(analysis) {
|
|
846
|
+
return analysis.commandsUsed.has("add") || analysis.commandsUsed.has("remove") || analysis.commandsUsed.has("toggle");
|
|
847
|
+
}
|
|
848
|
+
transform(ast, _analysis) {
|
|
849
|
+
return walkAndBatch(ast);
|
|
850
|
+
}
|
|
851
|
+
};
|
|
686
852
|
var ConstantFoldingPass = class {
|
|
687
853
|
constructor() {
|
|
688
854
|
this.name = "constant-folding";
|
|
@@ -1007,6 +1173,7 @@ var OptimizationPipeline = class {
|
|
|
1007
1173
|
new ConstantFoldingPass(),
|
|
1008
1174
|
new SelectorCachingPass(),
|
|
1009
1175
|
new DeadCodeEliminationPass(),
|
|
1176
|
+
new ClassBatchingPass(),
|
|
1010
1177
|
new LoopUnrollingPass()
|
|
1011
1178
|
];
|
|
1012
1179
|
}
|
|
@@ -1039,12 +1206,184 @@ var OptimizationPipeline = class {
|
|
|
1039
1206
|
}
|
|
1040
1207
|
};
|
|
1041
1208
|
function createOptimizer() {
|
|
1042
|
-
return new OptimizationPipeline();
|
|
1209
|
+
return /* @__PURE__ */ new OptimizationPipeline();
|
|
1043
1210
|
}
|
|
1044
1211
|
function optimize(ast, analysis, level = 2) {
|
|
1045
1212
|
const pipeline = new OptimizationPipeline();
|
|
1046
1213
|
return pipeline.optimize(ast, analysis, level);
|
|
1047
1214
|
}
|
|
1215
|
+
function classifyCommand(node) {
|
|
1216
|
+
if (node.type !== "command") return null;
|
|
1217
|
+
const cmd = node;
|
|
1218
|
+
switch (cmd.name) {
|
|
1219
|
+
case "add":
|
|
1220
|
+
return classifyAddCommand(cmd);
|
|
1221
|
+
case "remove":
|
|
1222
|
+
return classifyRemoveCommand(cmd);
|
|
1223
|
+
case "put":
|
|
1224
|
+
return classifyPutCommand(cmd);
|
|
1225
|
+
case "set":
|
|
1226
|
+
return classifySetCommand(cmd);
|
|
1227
|
+
default:
|
|
1228
|
+
return null;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
function getIdTarget(cmd) {
|
|
1232
|
+
if (!cmd.target) return null;
|
|
1233
|
+
if (cmd.target.type !== "selector") return null;
|
|
1234
|
+
const sel = cmd.target.value;
|
|
1235
|
+
if (!sel.startsWith("#")) return null;
|
|
1236
|
+
return sel.slice(1);
|
|
1237
|
+
}
|
|
1238
|
+
function classifyAddCommand(cmd) {
|
|
1239
|
+
const targetId = getIdTarget(cmd);
|
|
1240
|
+
if (!targetId) return null;
|
|
1241
|
+
const args = cmd.args ?? [];
|
|
1242
|
+
if (args.length === 0) return null;
|
|
1243
|
+
const arg = args[0];
|
|
1244
|
+
if (arg.type !== "selector") return null;
|
|
1245
|
+
const val = arg.value;
|
|
1246
|
+
if (!val.startsWith(".")) return null;
|
|
1247
|
+
return { type: "addClass", targetId, value: val.slice(1) };
|
|
1248
|
+
}
|
|
1249
|
+
function classifyRemoveCommand(cmd) {
|
|
1250
|
+
const targetId = getIdTarget(cmd);
|
|
1251
|
+
if (!targetId) return null;
|
|
1252
|
+
const args = cmd.args ?? [];
|
|
1253
|
+
if (args.length === 0) return null;
|
|
1254
|
+
const arg = args[0];
|
|
1255
|
+
if (arg.type !== "selector") return null;
|
|
1256
|
+
const val = arg.value;
|
|
1257
|
+
if (!val.startsWith(".")) return null;
|
|
1258
|
+
return { type: "removeClass", targetId, value: val.slice(1) };
|
|
1259
|
+
}
|
|
1260
|
+
function classifyPutCommand(cmd) {
|
|
1261
|
+
const targetId = getIdTarget(cmd);
|
|
1262
|
+
if (!targetId) return null;
|
|
1263
|
+
const args = cmd.args ?? [];
|
|
1264
|
+
if (args.length === 0) return null;
|
|
1265
|
+
const arg = args[0];
|
|
1266
|
+
if (arg.type !== "literal") return null;
|
|
1267
|
+
const val = arg.value;
|
|
1268
|
+
if (typeof val !== "string") return null;
|
|
1269
|
+
return { type: "putContent", targetId, value: val };
|
|
1270
|
+
}
|
|
1271
|
+
function classifySetCommand(cmd) {
|
|
1272
|
+
const targetId = getIdTarget(cmd);
|
|
1273
|
+
if (!targetId) return null;
|
|
1274
|
+
const args = cmd.args ?? [];
|
|
1275
|
+
if (args.length < 2) return null;
|
|
1276
|
+
const attrArg = args[0];
|
|
1277
|
+
if (attrArg.type !== "identifier") return null;
|
|
1278
|
+
const attrValue = attrArg.value;
|
|
1279
|
+
if (!attrValue || !attrValue.startsWith("@")) return null;
|
|
1280
|
+
const attrName = attrValue.slice(1);
|
|
1281
|
+
const valArg = args[1];
|
|
1282
|
+
if (valArg.type !== "literal") return null;
|
|
1283
|
+
const val = valArg.value;
|
|
1284
|
+
if (typeof val !== "string" && typeof val !== "number") return null;
|
|
1285
|
+
return { type: "setAttribute", targetId, value: String(val), attrName };
|
|
1286
|
+
}
|
|
1287
|
+
function classifyInitCommands(commands) {
|
|
1288
|
+
const pure = [];
|
|
1289
|
+
const impure = [];
|
|
1290
|
+
for (let i = 0; i < commands.length; i++) {
|
|
1291
|
+
const classified = classifyCommand(commands[i]);
|
|
1292
|
+
if (classified) {
|
|
1293
|
+
pure.push({ index: i, command: classified });
|
|
1294
|
+
} else {
|
|
1295
|
+
impure.push({ index: i, node: commands[i] });
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
return { pure, impure };
|
|
1299
|
+
}
|
|
1300
|
+
function applyPureCommand(html, cmd) {
|
|
1301
|
+
switch (cmd.type) {
|
|
1302
|
+
case "addClass":
|
|
1303
|
+
return addClassToElement(html, cmd.targetId, cmd.value);
|
|
1304
|
+
case "removeClass":
|
|
1305
|
+
return removeClassFromElement(html, cmd.targetId, cmd.value);
|
|
1306
|
+
case "putContent":
|
|
1307
|
+
return putContentIntoElement(html, cmd.targetId, cmd.value);
|
|
1308
|
+
case "setAttribute":
|
|
1309
|
+
return setAttributeOnElement(html, cmd.targetId, cmd.attrName, cmd.value);
|
|
1310
|
+
default:
|
|
1311
|
+
return html;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
function transformElementById(html, id, transform) {
|
|
1315
|
+
const idPattern = new RegExp(`(<[^>]*\\bid=["']${escapeRegExp(id)}["'][^>]*>)`, "i");
|
|
1316
|
+
const match = html.match(idPattern);
|
|
1317
|
+
if (!match) return html;
|
|
1318
|
+
return html.replace(match[1], transform(match[1]));
|
|
1319
|
+
}
|
|
1320
|
+
function addClassToElement(html, id, className) {
|
|
1321
|
+
return transformElementById(html, id, (tag) => {
|
|
1322
|
+
const classMatch = tag.match(/\bclass=["']([^"']*)["']/i);
|
|
1323
|
+
if (classMatch) {
|
|
1324
|
+
const existing = classMatch[1];
|
|
1325
|
+
const classes = existing.split(/\s+/).filter(Boolean);
|
|
1326
|
+
if (!classes.includes(className)) {
|
|
1327
|
+
classes.push(className);
|
|
1328
|
+
}
|
|
1329
|
+
return tag.replace(classMatch[0], `class="${classes.join(" ")}"`);
|
|
1330
|
+
}
|
|
1331
|
+
return tag.replace(/>$/, ` class="${className}">`);
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
function removeClassFromElement(html, id, className) {
|
|
1335
|
+
return transformElementById(html, id, (tag) => {
|
|
1336
|
+
const classMatch = tag.match(/\bclass=["']([^"']*)["']/i);
|
|
1337
|
+
if (!classMatch) return tag;
|
|
1338
|
+
const classes = classMatch[1].split(/\s+/).filter((c) => c !== className);
|
|
1339
|
+
if (classes.length === 0) {
|
|
1340
|
+
return tag.replace(classMatch[0], "").replace(/\s+>/, ">");
|
|
1341
|
+
}
|
|
1342
|
+
return tag.replace(classMatch[0], `class="${classes.join(" ")}"`);
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
function putContentIntoElement(html, id, content) {
|
|
1346
|
+
const idPattern = new RegExp(
|
|
1347
|
+
`(<[a-zA-Z][^>]*\\bid=["']${escapeRegExp(id)}["'][^>]*>)((?:(?!<\\/[a-zA-Z]).)*?)(<\\/[a-zA-Z][^>]*>)`,
|
|
1348
|
+
"is"
|
|
1349
|
+
);
|
|
1350
|
+
const match = html.match(idPattern);
|
|
1351
|
+
if (!match) return html;
|
|
1352
|
+
return html.replace(match[0], `${match[1]}${escapeHtml(content)}${match[3]}`);
|
|
1353
|
+
}
|
|
1354
|
+
function setAttributeOnElement(html, id, attrName, value) {
|
|
1355
|
+
return transformElementById(html, id, (tag) => {
|
|
1356
|
+
const attrPattern = new RegExp(`\\b${escapeRegExp(attrName)}=["'][^"']*["']`, "i");
|
|
1357
|
+
const attrMatch = tag.match(attrPattern);
|
|
1358
|
+
if (attrMatch) {
|
|
1359
|
+
return tag.replace(attrMatch[0], `${attrName}="${escapeHtml(value)}"`);
|
|
1360
|
+
}
|
|
1361
|
+
return tag.replace(/>$/, ` ${attrName}="${escapeHtml(value)}">`);
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
function escapeRegExp(str) {
|
|
1365
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1366
|
+
}
|
|
1367
|
+
function escapeHtml(str) {
|
|
1368
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1369
|
+
}
|
|
1370
|
+
function preRenderInitBlock(html, initCommands) {
|
|
1371
|
+
const { pure, impure } = classifyInitCommands(initCommands);
|
|
1372
|
+
let modifiedHtml = html;
|
|
1373
|
+
let preRenderedCount = 0;
|
|
1374
|
+
for (const { command } of pure) {
|
|
1375
|
+
const before = modifiedHtml;
|
|
1376
|
+
modifiedHtml = applyPureCommand(modifiedHtml, command);
|
|
1377
|
+
if (modifiedHtml !== before) {
|
|
1378
|
+
preRenderedCount++;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
return {
|
|
1382
|
+
html: modifiedHtml,
|
|
1383
|
+
remainingInitCommands: impure.map((i) => i.node),
|
|
1384
|
+
preRenderedCount
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1048
1387
|
function sanitizeClassName(name) {
|
|
1049
1388
|
if (!/^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(name)) {
|
|
1050
1389
|
return null;
|
|
@@ -2918,6 +3257,22 @@ var EventHandlerCodegen = class {
|
|
|
2918
3257
|
const nested = node;
|
|
2919
3258
|
return this.generateBody(nested.body ?? []);
|
|
2920
3259
|
}
|
|
3260
|
+
case "batchedClassOps": {
|
|
3261
|
+
const batch = node;
|
|
3262
|
+
const lines = [];
|
|
3263
|
+
if (batch.adds.length > 0) {
|
|
3264
|
+
lines.push(`${batch.target}.classList.add(${batch.adds.map((c) => `'${c}'`).join(", ")})`);
|
|
3265
|
+
}
|
|
3266
|
+
if (batch.removes.length > 0) {
|
|
3267
|
+
lines.push(
|
|
3268
|
+
`${batch.target}.classList.remove(${batch.removes.map((c) => `'${c}'`).join(", ")})`
|
|
3269
|
+
);
|
|
3270
|
+
}
|
|
3271
|
+
for (const t of batch.toggles) {
|
|
3272
|
+
lines.push(`${batch.target}.classList.toggle('${t}')`);
|
|
3273
|
+
}
|
|
3274
|
+
return lines.join(";\n");
|
|
3275
|
+
}
|
|
2921
3276
|
default:
|
|
2922
3277
|
return null;
|
|
2923
3278
|
}
|
|
@@ -3165,10 +3520,40 @@ var AOTCompiler = class {
|
|
|
3165
3520
|
// ===========================================================================
|
|
3166
3521
|
/**
|
|
3167
3522
|
* Parse a hyperscript string to AST.
|
|
3523
|
+
* Supports natural language, explicit bracket syntax, and JSON input.
|
|
3168
3524
|
*/
|
|
3169
3525
|
parse(code, options = {}) {
|
|
3170
3526
|
const { language = "en", confidenceThreshold = 0.7, debug = false } = options;
|
|
3171
3527
|
let ast = null;
|
|
3528
|
+
if (isExplicitSyntax(code)) {
|
|
3529
|
+
try {
|
|
3530
|
+
const node = parseExplicit(code);
|
|
3531
|
+
ast = semanticNodeToRuntimeAST(node);
|
|
3532
|
+
if (debug) {
|
|
3533
|
+
console.log(`[aot] Parsed explicit syntax: "${code}"`);
|
|
3534
|
+
}
|
|
3535
|
+
} catch (error) {
|
|
3536
|
+
if (debug) {
|
|
3537
|
+
console.log(`[aot] Explicit parse error for "${code}":`, error);
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
if (ast) return this.ensureEventHandler(ast);
|
|
3541
|
+
}
|
|
3542
|
+
if (this.looksLikeJSON(code)) {
|
|
3543
|
+
try {
|
|
3544
|
+
const json = JSON.parse(code.trim());
|
|
3545
|
+
const node = fromProtocolJSON(json);
|
|
3546
|
+
ast = semanticNodeToRuntimeAST(node);
|
|
3547
|
+
if (debug) {
|
|
3548
|
+
console.log(`[aot] Parsed JSON input: "${code.slice(0, 80)}..."`);
|
|
3549
|
+
}
|
|
3550
|
+
} catch (error) {
|
|
3551
|
+
if (debug) {
|
|
3552
|
+
console.log(`[aot] JSON parse error for "${code.slice(0, 80)}":`, error);
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
if (ast) return this.ensureEventHandler(ast);
|
|
3556
|
+
}
|
|
3172
3557
|
if (language !== "en" && this.semanticParser?.supportsLanguage(language)) {
|
|
3173
3558
|
const result = this.semanticParser.analyze(code, language);
|
|
3174
3559
|
if (result.node && result.confidence >= confidenceThreshold) {
|
|
@@ -3195,15 +3580,7 @@ var AOTCompiler = class {
|
|
|
3195
3580
|
if (!ast) {
|
|
3196
3581
|
ast = this.createSimpleAST(code);
|
|
3197
3582
|
}
|
|
3198
|
-
|
|
3199
|
-
ast = {
|
|
3200
|
-
type: "event",
|
|
3201
|
-
event: "click",
|
|
3202
|
-
modifiers: {},
|
|
3203
|
-
body: [ast]
|
|
3204
|
-
};
|
|
3205
|
-
}
|
|
3206
|
-
return ast;
|
|
3583
|
+
return this.ensureEventHandler(ast);
|
|
3207
3584
|
}
|
|
3208
3585
|
/**
|
|
3209
3586
|
* Create a simple AST from code (for testing without full parser).
|
|
@@ -3368,6 +3745,31 @@ var AOTCompiler = class {
|
|
|
3368
3745
|
return { type: "identifier", value: trimmed };
|
|
3369
3746
|
}
|
|
3370
3747
|
// ===========================================================================
|
|
3748
|
+
// EXPLICIT / JSON INPUT HELPERS
|
|
3749
|
+
// ===========================================================================
|
|
3750
|
+
/**
|
|
3751
|
+
* Check if input looks like JSON (LLM JSON format).
|
|
3752
|
+
*/
|
|
3753
|
+
looksLikeJSON(code) {
|
|
3754
|
+
const trimmed = code.trim();
|
|
3755
|
+
return trimmed.startsWith("{") && trimmed.includes('"action"');
|
|
3756
|
+
}
|
|
3757
|
+
/**
|
|
3758
|
+
* Ensure top-level node is always an event handler.
|
|
3759
|
+
* The codegen pipeline (EventHandlerCodegen) requires this.
|
|
3760
|
+
*/
|
|
3761
|
+
ensureEventHandler(ast) {
|
|
3762
|
+
if (ast && ast.type !== "event") {
|
|
3763
|
+
return {
|
|
3764
|
+
type: "event",
|
|
3765
|
+
event: "click",
|
|
3766
|
+
modifiers: {},
|
|
3767
|
+
body: [ast]
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
return ast;
|
|
3771
|
+
}
|
|
3772
|
+
// ===========================================================================
|
|
3371
3773
|
// ANALYSIS
|
|
3372
3774
|
// ===========================================================================
|
|
3373
3775
|
/**
|
|
@@ -3377,6 +3779,63 @@ var AOTCompiler = class {
|
|
|
3377
3779
|
return this.analyzer.analyze(ast);
|
|
3378
3780
|
}
|
|
3379
3781
|
// ===========================================================================
|
|
3782
|
+
// INIT PRE-RENDERING
|
|
3783
|
+
// ===========================================================================
|
|
3784
|
+
/**
|
|
3785
|
+
* Pre-render pure init block commands into an HTML template at build time.
|
|
3786
|
+
*
|
|
3787
|
+
* Analyzes init block commands for purity (static DOM writes with literal
|
|
3788
|
+
* values targeting #id selectors) and applies them directly to the HTML.
|
|
3789
|
+
* Impure commands are preserved for normal runtime execution.
|
|
3790
|
+
*
|
|
3791
|
+
* @param html - The HTML template string
|
|
3792
|
+
* @param initCommands - Parsed commands from an init block
|
|
3793
|
+
* @returns Modified HTML, remaining impure commands, and count of pre-rendered commands
|
|
3794
|
+
*/
|
|
3795
|
+
preRenderInit(html, initCommands) {
|
|
3796
|
+
return preRenderInitBlock(html, initCommands);
|
|
3797
|
+
}
|
|
3798
|
+
/**
|
|
3799
|
+
* Extract init blocks from HTML, pre-render pure commands, and return modified HTML.
|
|
3800
|
+
* This is a higher-level convenience that combines extraction, parsing, and pre-rendering.
|
|
3801
|
+
*
|
|
3802
|
+
* @param html - The HTML template string
|
|
3803
|
+
* @param options - Compile options (language, etc.)
|
|
3804
|
+
* @returns Modified HTML with pre-rendered init effects and compilation results
|
|
3805
|
+
*/
|
|
3806
|
+
preRenderInitBlocks(html, options = {}) {
|
|
3807
|
+
const scripts = this.extract(html, "template.html");
|
|
3808
|
+
let modifiedHtml = html;
|
|
3809
|
+
let totalPreRendered = 0;
|
|
3810
|
+
const remainingScripts = [];
|
|
3811
|
+
for (const script of scripts) {
|
|
3812
|
+
const ast = this.parse(script.code, {
|
|
3813
|
+
...options,
|
|
3814
|
+
language: script.language ?? options.language ?? "en"
|
|
3815
|
+
});
|
|
3816
|
+
if (!ast) {
|
|
3817
|
+
remainingScripts.push(script);
|
|
3818
|
+
continue;
|
|
3819
|
+
}
|
|
3820
|
+
const eventNode = ast;
|
|
3821
|
+
if (eventNode.type === "event" && eventNode.event === "init" && eventNode.body) {
|
|
3822
|
+
const result = preRenderInitBlock(modifiedHtml, eventNode.body);
|
|
3823
|
+
modifiedHtml = result.html;
|
|
3824
|
+
totalPreRendered += result.preRenderedCount;
|
|
3825
|
+
if (result.remainingInitCommands.length > 0) {
|
|
3826
|
+
remainingScripts.push(script);
|
|
3827
|
+
}
|
|
3828
|
+
} else {
|
|
3829
|
+
remainingScripts.push(script);
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
return {
|
|
3833
|
+
html: modifiedHtml,
|
|
3834
|
+
preRenderedCount: totalPreRendered,
|
|
3835
|
+
remainingScripts
|
|
3836
|
+
};
|
|
3837
|
+
}
|
|
3838
|
+
// ===========================================================================
|
|
3380
3839
|
// COMPILATION
|
|
3381
3840
|
// ===========================================================================
|
|
3382
3841
|
/**
|
|
@@ -3499,6 +3958,30 @@ var AOTCompiler = class {
|
|
|
3499
3958
|
}
|
|
3500
3959
|
};
|
|
3501
3960
|
}
|
|
3961
|
+
/**
|
|
3962
|
+
* Compile explicit bracket syntax or LLM JSON to JavaScript.
|
|
3963
|
+
* Uses the framework IR directly — no semantic or traditional parser needed.
|
|
3964
|
+
*/
|
|
3965
|
+
compileExplicit(code, options = {}) {
|
|
3966
|
+
try {
|
|
3967
|
+
const ast = isExplicitSyntax(code) ? semanticNodeToRuntimeAST(parseExplicit(code)) : semanticNodeToRuntimeAST(fromProtocolJSON(JSON.parse(code.trim())));
|
|
3968
|
+
return this.compileAST(ast, options);
|
|
3969
|
+
} catch (error) {
|
|
3970
|
+
return {
|
|
3971
|
+
success: false,
|
|
3972
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
3973
|
+
warnings: [],
|
|
3974
|
+
metadata: {
|
|
3975
|
+
handlerId: "",
|
|
3976
|
+
parserUsed: "traditional",
|
|
3977
|
+
commandsUsed: [],
|
|
3978
|
+
optimizationsApplied: [],
|
|
3979
|
+
needsRuntime: false,
|
|
3980
|
+
runtimeHelpers: []
|
|
3981
|
+
}
|
|
3982
|
+
};
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3502
3985
|
/**
|
|
3503
3986
|
* Compile multiple extracted scripts.
|
|
3504
3987
|
*/
|
|
@@ -3734,12 +4217,12 @@ async function compileHyperscript(code, options) {
|
|
|
3734
4217
|
async function createMultilingualCompiler() {
|
|
3735
4218
|
const compiler = new AOTCompiler();
|
|
3736
4219
|
try {
|
|
3737
|
-
const { createCoreParserAdapter: createCoreParserAdapter2 } = await import("./core-parser-adapter-VCJB52SO-
|
|
4220
|
+
const { createCoreParserAdapter: createCoreParserAdapter2 } = await import("./core-parser-adapter-VCJB52SO-7T2PARW4.js");
|
|
3738
4221
|
compiler.setParser(await createCoreParserAdapter2());
|
|
3739
4222
|
} catch {
|
|
3740
4223
|
}
|
|
3741
4224
|
try {
|
|
3742
|
-
const { createSemanticAdapter: createSemanticAdapter2 } = await import("./semantic-adapter-7HTMTO75-
|
|
4225
|
+
const { createSemanticAdapter: createSemanticAdapter2 } = await import("./semantic-adapter-7HTMTO75-WVF6UAHI.js");
|
|
3743
4226
|
compiler.setSemanticParser(await createSemanticAdapter2());
|
|
3744
4227
|
} catch {
|
|
3745
4228
|
}
|
|
@@ -3787,4 +4270,4 @@ export {
|
|
|
3787
4270
|
sanitizeSelector,
|
|
3788
4271
|
scanFiles
|
|
3789
4272
|
};
|
|
3790
|
-
//# sourceMappingURL=dist-
|
|
4273
|
+
//# sourceMappingURL=dist-A6VWPCPB.js.map
|