@lark.js/mvc 0.0.14 → 0.0.16

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.js CHANGED
@@ -27,12 +27,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  mod
28
28
  ));
29
29
 
30
- // ../../node_modules/.pnpm/tsup@8.5.1_@swc+core@1.15.43_@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/esm_shims.js
30
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.7.0_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/esm_shims.js
31
31
  import path from "path";
32
32
  import { fileURLToPath } from "url";
33
33
  var getFilename, getDirname, __dirname;
34
34
  var init_esm_shims = __esm({
35
- "../../node_modules/.pnpm/tsup@8.5.1_@swc+core@1.15.43_@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/esm_shims.js"() {
35
+ "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.7.0_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/esm_shims.js"() {
36
36
  "use strict";
37
37
  getFilename = () => fileURLToPath(import.meta.url);
38
38
  getDirname = () => path.dirname(getFilename());
@@ -14738,12 +14738,7 @@ function convertArtSyntax(source, debug) {
14738
14738
  } else {
14739
14739
  cleanCode = code.trim();
14740
14740
  }
14741
- const converted = convertArtExpression(
14742
- cleanCode,
14743
- debug,
14744
- lineNo,
14745
- blockStack
14746
- );
14741
+ const converted = convertArtExpression(cleanCode, debug, lineNo, blockStack);
14747
14742
  result.push(converted);
14748
14743
  result.push(rest);
14749
14744
  }
@@ -14989,12 +14984,74 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
14989
14984
  function vdomEscapeStr(s) {
14990
14985
  return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\x1e/g, "\\x1e");
14991
14986
  }
14987
+ function vdomResolveAttrValueIIFE(rawValue, exprStore) {
14988
+ const stmts = [];
14989
+ let remaining = rawValue;
14990
+ while (remaining.length > 0) {
14991
+ const phIdx = remaining.indexOf("\0");
14992
+ const viIdx = remaining.indexOf("");
14993
+ let nextSpecial = -1;
14994
+ let specialType = null;
14995
+ if (phIdx >= 0 && (viIdx < 0 || phIdx <= viIdx)) {
14996
+ nextSpecial = phIdx;
14997
+ specialType = "ph";
14998
+ } else if (viIdx >= 0) {
14999
+ nextSpecial = viIdx;
15000
+ specialType = "vi";
15001
+ }
15002
+ if (nextSpecial === -1) {
15003
+ if (remaining) stmts.push(`$s+='${vdomEscapeStr(remaining)}'`);
15004
+ break;
15005
+ }
15006
+ if (nextSpecial > 0) {
15007
+ stmts.push(`$s+='${vdomEscapeStr(remaining.substring(0, nextSpecial))}'`);
15008
+ }
15009
+ if (specialType === "vi") {
15010
+ stmts.push(`$s+=$viewId`);
15011
+ remaining = remaining.substring(nextSpecial + 1);
15012
+ } else {
15013
+ const closeIdx = remaining.indexOf("\0", nextSpecial + 1);
15014
+ if (closeIdx === -1) {
15015
+ stmts.push(`$s+='${vdomEscapeStr(remaining.substring(nextSpecial))}'`);
15016
+ break;
15017
+ }
15018
+ const idx = parseInt(remaining.substring(nextSpecial + 1, closeIdx), 10);
15019
+ const expr = exprStore[idx];
15020
+ if (expr.op === "=" || expr.op === ":") {
15021
+ stmts.push(`$s+=$strSafe(${expr.content})`);
15022
+ } else if (expr.op === "!") {
15023
+ if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15024
+ stmts.push(`$s+=${expr.content}`);
15025
+ } else {
15026
+ stmts.push(`$s+=$strSafe(${expr.content})`);
15027
+ }
15028
+ } else if (expr.op === "@") {
15029
+ stmts.push(`$s+=$refFn($refAlt,${expr.content})`);
15030
+ } else {
15031
+ stmts.push(expr.content);
15032
+ }
15033
+ remaining = remaining.substring(closeIdx + 1);
15034
+ }
15035
+ }
15036
+ const body = stmts.join(";");
15037
+ return `(()=>{let $s='';${body};return $s;})()`;
15038
+ }
14992
15039
  function vdomResolveAttrValue(rawValue, exprStore) {
14993
15040
  const hasPlaceholders = rawValue.includes("\0");
14994
15041
  const hasViewId = rawValue.includes("");
14995
15042
  if (!hasPlaceholders && !hasViewId) {
14996
15043
  return `'${vdomEscapeStr(rawValue)}'`;
14997
15044
  }
15045
+ if (hasPlaceholders) {
15046
+ const codeBlockRegExp = /\x00(\d+)\x00/g;
15047
+ let m;
15048
+ while ((m = codeBlockRegExp.exec(rawValue)) !== null) {
15049
+ const idx = parseInt(m[1], 10);
15050
+ if (exprStore[idx] && exprStore[idx].op === "") {
15051
+ return vdomResolveAttrValueIIFE(rawValue, exprStore);
15052
+ }
15053
+ }
15054
+ }
14998
15055
  const segments = [];
14999
15056
  let remaining = rawValue;
15000
15057
  while (remaining.length > 0) {
@@ -15028,17 +15085,17 @@ function vdomResolveAttrValue(rawValue, exprStore) {
15028
15085
  const idx = parseInt(remaining.substring(nextSpecial + 1, closeIdx));
15029
15086
  const expr = exprStore[idx];
15030
15087
  if (expr.op === "=" || expr.op === ":") {
15031
- segments.push(`$n(${expr.content})`);
15088
+ segments.push(`$strSafe(${expr.content})`);
15032
15089
  } else if (expr.op === "!") {
15033
15090
  if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15034
15091
  segments.push(expr.content);
15035
15092
  } else {
15036
- segments.push(`$n(${expr.content})`);
15093
+ segments.push(`$strSafe(${expr.content})`);
15037
15094
  }
15038
15095
  } else if (expr.op === "@") {
15039
15096
  segments.push(`$refFn($refAlt,${expr.content})`);
15040
15097
  } else {
15041
- segments.push(`$n(${expr.content})`);
15098
+ segments.push(`$strSafe(${expr.content})`);
15042
15099
  }
15043
15100
  remaining = remaining.substring(closeIdx + 1);
15044
15101
  }
@@ -15080,14 +15137,7 @@ function compileToVDomFunction(source, debug, file) {
15080
15137
  });
15081
15138
  const rootVar = `$v${varCounter++}`;
15082
15139
  lines.push(`let ${rootVar}=[]`);
15083
- const maxVars = 30;
15084
- const varDecls = [];
15085
- for (let i = 1; i < maxVars; i++) {
15086
- varDecls.push(`$v${i}`);
15087
- }
15088
- lines.push(`let ${varDecls.join(",")}`);
15089
15140
  function allocVar() {
15090
- if (varCounter >= maxVars) return `$v${maxVars - 1}`;
15091
15141
  return `$v${varCounter++}`;
15092
15142
  }
15093
15143
  function emitNode(node, parentVar) {
@@ -15104,7 +15154,7 @@ function compileToVDomFunction(source, debug, file) {
15104
15154
  if (i % 2 === 0) {
15105
15155
  const trimmed = parts[i];
15106
15156
  if (trimmed.trim()) {
15107
- lines.push(`${parentVar}.push($c(0,'${vdomEscapeStr(trimmed)}'))`);
15157
+ lines.push(`${parentVar}.push($vdomCreate(0,'${vdomEscapeStr(trimmed)}'))`);
15108
15158
  }
15109
15159
  } else {
15110
15160
  const idx = parseInt(parts[i]);
@@ -15115,15 +15165,15 @@ function compileToVDomFunction(source, debug, file) {
15115
15165
  }
15116
15166
  function emitExpr(expr, parentVar) {
15117
15167
  if (expr.op === "=" || expr.op === ":") {
15118
- lines.push(`${parentVar}.push($c(0,$n(${expr.content})))`);
15168
+ lines.push(`${parentVar}.push($vdomCreate(0,$strSafe(${expr.content})))`);
15119
15169
  } else if (expr.op === "!") {
15120
15170
  if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15121
- lines.push(`${parentVar}.push($c(0,${expr.content}))`);
15171
+ lines.push(`${parentVar}.push($vdomCreate(0,${expr.content},1))`);
15122
15172
  } else {
15123
- lines.push(`${parentVar}.push($c(0,$n(${expr.content})))`);
15173
+ lines.push(`${parentVar}.push($vdomCreate(0,$strSafe(${expr.content}),1))`);
15124
15174
  }
15125
15175
  } else if (expr.op === "@") {
15126
- lines.push(`${parentVar}.push($c(0,$refFn($refAlt,${expr.content})))`);
15176
+ lines.push(`${parentVar}.push($vdomCreate(0,$refFn($refAlt,${expr.content})))`);
15127
15177
  } else if (expr.content) {
15128
15178
  lines.push(expr.content);
15129
15179
  }
@@ -15141,25 +15191,26 @@ function compileToVDomFunction(source, debug, file) {
15141
15191
  }
15142
15192
  const isVoid = VOID_ELEMENTS.has(tagName) && children.length === 0;
15143
15193
  const childrenArg = isVoid ? "1" : childVar;
15144
- lines.push(
15145
- `${parentVar}.push($c('${tagName}',${propsKey},${childrenArg}))`
15146
- );
15194
+ lines.push(`${parentVar}.push($vdomCreate('${tagName}',${propsKey},${childrenArg}))`);
15147
15195
  }
15148
15196
  for (const child of doc.children) {
15149
15197
  emitNode(child, rootVar);
15150
15198
  }
15151
- lines.push(`return $c($viewId,0,${rootVar})`);
15152
- const body = lines.join(";");
15199
+ lines.push(`return $vdomCreate($viewId,0,${rootVar})`);
15200
+ const varDeclStmts = [];
15201
+ for (let i = 1; i < varCounter; i++) varDeclStmts.push(`$v${i}`);
15202
+ const varDecl = varDeclStmts.length ? `let ${varDeclStmts.join(",")};` : "";
15203
+ const body = varDecl + lines.join(";");
15153
15204
  let funcBody = body;
15154
15205
  if (debug) {
15155
15206
  const filePart = file ? `\\r\\n\\tat file:${file}` : "";
15156
- funcBody = `let $dbgExpr,$dbgArt,$dbgLine;try{${body}}catch(ex){let msg='render view error:'+(ex.message||ex);msg+='${filePart}';throw msg;}`;
15207
+ funcBody = `let $dbgExpr,$dbgArt;try{${body}}catch(e){let msg='render error:'+(e.message||e);msg+='${filePart}';throw msg;}`;
15157
15208
  }
15158
15209
  const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
15159
15210
  funcBody = funcBody.replace(viewIdRegExp, `'+$viewId+'`);
15160
15211
  const refFallback = "if(!$refAlt)$refAlt=$data;";
15161
15212
  const fullSource = `${refFallback}let $splitter='\\x1e'{{VARS}};${funcBody}`;
15162
- return `($data,$viewId,$refAlt,$n,$refFn,$encUri,$encQuote)=>{${fullSource}}`;
15213
+ return `($data,$viewId,$refAlt,$strSafe,$refFn,$encUri,$encQuote)=>{${fullSource}}`;
15163
15214
  }
15164
15215
 
15165
15216
  // src/compiler/extract-global-vars.ts
@@ -15393,9 +15444,6 @@ var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
15393
15444
  // conversion, for error reporting. Only present in debug mode.
15394
15445
  // e.g. $dbgArt='{{=user.name}}'
15395
15446
  "$dbgArt",
15396
- // Debug: source line number — tracks the current line in the template
15397
- // source, for error reporting. Only present in debug mode.
15398
- "$dbgLine",
15399
15447
  // RefData alias — fallback reference lookup table.
15400
15448
  // Defaults to $data when no explicit $refAlt is provided.
15401
15449
  // Ensures $refFn() does not crash when @ operator is used without refData.
@@ -15479,19 +15527,14 @@ function compileToFunction(source, debug, file) {
15479
15527
  funcSource += source.substring(index, offset).replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
15480
15528
  index = offset + match.length;
15481
15529
  if (debug) {
15482
- let expr = source.substring(
15483
- index - match.length + 2 + (operate ? 1 : 0),
15484
- index - 2
15485
- );
15530
+ let expr = source.substring(index - match.length + 2 + (operate ? 1 : 0), index - 2);
15486
15531
  const x11 = String.fromCharCode(17);
15487
15532
  const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
15488
15533
  const artM = expr.match(artRegExp);
15489
15534
  let art = "";
15490
- let line = -1;
15491
15535
  if (artM) {
15492
15536
  expr = expr.replace(artRegExp, "");
15493
15537
  art = artM[2];
15494
- line = parseInt(artM[1], 10);
15495
15538
  } else {
15496
15539
  expr = expr.replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
15497
15540
  }
@@ -15506,8 +15549,8 @@ function compileToFunction(source, debug, file) {
15506
15549
  }
15507
15550
  funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
15508
15551
  } else if (content) {
15509
- if (line > -1) {
15510
- funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
15552
+ if (artM) {
15553
+ funcSource += `';$dbgArt='${art}';`;
15511
15554
  content = "";
15512
15555
  } else {
15513
15556
  funcSource += `';`;
@@ -15546,7 +15589,7 @@ function compileToFunction(source, debug, file) {
15546
15589
  funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
15547
15590
  if (debug) {
15548
15591
  const filePart = file ? `\\r\\n\\tat file:${file}` : "";
15549
- 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;}`;
15592
+ funcSource = `let $dbgExpr,$dbgArt;try{${funcSource}}catch(e){let msg='render error:'+(e.message||e);if($dbgArt)msg+='\\r\\n\\tsrc art:{{'+$dbgArt+'}};msg+='\\r\\n\\t'+($dbgArt?'translate to:':'expr:');msg+=$dbgExpr+'${filePart}';throw msg;}`;
15550
15593
  }
15551
15594
  const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
15552
15595
  funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
@@ -15566,28 +15609,205 @@ async function compileTemplate(source, options = {}) {
15566
15609
  if (virtualDom) {
15567
15610
  const funcBody2 = compileToVDomFunction(finalSource, debug, file);
15568
15611
  const funcWithVars2 = funcBody2.replace("{{VARS}}", () => varDeclarations);
15569
- return `import { vdomCreate as __larkC } from "@lark.js/mvc";
15612
+ return `import { vdomCreate as __larkVdomCreate } from "@lark.js/mvc";
15570
15613
  import { strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15571
- export default function(data, viewId, refData) {
15614
+ function __larkTemplate(data, viewId, refData) {
15572
15615
  let $data = data || {},
15573
15616
  $viewId = viewId || '',
15574
- $c = __larkC,
15575
- $n = __larkStrSafe;
15617
+ $vdomCreate = __larkVdomCreate,
15618
+ $strSafe = __larkStrSafe;
15576
15619
  return (${funcWithVars2})($data, $viewId, refData,
15577
- $n, __larkRefFn, __larkEncUri, __larkEncQuote
15620
+ $strSafe, __larkRefFn, __larkEncUri, __larkEncQuote
15578
15621
  );
15579
- }`;
15622
+ }
15623
+ export default __larkTemplate;`;
15580
15624
  }
15581
15625
  const funcBody = compileToFunction(finalSource, debug, file);
15582
15626
  const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
15583
15627
  return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15584
- export default function(data, viewId, refData) {
15628
+ function __larkTemplate(data, viewId, refData) {
15585
15629
  let $data = data || {},
15586
15630
  $viewId = viewId || '';
15587
15631
  return (${funcWithVars})($data, $viewId, refData,
15588
15632
  __larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
15589
15633
  );
15590
- }`;
15634
+ }
15635
+ export default __larkTemplate;`;
15636
+ }
15637
+
15638
+ // src/hmr-inject.ts
15639
+ init_esm_shims();
15640
+ var TEMPLATE_VAR = "__larkTemplate";
15641
+ function getTemplateHmrSnippet(bundler) {
15642
+ if (bundler === "vite") {
15643
+ return `
15644
+ // \u2500\u2500 Lark template HMR (auto-injected by larkMvcPlugin \u2014 Vite) \u2500\u2500
15645
+ if (import.meta.hot) {
15646
+ import.meta.hot.dispose(function(__larkData) {
15647
+ __larkData.oldTemplate = ${TEMPLATE_VAR};
15648
+ });
15649
+ import.meta.hot.accept(function(__larkNewModule) {
15650
+ var __larkNew = __larkNewModule && __larkNewModule.default;
15651
+ var __larkOld = import.meta.hot.data && import.meta.hot.data.oldTemplate;
15652
+ if (__larkOld && __larkNew && __larkOld !== __larkNew) {
15653
+ import("@lark.js/mvc").then(function(m) {
15654
+ if (m && m.hotSwapByTemplate) m.hotSwapByTemplate(__larkOld, __larkNew);
15655
+ });
15656
+ }
15657
+ });
15658
+ }
15659
+ `;
15660
+ }
15661
+ return `
15662
+ // \u2500\u2500 Lark template HMR (auto-injected by larkMvcPlugin \u2014 ${bundler}) \u2500\u2500
15663
+ if (typeof module !== "undefined" && module.hot) {
15664
+ module.hot.dispose(function(__larkData) {
15665
+ __larkData.oldTemplate = ${TEMPLATE_VAR};
15666
+ });
15667
+ module.hot.accept(function() {
15668
+ var __larkNew = ${TEMPLATE_VAR};
15669
+ var __larkOld = module.hot && module.hot.data && module.hot.data.oldTemplate;
15670
+ if (__larkOld && __larkNew && __larkOld !== __larkNew) {
15671
+ import("@lark.js/mvc").then(function(m) {
15672
+ if (m && m.hotSwapByTemplate) m.hotSwapByTemplate(__larkOld, __larkNew);
15673
+ });
15674
+ }
15675
+ });
15676
+ }
15677
+ `;
15678
+ }
15679
+ function injectTemplateHmrSnippet(source, bundler) {
15680
+ return source + "\n" + getTemplateHmrSnippet(bundler);
15681
+ }
15682
+ function getViewHmrSnippet(bundler) {
15683
+ const VIEW_VAR = "__larkViewDefault";
15684
+ if (bundler === "vite") {
15685
+ return `
15686
+ // \u2500\u2500 Lark view class HMR (auto-injected by larkMvcPlugin \u2014 Vite) \u2500\u2500
15687
+ if (import.meta.hot) {
15688
+ import.meta.hot.dispose(function(__larkData) {
15689
+ __larkData.oldClass = ${VIEW_VAR};
15690
+ });
15691
+ import.meta.hot.accept(function(__larkNewModule) {
15692
+ var __larkNew = __larkNewModule && __larkNewModule.default;
15693
+ var __larkOld = import.meta.hot.data && import.meta.hot.data.oldClass;
15694
+ if (__larkOld && __larkNew && __larkOld !== __larkNew) {
15695
+ import("@lark.js/mvc").then(function(m) {
15696
+ if (m && m.hotSwapByView) m.hotSwapByView(__larkOld, __larkNew);
15697
+ });
15698
+ }
15699
+ });
15700
+ }
15701
+ `;
15702
+ }
15703
+ return `
15704
+ // \u2500\u2500 Lark view class HMR (auto-injected by larkMvcPlugin \u2014 ${bundler}) \u2500\u2500
15705
+ if (typeof module !== "undefined" && module.hot) {
15706
+ module.hot.dispose(function(__larkData) {
15707
+ __larkData.oldClass = ${VIEW_VAR};
15708
+ });
15709
+ module.hot.accept(function() {
15710
+ var __larkNew = ${VIEW_VAR};
15711
+ var __larkOld = module.hot && module.hot.data && module.hot.data.oldClass;
15712
+ if (__larkOld && __larkNew && __larkOld !== __larkNew) {
15713
+ import("@lark.js/mvc").then(function(m) {
15714
+ if (m && m.hotSwapByView) m.hotSwapByView(__larkOld, __larkNew);
15715
+ });
15716
+ }
15717
+ });
15718
+ }
15719
+ `;
15720
+ }
15721
+ var HTML_IMPORT_RE = /import\s+(?:template\s+from\s+|.*from\s+)?["'][^"']+\.html["']/;
15722
+ function importsHtmlTemplate(source) {
15723
+ return HTML_IMPORT_RE.test(source);
15724
+ }
15725
+ function injectViewHmr(source, bundler) {
15726
+ if (!importsHtmlTemplate(source)) return source;
15727
+ const exportDefaultRe = /export\s+default\s+/;
15728
+ const match = exportDefaultRe.exec(source);
15729
+ if (!match) return source;
15730
+ const startIdx = match.index + match[0].length;
15731
+ const endIdx = findExpressionEnd(source, startIdx);
15732
+ if (endIdx === -1) return source;
15733
+ const expression = source.substring(startIdx, endIdx);
15734
+ const before = source.substring(0, match.index);
15735
+ const after = source.substring(endIdx);
15736
+ const VIEW_VAR = "__larkViewDefault";
15737
+ const transformed = before + `const ${VIEW_VAR} = ${expression};
15738
+ export default ${VIEW_VAR};` + after + "\n" + getViewHmrSnippet(bundler);
15739
+ return transformed;
15740
+ }
15741
+ function findExpressionEnd(source, startIdx) {
15742
+ let depth = 0;
15743
+ let inString = null;
15744
+ let inTemplate = false;
15745
+ let inLineComment = false;
15746
+ let inBlockComment = false;
15747
+ for (let i = startIdx; i < source.length; i++) {
15748
+ const ch = source[i];
15749
+ const next = source[i + 1];
15750
+ if (inLineComment) {
15751
+ if (ch === "\n") inLineComment = false;
15752
+ continue;
15753
+ }
15754
+ if (inBlockComment) {
15755
+ if (ch === "*" && next === "/") {
15756
+ inBlockComment = false;
15757
+ i++;
15758
+ }
15759
+ continue;
15760
+ }
15761
+ if (inString) {
15762
+ if (ch === "\\") {
15763
+ i++;
15764
+ continue;
15765
+ }
15766
+ if (ch === inString) inString = null;
15767
+ continue;
15768
+ }
15769
+ if (inTemplate) {
15770
+ if (ch === "\\") {
15771
+ i++;
15772
+ continue;
15773
+ }
15774
+ if (ch === "`") inTemplate = false;
15775
+ continue;
15776
+ }
15777
+ if (ch === "/" && next === "/") {
15778
+ inLineComment = true;
15779
+ i++;
15780
+ continue;
15781
+ }
15782
+ if (ch === "/" && next === "*") {
15783
+ inBlockComment = true;
15784
+ i++;
15785
+ continue;
15786
+ }
15787
+ if (ch === '"' || ch === "'") {
15788
+ inString = ch;
15789
+ continue;
15790
+ }
15791
+ if (ch === "`") {
15792
+ inTemplate = true;
15793
+ continue;
15794
+ }
15795
+ if (ch === "(" || ch === "{" || ch === "[") {
15796
+ depth++;
15797
+ continue;
15798
+ }
15799
+ if (ch === ")" || ch === "}" || ch === "]") {
15800
+ depth--;
15801
+ if (depth === 0) {
15802
+ return i + 1;
15803
+ }
15804
+ continue;
15805
+ }
15806
+ if (depth === 0 && ch === ";") {
15807
+ return i;
15808
+ }
15809
+ }
15810
+ return -1;
15591
15811
  }
15592
15812
 
15593
15813
  // src/vite.ts
@@ -15636,9 +15856,30 @@ function larkMvcPlugin(options = {}) {
15636
15856
  if (!existsSync(filePath)) return void 0;
15637
15857
  const raw = readFileSync(filePath, "utf-8");
15638
15858
  const globalVars = await extractGlobalVars(raw);
15639
- return compileTemplate(raw, { debug, globalVars, virtualDom });
15859
+ const compiled = await compileTemplate(raw, {
15860
+ debug,
15861
+ globalVars,
15862
+ virtualDom
15863
+ });
15864
+ return { code: injectTemplateHmrSnippet(compiled, "vite"), map: null };
15640
15865
  }
15641
15866
  return void 0;
15867
+ },
15868
+ /**
15869
+ * Transform hook: inject view-class HMR into .ts files that import .html.
15870
+ *
15871
+ * When a .ts view file changes, the auto-injected HMR snippet captures
15872
+ * the old View setup function (via dispose) and the new one (via accept),
15873
+ * then calls `hotSwapByView(old, new)` to hot-swap all mounted views
15874
+ * — preserving state.
15875
+ */
15876
+ transform(code, id) {
15877
+ if (!/\.[tj]s$/.test(id)) return void 0;
15878
+ if (id.includes("node_modules")) return void 0;
15879
+ if (!importsHtmlTemplate(code)) return void 0;
15880
+ const transformed = injectViewHmr(code, "vite");
15881
+ if (transformed === code) return void 0;
15882
+ return { code: transformed, map: null };
15642
15883
  }
15643
15884
  };
15644
15885
  }
@@ -15659,7 +15900,12 @@ function larkMvcPluginLegacy(options = {}) {
15659
15900
  const filePath = id.slice(0, -LARK_TEMPLATE_SUFFIX.length);
15660
15901
  const raw = readFileSync(filePath, "utf-8");
15661
15902
  const globalVars = await extractGlobalVars(raw);
15662
- return compileTemplate(raw, { debug, globalVars, virtualDom });
15903
+ const compiled = await compileTemplate(raw, {
15904
+ debug,
15905
+ globalVars,
15906
+ virtualDom
15907
+ });
15908
+ return { code: compiled, map: null };
15663
15909
  }
15664
15910
  return void 0;
15665
15911
  }