@lark.js/mvc 0.0.10 → 0.0.12

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