@lark.js/mvc 0.0.10 → 0.0.11

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/vite.cjs CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __commonJS = (cb, mod) => function __require() {
9
12
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
13
  };
@@ -30,10 +33,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
33
  ));
31
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
35
 
36
+ // ../../node_modules/.pnpm/tsup@8.5.1_@swc+core@1.15.41_@swc+helpers@0.5.23__jiti@2.7.0_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js
37
+ var init_cjs_shims = __esm({
38
+ "../../node_modules/.pnpm/tsup@8.5.1_@swc+core@1.15.41_@swc+helpers@0.5.23__jiti@2.7.0_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js"() {
39
+ "use strict";
40
+ }
41
+ });
42
+
33
43
  // ../../node_modules/.pnpm/@babel+parser@7.29.7/node_modules/@babel/parser/lib/index.js
34
44
  var require_lib = __commonJS({
35
45
  "../../node_modules/.pnpm/@babel+parser@7.29.7/node_modules/@babel/parser/lib/index.js"(exports2) {
36
46
  "use strict";
47
+ init_cjs_shims();
37
48
  Object.defineProperty(exports2, "__esModule", {
38
49
  value: true
39
50
  });
@@ -14518,7 +14529,7 @@ var require_lib = __commonJS({
14518
14529
  options = Object.assign({}, options);
14519
14530
  try {
14520
14531
  options.sourceType = "module";
14521
- const parser = getParser(options, input);
14532
+ const parser = getParser2(options, input);
14522
14533
  const ast = parser.parse();
14523
14534
  if (parser.sawUnambiguousESM) {
14524
14535
  return ast;
@@ -14526,7 +14537,7 @@ var require_lib = __commonJS({
14526
14537
  if (parser.ambiguousScriptDifferentAst) {
14527
14538
  try {
14528
14539
  options.sourceType = "script";
14529
- return getParser(options, input).parse();
14540
+ return getParser2(options, input).parse();
14530
14541
  } catch (_unused) {
14531
14542
  }
14532
14543
  } else {
@@ -14536,17 +14547,17 @@ var require_lib = __commonJS({
14536
14547
  } catch (moduleError) {
14537
14548
  try {
14538
14549
  options.sourceType = "script";
14539
- return getParser(options, input).parse();
14550
+ return getParser2(options, input).parse();
14540
14551
  } catch (_unused2) {
14541
14552
  }
14542
14553
  throw moduleError;
14543
14554
  }
14544
14555
  } else {
14545
- return getParser(options, input).parse();
14556
+ return getParser2(options, input).parse();
14546
14557
  }
14547
14558
  }
14548
14559
  function parseExpression(input, options) {
14549
- const parser = getParser(options, input);
14560
+ const parser = getParser2(options, input);
14550
14561
  if (parser.options.strictMode) {
14551
14562
  parser.state.strict = true;
14552
14563
  }
@@ -14560,7 +14571,7 @@ var require_lib = __commonJS({
14560
14571
  return tokenTypes2;
14561
14572
  }
14562
14573
  var tokTypes = generateExportedTokenTypes(tt);
14563
- function getParser(options, input) {
14574
+ function getParser2(options, input) {
14564
14575
  let cls = Parser;
14565
14576
  const pluginsMap = /* @__PURE__ */ new Map();
14566
14577
  if (options != null && options.plugins) {
@@ -14612,11 +14623,18 @@ __export(vite_exports, {
14612
14623
  larkMvcPlugin: () => larkMvcPlugin
14613
14624
  });
14614
14625
  module.exports = __toCommonJS(vite_exports);
14626
+ init_cjs_shims();
14615
14627
  var import_path = __toESM(require("path"), 1);
14616
14628
  var import_fs = __toESM(require("fs"), 1);
14617
14629
 
14618
14630
  // src/compiler.ts
14619
- var import_parser = __toESM(require_lib(), 1);
14631
+ init_cjs_shims();
14632
+
14633
+ // src/compiler/compile-template.ts
14634
+ init_cjs_shims();
14635
+
14636
+ // src/compiler/template-syntax.ts
14637
+ init_cjs_shims();
14620
14638
  var SPLITTER = String.fromCharCode(30);
14621
14639
  var VIEW_ID_PLACEHOLDER = String.fromCharCode(31);
14622
14640
  function jsObjectToUrlParams(paramsStr) {
@@ -14737,7 +14755,7 @@ function convertArtSyntax(source, debug) {
14737
14755
  }
14738
14756
  if (blockStack.length > 0) {
14739
14757
  const unclosed = blockStack.map((b) => `"${b.ctrl}" at line ${b.line}`).join(", ");
14740
- throw new Error(`[@lark.js/mvc error] unclosed block(s): ${unclosed}`);
14758
+ throw new Error(`Unclosed block(s): ${unclosed}`);
14741
14759
  }
14742
14760
  return result.join("");
14743
14761
  }
@@ -14836,7 +14854,7 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
14836
14854
  const object = tokens[0];
14837
14855
  if (tokens.length > 1 && tokens[1] !== "as") {
14838
14856
  throw new Error(
14839
- `[@lark.js/mvc error] bad forOf syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forOf list as item [index]}}`
14857
+ `Bad forOf syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forOf list as item [index]}}`
14840
14858
  );
14841
14859
  }
14842
14860
  const restTokens = tokens.slice(2);
@@ -14863,7 +14881,7 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
14863
14881
  const object = tokens[0];
14864
14882
  if (tokens.length > 1 && tokens[1] !== "as") {
14865
14883
  throw new Error(
14866
- `[@lark.js/mvc error] bad forIn syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forIn obj as val [key]}}`
14884
+ `Bad forIn syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forIn obj as val [key]}}`
14867
14885
  );
14868
14886
  }
14869
14887
  const restTokens2 = tokens.slice(2);
@@ -14889,13 +14907,11 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
14889
14907
  const expectedCtrl = keyword.substring(1);
14890
14908
  const last = blockStack.pop();
14891
14909
  if (!last) {
14892
- throw new Error(
14893
- `[@lark.js/mvc error] unexpected {{${code}}}: no matching open block`
14894
- );
14910
+ throw new Error(`Unexpected {{${code}}}: no matching open block`);
14895
14911
  }
14896
14912
  if (last.ctrl !== expectedCtrl) {
14897
14913
  throw new Error(
14898
- `[@lark.js/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
14914
+ `Unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
14899
14915
  );
14900
14916
  }
14901
14917
  return `${debugPrefix}<%}%>`;
@@ -14956,112 +14972,219 @@ function parseAsExpr(expr) {
14956
14972
  bad: false
14957
14973
  };
14958
14974
  }
14959
- function compileToFunction(source, debug, file) {
14960
- const matcher = /<%([@=!:])?([\s\S]*?)%>|$/g;
14961
- let index = 0;
14962
- let funcSource = `$out+='`;
14963
- let hasAtRule = false;
14964
- const escapeSlashRegExp = /\\|'/g;
14965
- const escapeBreakReturnRegExp = /\r|\n/g;
14966
- source.replace(matcher, (match, operate, content, offset) => {
14967
- funcSource += source.substring(index, offset).replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
14968
- index = offset + match.length;
14969
- if (debug) {
14970
- let expr = source.substring(
14971
- index - match.length + 2 + (operate ? 1 : 0),
14972
- index - 2
14973
- );
14974
- const x11 = String.fromCharCode(17);
14975
- const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
14976
- const artM = expr.match(artRegExp);
14977
- let art = "";
14978
- let line = -1;
14979
- if (artM) {
14980
- expr = expr.replace(artRegExp, "");
14981
- art = artM[2];
14982
- line = parseInt(artM[1], 10);
14983
- } else {
14984
- expr = expr.replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
14975
+
14976
+ // src/compiler/compile-to-vdom-function.ts
14977
+ init_cjs_shims();
14978
+ var import_htmlparser2 = require("htmlparser2");
14979
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
14980
+ "area",
14981
+ "base",
14982
+ "br",
14983
+ "col",
14984
+ "embed",
14985
+ "hr",
14986
+ "img",
14987
+ "input",
14988
+ "link",
14989
+ "meta",
14990
+ "param",
14991
+ "source",
14992
+ "track",
14993
+ "wbr"
14994
+ ]);
14995
+ function vdomEscapeStr(s) {
14996
+ return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\x1e/g, "\\x1e");
14997
+ }
14998
+ function vdomResolveAttrValue(rawValue, exprStore) {
14999
+ const hasPlaceholders = rawValue.includes("\0");
15000
+ const hasViewId = rawValue.includes("");
15001
+ if (!hasPlaceholders && !hasViewId) {
15002
+ return `'${vdomEscapeStr(rawValue)}'`;
15003
+ }
15004
+ const segments = [];
15005
+ let remaining = rawValue;
15006
+ while (remaining.length > 0) {
15007
+ const phIdx = remaining.indexOf("\0");
15008
+ const viIdx = remaining.indexOf("");
15009
+ let nextSpecial = -1;
15010
+ let specialType = null;
15011
+ if (phIdx >= 0 && (viIdx < 0 || phIdx <= viIdx)) {
15012
+ nextSpecial = phIdx;
15013
+ specialType = "ph";
15014
+ } else if (viIdx >= 0) {
15015
+ nextSpecial = viIdx;
15016
+ specialType = "vi";
15017
+ }
15018
+ if (nextSpecial === -1) {
15019
+ if (remaining) segments.push(`'${vdomEscapeStr(remaining)}'`);
15020
+ break;
15021
+ }
15022
+ if (nextSpecial > 0) {
15023
+ segments.push(`'${vdomEscapeStr(remaining.substring(0, nextSpecial))}'`);
15024
+ }
15025
+ if (specialType === "vi") {
15026
+ segments.push("$viewId");
15027
+ remaining = remaining.substring(nextSpecial + 1);
15028
+ } else {
15029
+ const closeIdx = remaining.indexOf("\0", nextSpecial + 1);
15030
+ if (closeIdx === -1) {
15031
+ segments.push(`'${vdomEscapeStr(remaining.substring(nextSpecial))}'`);
15032
+ break;
14985
15033
  }
14986
- if (operate === "@") {
14987
- hasAtRule = true;
14988
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',$refFn($refAlt,${content}))+'`;
14989
- } else if (operate === "=" || operate === ":") {
14990
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',$encHtml(${content}))+'`;
14991
- } else if (operate === "!") {
14992
- if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
14993
- content = `$strSafe(${content})`;
14994
- }
14995
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
14996
- } else if (content) {
14997
- if (line > -1) {
14998
- funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
14999
- content = "";
15034
+ const idx = parseInt(remaining.substring(nextSpecial + 1, closeIdx));
15035
+ const expr = exprStore[idx];
15036
+ if (expr.op === "=" || expr.op === ":") {
15037
+ segments.push(`$n(${expr.content})`);
15038
+ } else if (expr.op === "!") {
15039
+ if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15040
+ segments.push(expr.content);
15000
15041
  } else {
15001
- funcSource += `';`;
15002
- }
15003
- if (funcSource.endsWith(`+'';`)) {
15004
- funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
15005
- }
15006
- if (expr) {
15007
- funcSource += `$dbgExpr='<%${expr}%>';`;
15042
+ segments.push(`$n(${expr.content})`);
15008
15043
  }
15009
- funcSource += content + `;$out+='`;
15044
+ } else if (expr.op === "@") {
15045
+ segments.push(`$refFn($refAlt,${expr.content})`);
15046
+ } else {
15047
+ segments.push(`$n(${expr.content})`);
15010
15048
  }
15011
- } else {
15012
- if (operate === "@") {
15013
- hasAtRule = true;
15014
- funcSource += `'+$refFn($refAlt,${content})+'`;
15015
- } else if (operate === "=" || operate === ":") {
15016
- funcSource += `'+$encHtml(${content})+'`;
15017
- } else if (operate === "!") {
15018
- if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
15019
- content = `$strSafe(${content})`;
15020
- }
15021
- funcSource += `'+${content}+'`;
15022
- } else if (content) {
15023
- funcSource += `';`;
15024
- if (funcSource.endsWith(`+'';`)) {
15025
- funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
15049
+ remaining = remaining.substring(closeIdx + 1);
15050
+ }
15051
+ }
15052
+ if (segments.length === 0) return "''";
15053
+ if (segments.length === 1) return segments[0];
15054
+ return segments.join("+");
15055
+ }
15056
+ function vdomBuildPropsFromAttribs(attribs, exprStore) {
15057
+ if (!attribs) return "null";
15058
+ const keys = Object.keys(attribs);
15059
+ if (keys.length === 0) return "null";
15060
+ const entries = [];
15061
+ for (const name of keys) {
15062
+ const value = attribs[name];
15063
+ const valueExpr = vdomResolveAttrValue(value, exprStore);
15064
+ entries.push(`'${vdomEscapeStr(name)}':${valueExpr}`);
15065
+ }
15066
+ return `{${entries.join(",")}}`;
15067
+ }
15068
+ function compileToVDomFunction(source, debug, file) {
15069
+ const lines = [];
15070
+ let varCounter = 0;
15071
+ let propsCounter = 0;
15072
+ const exprStore = [];
15073
+ const protectedSource = source.replace(
15074
+ /<%([@=!:])?([\s\S]*?)%>/g,
15075
+ (_, op, content) => {
15076
+ const idx = exprStore.length;
15077
+ exprStore.push({ op: op || "", content: (content || "").trim() });
15078
+ return `\0${idx}\0`;
15079
+ }
15080
+ );
15081
+ const doc = (0, import_htmlparser2.parseDocument)(protectedSource, {
15082
+ recognizeSelfClosing: true,
15083
+ lowerCaseTags: false,
15084
+ lowerCaseAttributeNames: false,
15085
+ decodeEntities: false
15086
+ });
15087
+ const rootVar = `$v${varCounter++}`;
15088
+ lines.push(`let ${rootVar}=[]`);
15089
+ const maxVars = 30;
15090
+ const varDecls = [];
15091
+ for (let i = 1; i < maxVars; i++) {
15092
+ varDecls.push(`$v${i}`);
15093
+ }
15094
+ lines.push(`let ${varDecls.join(",")}`);
15095
+ function allocVar() {
15096
+ if (varCounter >= maxVars) return `$v${maxVars - 1}`;
15097
+ return `$v${varCounter++}`;
15098
+ }
15099
+ function emitNode(node, parentVar) {
15100
+ const type = node.type;
15101
+ if (type === "text") {
15102
+ emitText(node.data || "", parentVar);
15103
+ } else if (type === "tag" || type === "script" || type === "style") {
15104
+ emitElement(node, parentVar);
15105
+ }
15106
+ }
15107
+ function emitText(text, parentVar) {
15108
+ const parts = text.split(/\x00(\d+)\x00/);
15109
+ for (let i = 0; i < parts.length; i++) {
15110
+ if (i % 2 === 0) {
15111
+ const trimmed = parts[i];
15112
+ if (trimmed.trim()) {
15113
+ lines.push(`${parentVar}.push($c(0,'${vdomEscapeStr(trimmed)}'))`);
15026
15114
  }
15027
- funcSource += `${content};$out+='`;
15115
+ } else {
15116
+ const idx = parseInt(parts[i]);
15117
+ const expr = exprStore[idx];
15118
+ emitExpr(expr, parentVar);
15028
15119
  }
15029
15120
  }
15030
- return match;
15031
- });
15032
- funcSource += `';`;
15033
- funcSource = funcSource.replace(/\$out\+='';/g, "");
15034
- funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
15121
+ }
15122
+ function emitExpr(expr, parentVar) {
15123
+ if (expr.op === "=" || expr.op === ":") {
15124
+ lines.push(`${parentVar}.push($c(0,$n(${expr.content})))`);
15125
+ } else if (expr.op === "!") {
15126
+ if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15127
+ lines.push(`${parentVar}.push($c(0,${expr.content}))`);
15128
+ } else {
15129
+ lines.push(`${parentVar}.push($c(0,$n(${expr.content})))`);
15130
+ }
15131
+ } else if (expr.op === "@") {
15132
+ lines.push(`${parentVar}.push($c(0,$refFn($refAlt,${expr.content})))`);
15133
+ } else if (expr.content) {
15134
+ lines.push(expr.content);
15135
+ }
15136
+ }
15137
+ function emitElement(node, parentVar) {
15138
+ const tagName = node.name || "";
15139
+ const children = node.children || [];
15140
+ const childVar = allocVar();
15141
+ const propsKey = `__p${propsCounter++}`;
15142
+ const props = vdomBuildPropsFromAttribs(node.attribs, exprStore);
15143
+ lines.push(`let ${propsKey}=${props}`);
15144
+ lines.push(`${childVar}=[]`);
15145
+ for (const child of children) {
15146
+ emitNode(child, childVar);
15147
+ }
15148
+ const isVoid = VOID_ELEMENTS.has(tagName) && children.length === 0;
15149
+ const childrenArg = isVoid ? "1" : childVar;
15150
+ lines.push(
15151
+ `${parentVar}.push($c('${tagName}',${propsKey},${childrenArg}))`
15152
+ );
15153
+ }
15154
+ for (const child of doc.children) {
15155
+ emitNode(child, rootVar);
15156
+ }
15157
+ lines.push(`return $c($viewId,0,${rootVar})`);
15158
+ const body = lines.join(";");
15159
+ let funcBody = body;
15035
15160
  if (debug) {
15036
15161
  const filePart = file ? `\\r\\n\\tat file:${file}` : "";
15037
- funcSource = `let $dbgExpr,$dbgArt,$dbgLine;try{${funcSource}}catch(ex){let msg='render view error:'+(ex.message||ex);if($dbgArt)msg+='\\r\\n\\tsrc art:{{'+$dbgArt+'}}\\r\\n\\tat line:'+$dbgLine;msg+='\\r\\n\\t'+($dbgArt?'translate to:':'expr:');msg+=$dbgExpr+'${filePart}';throw msg;}`;
15162
+ funcBody = `let $dbgExpr,$dbgArt,$dbgLine;try{${body}}catch(ex){let msg='render view error:'+(ex.message||ex);msg+='${filePart}';throw msg;}`;
15038
15163
  }
15039
15164
  const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
15040
- funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
15041
- void hasAtRule;
15165
+ funcBody = funcBody.replace(viewIdRegExp, `'+$viewId+'`);
15042
15166
  const refFallback = "if(!$refAlt)$refAlt=$data;";
15043
- const fullSource = `${refFallback}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
15044
- return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
15167
+ const fullSource = `${refFallback}let $splitter='\\x1e'{{VARS}};${funcBody}`;
15168
+ return `($data,$viewId,$refAlt,$n,$refFn,$encUri,$encQuote)=>{${fullSource}}`;
15045
15169
  }
15046
- function compileTemplate(source, options = {}) {
15047
- const { debug = false, globalVars = [], file } = options;
15048
- const { protectedSource, comments } = protectComments(source);
15049
- const converted = convertArtSyntax(protectedSource, debug);
15050
- const viewEventProcessed = processViewEvents(converted);
15051
- const finalSource = restoreComments(viewEventProcessed, comments);
15052
- const funcBody = compileToFunction(finalSource, debug, file);
15053
- const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
15054
- const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
15055
- return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15056
- export default function(data, viewId, refData) {
15057
- let $data = data || {},
15058
- $viewId = viewId || '';
15059
- return (${funcWithVars})($data, $viewId, refData,
15060
- __larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
15061
- );
15062
- }`;
15170
+
15171
+ // src/compiler/swc/extract-global-vars.ts
15172
+ init_cjs_shims();
15173
+ var parseSyncFn = null;
15174
+ var parseSyncLoadAttempted = false;
15175
+ async function getParser() {
15176
+ if (!parseSyncLoadAttempted) {
15177
+ parseSyncLoadAttempted = true;
15178
+ try {
15179
+ const swc = await import("@swc/core");
15180
+ parseSyncFn = swc.parseSync;
15181
+ } catch (err) {
15182
+ console.error("failed to load @swc/core", err);
15183
+ }
15184
+ }
15185
+ return parseSyncFn;
15063
15186
  }
15064
- function extractGlobalVars(source) {
15187
+ async function extractGlobalVars(source) {
15065
15188
  const { protectedSource, comments: _comments } = protectComments(source);
15066
15189
  const viewEventProcessed = processViewEvents(protectedSource);
15067
15190
  const converted = convertArtSyntax(viewEventProcessed, false);
@@ -15090,12 +15213,15 @@ function extractGlobalVars(source) {
15090
15213
  );
15091
15214
  let fn = fnParts.join("");
15092
15215
  fn = `(function(){${fn}})`;
15216
+ const parseSync = await getParser();
15217
+ if (!parseSync) {
15218
+ return fallbackExtractVariables(source);
15219
+ }
15093
15220
  let ast;
15094
15221
  try {
15095
- ast = (0, import_parser.parse)(fn, {
15096
- sourceType: "script",
15097
- allowReturnOutsideFunction: true,
15098
- allowAwaitOutsideFunction: true
15222
+ ast = parseSync(fn, {
15223
+ syntax: "ecmascript",
15224
+ target: "es2022"
15099
15225
  });
15100
15226
  } catch {
15101
15227
  return fallbackExtractVariables(source);
@@ -15103,55 +15229,55 @@ function extractGlobalVars(source) {
15103
15229
  const globalExists = {};
15104
15230
  for (const name of BUILTIN_GLOBALS) globalExists[name] = 1;
15105
15231
  const globalVars = /* @__PURE__ */ Object.create(null);
15106
- const fnRange = [];
15107
- walkAst(ast, {
15232
+ const fnNodes = [];
15233
+ walkSwcAst(ast, {
15108
15234
  VariableDeclarator(node) {
15109
15235
  if (node.id.type === "Identifier") {
15110
- const name = node.id.name;
15236
+ const name = node.id.value;
15111
15237
  globalExists[name] = node.init ? 3 : 2;
15112
15238
  }
15113
15239
  },
15114
15240
  FunctionDeclaration(node) {
15115
- if (node.id) {
15116
- globalExists[node.id.name] = 3;
15241
+ if (node.identifier) {
15242
+ globalExists[node.identifier.value] = 3;
15117
15243
  }
15118
- fnRange.push(node);
15244
+ fnNodes.push(node);
15119
15245
  },
15120
15246
  FunctionExpression(node) {
15121
- fnRange.push(node);
15247
+ fnNodes.push(node);
15122
15248
  },
15123
15249
  ArrowFunctionExpression(node) {
15124
- fnRange.push(node);
15250
+ fnNodes.push(node);
15125
15251
  },
15126
15252
  CallExpression(node) {
15127
15253
  if (node.callee.type === "Identifier") {
15128
- globalExists[node.callee.name] = 1;
15254
+ globalExists[node.callee.value] = 1;
15129
15255
  }
15130
15256
  }
15131
15257
  });
15132
15258
  const functionParams = /* @__PURE__ */ Object.create(null);
15133
- for (const fnNode of fnRange) {
15134
- const params = "params" in fnNode ? fnNode.params : [];
15135
- for (const p of params) {
15136
- if (p.type === "Identifier") {
15137
- functionParams[p.name] = 1;
15138
- } else if (p.type === "AssignmentPattern" && p.left.type === "Identifier") {
15139
- functionParams[p.left.name] = 1;
15140
- } else if (p.type === "RestElement" && p.argument.type === "Identifier") {
15141
- functionParams[p.argument.name] = 1;
15259
+ for (const fnNode of fnNodes) {
15260
+ const patterns = getParamPatterns(fnNode);
15261
+ for (const pat of patterns) {
15262
+ if (pat.type === "Identifier") {
15263
+ functionParams[pat.value] = 1;
15264
+ } else if (pat.type === "AssignmentPattern" && pat.left.type === "Identifier") {
15265
+ functionParams[pat.left.value] = 1;
15266
+ } else if (pat.type === "RestElement" && pat.argument.type === "Identifier") {
15267
+ functionParams[pat.argument.value] = 1;
15142
15268
  }
15143
15269
  }
15144
15270
  }
15145
- walkAst(ast, {
15271
+ walkSwcAst(ast, {
15146
15272
  Identifier(node) {
15147
- const name = node.name;
15273
+ const name = node.value;
15148
15274
  if (globalExists[name]) return;
15149
15275
  if (functionParams[name]) return;
15150
15276
  globalVars[name] = 1;
15151
15277
  },
15152
15278
  AssignmentExpression(node) {
15153
15279
  if (node.left.type === "Identifier") {
15154
- const name = node.left.name;
15280
+ const name = node.left.value;
15155
15281
  if (!globalExists[name] || globalExists[name] === 1) {
15156
15282
  globalExists[name] = (globalExists[name] || 0) + 1;
15157
15283
  }
@@ -15160,6 +15286,12 @@ function extractGlobalVars(source) {
15160
15286
  });
15161
15287
  return Object.keys(globalVars);
15162
15288
  }
15289
+ function getParamPatterns(fnNode) {
15290
+ if (fnNode.type === "ArrowFunctionExpression") {
15291
+ return fnNode.params;
15292
+ }
15293
+ return fnNode.params.map((p) => p.pat);
15294
+ }
15163
15295
  function fallbackExtractVariables(source) {
15164
15296
  const vars = /* @__PURE__ */ new Set();
15165
15297
  const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
@@ -15177,41 +15309,39 @@ function fallbackExtractVariables(source) {
15177
15309
  }
15178
15310
  return Array.from(vars).filter((v) => !BUILTIN_GLOBALS.has(v));
15179
15311
  }
15180
- function walkAst(ast, visitors) {
15312
+ function walkSwcAst(ast, visitors) {
15181
15313
  function visit(node) {
15182
15314
  const type = node.type;
15183
15315
  if (visitors[type]) {
15184
15316
  visitors[type](node);
15185
15317
  }
15186
- const bag = node;
15187
15318
  for (const key of Object.keys(node)) {
15188
- if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
15189
- continue;
15319
+ if (key === "type" || key === "span" || key === "ctxt") continue;
15190
15320
  if (type === "MemberExpression" && key === "property") {
15191
15321
  const me = node;
15192
- if (!me.computed) continue;
15322
+ if (me.property.type !== "Computed") continue;
15193
15323
  }
15194
- if (type === "ObjectProperty" && key === "key") {
15195
- const op = node;
15196
- if (!op.computed) continue;
15324
+ if (type === "KeyValueProperty" && key === "key") {
15325
+ const kv = node;
15326
+ if (kv.key.type !== "Computed") continue;
15197
15327
  }
15198
- if (type === "ObjectMethod" && key === "key") {
15199
- const om = node;
15200
- if (!om.computed) continue;
15328
+ if (type === "MethodProperty" && key === "key") {
15329
+ const mp = node;
15330
+ if (mp.key.type !== "Computed") continue;
15201
15331
  }
15202
- const child = bag[key];
15332
+ const child = Reflect.get(node, key);
15203
15333
  if (Array.isArray(child)) {
15204
15334
  for (const item of child) {
15205
- if (isAstNode(item)) visit(item);
15335
+ if (isSwcNode(item)) visit(item);
15206
15336
  }
15207
- } else if (isAstNode(child)) {
15337
+ } else if (isSwcNode(child)) {
15208
15338
  visit(child);
15209
15339
  }
15210
15340
  }
15211
15341
  }
15212
15342
  visit(ast);
15213
15343
  }
15214
- function isAstNode(v) {
15344
+ function isSwcNode(v) {
15215
15345
  return !!v && typeof v === "object" && typeof v.type === "string";
15216
15346
  }
15217
15347
  var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
@@ -15356,7 +15486,7 @@ var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
15356
15486
  "decodeURIComponent",
15357
15487
  "encodeURI",
15358
15488
  "decodeURI",
15359
- // Babel helpers
15489
+ // SWC helpers
15360
15490
  "arguments",
15361
15491
  "this",
15362
15492
  "require",
@@ -15364,10 +15494,438 @@ var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
15364
15494
  "Lark"
15365
15495
  ]);
15366
15496
 
15497
+ // src/compiler/extract-global-vars.ts
15498
+ init_cjs_shims();
15499
+ var import_parser = __toESM(require_lib(), 1);
15500
+ async function extractGlobalVars2(source) {
15501
+ const { protectedSource, comments: _comments } = protectComments(source);
15502
+ const viewEventProcessed = processViewEvents(protectedSource);
15503
+ const converted = convertArtSyntax(viewEventProcessed, false);
15504
+ const template = restoreComments(converted, _comments);
15505
+ const templateCmdRegExp = /<%([@=!:])?([\s\S]*?)%>|$/g;
15506
+ const fnParts = [];
15507
+ const htmlStore = {};
15508
+ let htmlIndex = 0;
15509
+ let lastIndex = 0;
15510
+ const htmlKey = String.fromCharCode(5);
15511
+ template.replace(
15512
+ templateCmdRegExp,
15513
+ (match, operate, content, offset) => {
15514
+ const start = operate ? 3 : 2;
15515
+ const htmlText = template.substring(lastIndex, offset + start);
15516
+ const key = htmlKey + htmlIndex++ + htmlKey;
15517
+ htmlStore[key] = htmlText;
15518
+ lastIndex = offset + match.length - 2;
15519
+ if (operate && content.trim()) {
15520
+ fnParts.push(';"' + key + '";', "[" + content + "]");
15521
+ } else {
15522
+ fnParts.push(';"' + key + '";', content || "");
15523
+ }
15524
+ return match;
15525
+ }
15526
+ );
15527
+ let fn = fnParts.join("");
15528
+ fn = `(function(){${fn}})`;
15529
+ let ast;
15530
+ try {
15531
+ ast = (0, import_parser.parse)(fn, {
15532
+ sourceType: "script",
15533
+ allowReturnOutsideFunction: true,
15534
+ allowAwaitOutsideFunction: true
15535
+ });
15536
+ } catch {
15537
+ return fallbackExtractVariables2(source);
15538
+ }
15539
+ const globalExists = {};
15540
+ for (const name of BUILTIN_GLOBALS2) globalExists[name] = 1;
15541
+ const globalVars = /* @__PURE__ */ Object.create(null);
15542
+ const fnRange = [];
15543
+ walkAst(ast, {
15544
+ VariableDeclarator(node) {
15545
+ if (node.id.type === "Identifier") {
15546
+ const name = node.id.name;
15547
+ globalExists[name] = node.init ? 3 : 2;
15548
+ }
15549
+ },
15550
+ FunctionDeclaration(node) {
15551
+ if (node.id) {
15552
+ globalExists[node.id.name] = 3;
15553
+ }
15554
+ fnRange.push(node);
15555
+ },
15556
+ FunctionExpression(node) {
15557
+ fnRange.push(node);
15558
+ },
15559
+ ArrowFunctionExpression(node) {
15560
+ fnRange.push(node);
15561
+ },
15562
+ CallExpression(node) {
15563
+ if (node.callee.type === "Identifier") {
15564
+ globalExists[node.callee.name] = 1;
15565
+ }
15566
+ }
15567
+ });
15568
+ const functionParams = /* @__PURE__ */ Object.create(null);
15569
+ for (const fnNode of fnRange) {
15570
+ const params = "params" in fnNode ? fnNode.params : [];
15571
+ for (const p of params) {
15572
+ if (p.type === "Identifier") {
15573
+ functionParams[p.name] = 1;
15574
+ } else if (p.type === "AssignmentPattern" && p.left.type === "Identifier") {
15575
+ functionParams[p.left.name] = 1;
15576
+ } else if (p.type === "RestElement" && p.argument.type === "Identifier") {
15577
+ functionParams[p.argument.name] = 1;
15578
+ }
15579
+ }
15580
+ }
15581
+ walkAst(ast, {
15582
+ Identifier(node) {
15583
+ const name = node.name;
15584
+ if (globalExists[name]) return;
15585
+ if (functionParams[name]) return;
15586
+ globalVars[name] = 1;
15587
+ },
15588
+ AssignmentExpression(node) {
15589
+ if (node.left.type === "Identifier") {
15590
+ const name = node.left.name;
15591
+ if (!globalExists[name] || globalExists[name] === 1) {
15592
+ globalExists[name] = (globalExists[name] || 0) + 1;
15593
+ }
15594
+ }
15595
+ }
15596
+ });
15597
+ return Object.keys(globalVars);
15598
+ }
15599
+ function fallbackExtractVariables2(source) {
15600
+ const vars = /* @__PURE__ */ new Set();
15601
+ const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
15602
+ let m;
15603
+ while ((m = outputRegExp.exec(source)) !== null) {
15604
+ vars.add(m[1]);
15605
+ }
15606
+ const eachRegExp = /\{\{forOf\s+([a-zA-Z_$][\w$]*)\s+as/g;
15607
+ while ((m = eachRegExp.exec(source)) !== null) {
15608
+ vars.add(m[1]);
15609
+ }
15610
+ const ifRegExp = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
15611
+ while ((m = ifRegExp.exec(source)) !== null) {
15612
+ vars.add(m[1]);
15613
+ }
15614
+ return Array.from(vars).filter((v) => !BUILTIN_GLOBALS2.has(v));
15615
+ }
15616
+ function walkAst(ast, visitors) {
15617
+ function visit(node) {
15618
+ const type = node.type;
15619
+ if (visitors[type]) {
15620
+ visitors[type](node);
15621
+ }
15622
+ for (const key of Object.keys(node)) {
15623
+ if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
15624
+ continue;
15625
+ if (type === "MemberExpression" && key === "property") {
15626
+ const me = node;
15627
+ if (!me.computed) continue;
15628
+ }
15629
+ if (type === "ObjectProperty" && key === "key") {
15630
+ const op = node;
15631
+ if (!op.computed) continue;
15632
+ }
15633
+ if (type === "ObjectMethod" && key === "key") {
15634
+ const om = node;
15635
+ if (!om.computed) continue;
15636
+ }
15637
+ const child = Reflect.get(node, key);
15638
+ if (Array.isArray(child)) {
15639
+ for (const item of child) {
15640
+ if (isAstNode(item)) visit(item);
15641
+ }
15642
+ } else if (isAstNode(child)) {
15643
+ visit(child);
15644
+ }
15645
+ }
15646
+ }
15647
+ visit(ast);
15648
+ }
15649
+ function isAstNode(v) {
15650
+ return !!v && typeof v === "object" && typeof v.type === "string";
15651
+ }
15652
+ var BUILTIN_GLOBALS2 = /* @__PURE__ */ new Set([
15653
+ // ─── Template runtime helpers (injected by compileToFunction) ───────
15654
+ //
15655
+ // These variables appear in the generated template function signature
15656
+ // or body. They must be excluded from extractGlobalVars() so that
15657
+ // they are not mistaken for user data variables and destructured from $data.
15658
+ // SPLITTER character constant (same as \x1e), used as namespace separator
15659
+ // for refData keys, event attribute encoding, and internal data structures.
15660
+ // Declared as: let $splitter='\x1e'
15661
+ "$splitter",
15662
+ // Data — the data object passed from Updater to the template function.
15663
+ // User variables are destructured from $data at the top of the function:
15664
+ // let {name, age} = $data;
15665
+ // This is the first parameter of the generated arrow function.
15666
+ "$data",
15667
+ // Null-safe toString: v => '' + (v == null ? '' : v)
15668
+ // Converts null/undefined to empty string, otherwise calls toString().
15669
+ // Wraps every {{!raw}} output to prevent "null" / "undefined" rendering.
15670
+ "$strSafe",
15671
+ // HTML entity encoder: v => $strSafe(v).replace(/[&<>"'`]/g, entityMap)
15672
+ // Encodes &, <, >, ", ', ` to HTML entities (&amp; &lt; etc.)
15673
+ // Applied to all {{=escaped}} and {{:binding}} outputs.
15674
+ "$encHtml",
15675
+ // HTML entity map — internal object used by $encHtml:
15676
+ // {'&':'amp','<':'gt','>':'gt','"':'#34','\'':'#39','`':'#96'}
15677
+ // Not a standalone function; referenced inside $encHtml's closure.
15678
+ "$entMap",
15679
+ // HTML entity RegExp — internal regexp used by $encHtml:
15680
+ // /[&<>"'`]/g
15681
+ "$entReg",
15682
+ // HTML entity replacer function — internal helper used by $encHtml:
15683
+ // m => '&' + $entMap[m] + ';'
15684
+ // Maps matched character to its entity string.
15685
+ "$entFn",
15686
+ // Output buffer — the string accumulator for rendered HTML.
15687
+ // All template output is appended via $out += '...'.
15688
+ // Declared as: let $out = ''
15689
+ "$out",
15690
+ // Reference lookup: (refData, value) => key
15691
+ // Finds or allocates a SPLITTER-prefixed key in refData for a given
15692
+ // object reference. Used by {{@ref}} operator for passing object
15693
+ // references to child views via v-lark attributes.
15694
+ "$refFn",
15695
+ // URI encoder: v => encodeURIComponent($strSafe(v)).replace(/[!')(*]/g, extraMap)
15696
+ // Extends encodeURIComponent with encoding of ! ' ( ) *.
15697
+ // Applied to values in @event URL parameters and {{!uri}} contexts.
15698
+ "$encUri",
15699
+ // URI encode map — internal object used by $encUri:
15700
+ // {'!':'%21','\'':'%27','(':'%28',')':'%29','*':'%2A'}
15701
+ "$uriMap",
15702
+ // URI encode replacer — internal helper used by $encUri:
15703
+ // m => $uriMap[m]
15704
+ "$uriFn",
15705
+ // URI encode regexp — internal regexp used by $encUri:
15706
+ // /[!')(*]/g
15707
+ "$uriReg",
15708
+ // Quote encoder: v => $strSafe(v).replace(/['"\\]/g, '\\$&')
15709
+ // Escapes quotes and backslashes for safe embedding in HTML attribute
15710
+ // values (e.g. data-json='...').
15711
+ "$encQuote",
15712
+ // Quote encode regexp — internal regexp used by $encQuote:
15713
+ // /['"\\]/g
15714
+ "$qReg",
15715
+ // View ID — the unique identifier of the owning View instance.
15716
+ // Injected into @event attribute values at render time so that
15717
+ // EventDelegator can dispatch events to the correct View handler.
15718
+ // The \x1f placeholder in compiled output is replaced with '+$viewId+'.
15719
+ "$viewId",
15720
+ // Debug: current expression text — stores the template expression being
15721
+ // evaluated, for error reporting. Only present in debug mode.
15722
+ // e.g. $dbgExpr='<%=user.name%>'
15723
+ "$dbgExpr",
15724
+ // Debug: original art syntax — stores the {{}} template syntax before
15725
+ // conversion, for error reporting. Only present in debug mode.
15726
+ // e.g. $dbgArt='{{=user.name}}'
15727
+ "$dbgArt",
15728
+ // Debug: source line number — tracks the current line in the template
15729
+ // source, for error reporting. Only present in debug mode.
15730
+ "$dbgLine",
15731
+ // RefData alias — fallback reference lookup table.
15732
+ // Defaults to $data when no explicit $refAlt is provided.
15733
+ // Ensures $refFn() does not crash when @ operator is used without refData.
15734
+ "$refAlt",
15735
+ // Temporary variable — used by the compiler for intermediate
15736
+ // expression results in generated code (e.g. loop variables,
15737
+ // conditional branches). Declared as: let $tmp
15738
+ "$tmp",
15739
+ // JS literals
15740
+ "undefined",
15741
+ "null",
15742
+ "true",
15743
+ "false",
15744
+ "NaN",
15745
+ "Infinity",
15746
+ // JS built-in globals
15747
+ "window",
15748
+ "self",
15749
+ "globalThis",
15750
+ "document",
15751
+ "console",
15752
+ "JSON",
15753
+ "Math",
15754
+ "Intl",
15755
+ "Promise",
15756
+ "Symbol",
15757
+ "Number",
15758
+ "String",
15759
+ "Boolean",
15760
+ "Array",
15761
+ "Object",
15762
+ "Date",
15763
+ "RegExp",
15764
+ "Error",
15765
+ "TypeError",
15766
+ "RangeError",
15767
+ "SyntaxError",
15768
+ "Map",
15769
+ "Set",
15770
+ "WeakMap",
15771
+ "WeakSet",
15772
+ "Proxy",
15773
+ "Reflect",
15774
+ "ArrayBuffer",
15775
+ "DataView",
15776
+ "Float32Array",
15777
+ "Float64Array",
15778
+ "Int8Array",
15779
+ "Int16Array",
15780
+ "Int32Array",
15781
+ "Uint8Array",
15782
+ "Uint16Array",
15783
+ "Uint32Array",
15784
+ "Uint8ClampedArray",
15785
+ // Functions
15786
+ "parseInt",
15787
+ "parseFloat",
15788
+ "isNaN",
15789
+ "isFinite",
15790
+ "encodeURIComponent",
15791
+ "decodeURIComponent",
15792
+ "encodeURI",
15793
+ "decodeURI",
15794
+ // Babel helpers
15795
+ "arguments",
15796
+ "this",
15797
+ "require",
15798
+ // Lark framework
15799
+ "Lark"
15800
+ ]);
15801
+
15802
+ // src/compiler/compile-template.ts
15803
+ function compileToFunction(source, debug, file) {
15804
+ const matcher = /<%([@=!:])?([\s\S]*?)%>|$/g;
15805
+ let index = 0;
15806
+ let funcSource = `$out+='`;
15807
+ let hasAtRule = false;
15808
+ const escapeSlashRegExp = /\\|'/g;
15809
+ const escapeBreakReturnRegExp = /\r|\n/g;
15810
+ source.replace(matcher, (match, operate, content, offset) => {
15811
+ funcSource += source.substring(index, offset).replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
15812
+ index = offset + match.length;
15813
+ if (debug) {
15814
+ let expr = source.substring(
15815
+ index - match.length + 2 + (operate ? 1 : 0),
15816
+ index - 2
15817
+ );
15818
+ const x11 = String.fromCharCode(17);
15819
+ const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
15820
+ const artM = expr.match(artRegExp);
15821
+ let art = "";
15822
+ let line = -1;
15823
+ if (artM) {
15824
+ expr = expr.replace(artRegExp, "");
15825
+ art = artM[2];
15826
+ line = parseInt(artM[1], 10);
15827
+ } else {
15828
+ expr = expr.replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
15829
+ }
15830
+ if (operate === "@") {
15831
+ hasAtRule = true;
15832
+ funcSource += `'+($dbgExpr='<%${operate + expr}%>',$refFn($refAlt,${content}))+'`;
15833
+ } else if (operate === "=" || operate === ":") {
15834
+ funcSource += `'+($dbgExpr='<%${operate + expr}%>',$encHtml(${content}))+'`;
15835
+ } else if (operate === "!") {
15836
+ if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
15837
+ content = `$strSafe(${content})`;
15838
+ }
15839
+ funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
15840
+ } else if (content) {
15841
+ if (line > -1) {
15842
+ funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
15843
+ content = "";
15844
+ } else {
15845
+ funcSource += `';`;
15846
+ }
15847
+ if (funcSource.endsWith(`+'';`)) {
15848
+ funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
15849
+ }
15850
+ if (expr) {
15851
+ funcSource += `$dbgExpr='<%${expr}%>';`;
15852
+ }
15853
+ funcSource += content + `;$out+='`;
15854
+ }
15855
+ } else {
15856
+ if (operate === "@") {
15857
+ hasAtRule = true;
15858
+ funcSource += `'+$refFn($refAlt,${content})+'`;
15859
+ } else if (operate === "=" || operate === ":") {
15860
+ funcSource += `'+$encHtml(${content})+'`;
15861
+ } else if (operate === "!") {
15862
+ if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
15863
+ content = `$strSafe(${content})`;
15864
+ }
15865
+ funcSource += `'+${content}+'`;
15866
+ } else if (content) {
15867
+ funcSource += `';`;
15868
+ if (funcSource.endsWith(`+'';`)) {
15869
+ funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
15870
+ }
15871
+ funcSource += `${content};$out+='`;
15872
+ }
15873
+ }
15874
+ return match;
15875
+ });
15876
+ funcSource += `';`;
15877
+ funcSource = funcSource.replace(/\$out\+='';/g, "");
15878
+ funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
15879
+ if (debug) {
15880
+ const filePart = file ? `\\r\\n\\tat file:${file}` : "";
15881
+ funcSource = `let $dbgExpr,$dbgArt,$dbgLine;try{${funcSource}}catch(ex){let msg='render view error:'+(ex.message||ex);if($dbgArt)msg+='\\r\\n\\tsrc art:{{'+$dbgArt+'}}\\r\\n\\tat line:'+$dbgLine;msg+='\\r\\n\\t'+($dbgArt?'translate to:':'expr:');msg+=$dbgExpr+'${filePart}';throw msg;}`;
15882
+ }
15883
+ const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
15884
+ funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
15885
+ void hasAtRule;
15886
+ const refFallback = "if(!$refAlt)$refAlt=$data;";
15887
+ const fullSource = `${refFallback}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
15888
+ return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
15889
+ }
15890
+ async function compileTemplate(source, options = {}) {
15891
+ const { debug = false, file, virtualDom = false, useSwc = false } = options;
15892
+ const globalVars = options.globalVars ?? await (useSwc ? extractGlobalVars(source) : extractGlobalVars2(source));
15893
+ const { protectedSource, comments } = protectComments(source);
15894
+ const converted = convertArtSyntax(protectedSource, debug);
15895
+ const viewEventProcessed = processViewEvents(converted);
15896
+ const finalSource = restoreComments(viewEventProcessed, comments);
15897
+ const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
15898
+ if (virtualDom) {
15899
+ const funcBody2 = compileToVDomFunction(finalSource, debug, file);
15900
+ const funcWithVars2 = funcBody2.replace("{{VARS}}", () => varDeclarations);
15901
+ return `import { vdomCreate as __larkC } from "@lark.js/mvc";
15902
+ import { strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15903
+ export default function(data, viewId, refData) {
15904
+ let $data = data || {},
15905
+ $viewId = viewId || '',
15906
+ $c = __larkC,
15907
+ $n = __larkStrSafe;
15908
+ return (${funcWithVars2})($data, $viewId, refData,
15909
+ $n, __larkRefFn, __larkEncUri, __larkEncQuote
15910
+ );
15911
+ }`;
15912
+ }
15913
+ const funcBody = compileToFunction(finalSource, debug, file);
15914
+ const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
15915
+ return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15916
+ export default function(data, viewId, refData) {
15917
+ let $data = data || {},
15918
+ $viewId = viewId || '';
15919
+ return (${funcWithVars})($data, $viewId, refData,
15920
+ __larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
15921
+ );
15922
+ }`;
15923
+ }
15924
+
15367
15925
  // src/vite.ts
15368
15926
  var LARK_TEMPLATE_SUFFIX = "?lark-template";
15369
15927
  function larkMvcPlugin(options = {}) {
15370
- const { debug = false } = options;
15928
+ const { debug = false, virtualDom = false, useSwc = false } = options;
15371
15929
  return {
15372
15930
  name: "lark-template",
15373
15931
  enforce: "pre",
@@ -15377,12 +15935,12 @@ function larkMvcPlugin(options = {}) {
15377
15935
  }
15378
15936
  return void 0;
15379
15937
  },
15380
- load(id) {
15938
+ async load(id) {
15381
15939
  if (id.endsWith(LARK_TEMPLATE_SUFFIX)) {
15382
15940
  const filePath = id.slice(0, -LARK_TEMPLATE_SUFFIX.length);
15383
15941
  const raw = import_fs.default.readFileSync(filePath, "utf-8");
15384
- const globalVars = extractGlobalVars(raw);
15385
- return compileTemplate(raw, { debug, globalVars });
15942
+ const globalVars = await extractGlobalVars2(raw);
15943
+ return compileTemplate(raw, { debug, globalVars, virtualDom, useSwc });
15386
15944
  }
15387
15945
  return void 0;
15388
15946
  }