@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/compiler.js CHANGED
@@ -14709,12 +14709,7 @@ function convertArtSyntax(source, debug) {
14709
14709
  } else {
14710
14710
  cleanCode = code.trim();
14711
14711
  }
14712
- const converted = convertArtExpression(
14713
- cleanCode,
14714
- debug,
14715
- lineNo,
14716
- blockStack
14717
- );
14712
+ const converted = convertArtExpression(cleanCode, debug, lineNo, blockStack);
14718
14713
  result.push(converted);
14719
14714
  result.push(rest);
14720
14715
  }
@@ -14959,12 +14954,74 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
14959
14954
  function vdomEscapeStr(s) {
14960
14955
  return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\x1e/g, "\\x1e");
14961
14956
  }
14957
+ function vdomResolveAttrValueIIFE(rawValue, exprStore) {
14958
+ const stmts = [];
14959
+ let remaining = rawValue;
14960
+ while (remaining.length > 0) {
14961
+ const phIdx = remaining.indexOf("\0");
14962
+ const viIdx = remaining.indexOf("");
14963
+ let nextSpecial = -1;
14964
+ let specialType = null;
14965
+ if (phIdx >= 0 && (viIdx < 0 || phIdx <= viIdx)) {
14966
+ nextSpecial = phIdx;
14967
+ specialType = "ph";
14968
+ } else if (viIdx >= 0) {
14969
+ nextSpecial = viIdx;
14970
+ specialType = "vi";
14971
+ }
14972
+ if (nextSpecial === -1) {
14973
+ if (remaining) stmts.push(`$s+='${vdomEscapeStr(remaining)}'`);
14974
+ break;
14975
+ }
14976
+ if (nextSpecial > 0) {
14977
+ stmts.push(`$s+='${vdomEscapeStr(remaining.substring(0, nextSpecial))}'`);
14978
+ }
14979
+ if (specialType === "vi") {
14980
+ stmts.push(`$s+=$viewId`);
14981
+ remaining = remaining.substring(nextSpecial + 1);
14982
+ } else {
14983
+ const closeIdx = remaining.indexOf("\0", nextSpecial + 1);
14984
+ if (closeIdx === -1) {
14985
+ stmts.push(`$s+='${vdomEscapeStr(remaining.substring(nextSpecial))}'`);
14986
+ break;
14987
+ }
14988
+ const idx = parseInt(remaining.substring(nextSpecial + 1, closeIdx), 10);
14989
+ const expr = exprStore[idx];
14990
+ if (expr.op === "=" || expr.op === ":") {
14991
+ stmts.push(`$s+=$strSafe(${expr.content})`);
14992
+ } else if (expr.op === "!") {
14993
+ if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
14994
+ stmts.push(`$s+=${expr.content}`);
14995
+ } else {
14996
+ stmts.push(`$s+=$strSafe(${expr.content})`);
14997
+ }
14998
+ } else if (expr.op === "@") {
14999
+ stmts.push(`$s+=$refFn($refAlt,${expr.content})`);
15000
+ } else {
15001
+ stmts.push(expr.content);
15002
+ }
15003
+ remaining = remaining.substring(closeIdx + 1);
15004
+ }
15005
+ }
15006
+ const body = stmts.join(";");
15007
+ return `(()=>{let $s='';${body};return $s;})()`;
15008
+ }
14962
15009
  function vdomResolveAttrValue(rawValue, exprStore) {
14963
15010
  const hasPlaceholders = rawValue.includes("\0");
14964
15011
  const hasViewId = rawValue.includes("");
14965
15012
  if (!hasPlaceholders && !hasViewId) {
14966
15013
  return `'${vdomEscapeStr(rawValue)}'`;
14967
15014
  }
15015
+ if (hasPlaceholders) {
15016
+ const codeBlockRegExp = /\x00(\d+)\x00/g;
15017
+ let m;
15018
+ while ((m = codeBlockRegExp.exec(rawValue)) !== null) {
15019
+ const idx = parseInt(m[1], 10);
15020
+ if (exprStore[idx] && exprStore[idx].op === "") {
15021
+ return vdomResolveAttrValueIIFE(rawValue, exprStore);
15022
+ }
15023
+ }
15024
+ }
14968
15025
  const segments = [];
14969
15026
  let remaining = rawValue;
14970
15027
  while (remaining.length > 0) {
@@ -14998,17 +15055,17 @@ function vdomResolveAttrValue(rawValue, exprStore) {
14998
15055
  const idx = parseInt(remaining.substring(nextSpecial + 1, closeIdx));
14999
15056
  const expr = exprStore[idx];
15000
15057
  if (expr.op === "=" || expr.op === ":") {
15001
- segments.push(`$n(${expr.content})`);
15058
+ segments.push(`$strSafe(${expr.content})`);
15002
15059
  } else if (expr.op === "!") {
15003
15060
  if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15004
15061
  segments.push(expr.content);
15005
15062
  } else {
15006
- segments.push(`$n(${expr.content})`);
15063
+ segments.push(`$strSafe(${expr.content})`);
15007
15064
  }
15008
15065
  } else if (expr.op === "@") {
15009
15066
  segments.push(`$refFn($refAlt,${expr.content})`);
15010
15067
  } else {
15011
- segments.push(`$n(${expr.content})`);
15068
+ segments.push(`$strSafe(${expr.content})`);
15012
15069
  }
15013
15070
  remaining = remaining.substring(closeIdx + 1);
15014
15071
  }
@@ -15050,14 +15107,7 @@ function compileToVDomFunction(source, debug, file) {
15050
15107
  });
15051
15108
  const rootVar = `$v${varCounter++}`;
15052
15109
  lines.push(`let ${rootVar}=[]`);
15053
- const maxVars = 30;
15054
- const varDecls = [];
15055
- for (let i = 1; i < maxVars; i++) {
15056
- varDecls.push(`$v${i}`);
15057
- }
15058
- lines.push(`let ${varDecls.join(",")}`);
15059
15110
  function allocVar() {
15060
- if (varCounter >= maxVars) return `$v${maxVars - 1}`;
15061
15111
  return `$v${varCounter++}`;
15062
15112
  }
15063
15113
  function emitNode(node, parentVar) {
@@ -15074,7 +15124,7 @@ function compileToVDomFunction(source, debug, file) {
15074
15124
  if (i % 2 === 0) {
15075
15125
  const trimmed = parts[i];
15076
15126
  if (trimmed.trim()) {
15077
- lines.push(`${parentVar}.push($c(0,'${vdomEscapeStr(trimmed)}'))`);
15127
+ lines.push(`${parentVar}.push($vdomCreate(0,'${vdomEscapeStr(trimmed)}'))`);
15078
15128
  }
15079
15129
  } else {
15080
15130
  const idx = parseInt(parts[i]);
@@ -15085,15 +15135,15 @@ function compileToVDomFunction(source, debug, file) {
15085
15135
  }
15086
15136
  function emitExpr(expr, parentVar) {
15087
15137
  if (expr.op === "=" || expr.op === ":") {
15088
- lines.push(`${parentVar}.push($c(0,$n(${expr.content})))`);
15138
+ lines.push(`${parentVar}.push($vdomCreate(0,$strSafe(${expr.content})))`);
15089
15139
  } else if (expr.op === "!") {
15090
15140
  if (expr.content.startsWith("$encUri(") && expr.content.endsWith(")")) {
15091
- lines.push(`${parentVar}.push($c(0,${expr.content}))`);
15141
+ lines.push(`${parentVar}.push($vdomCreate(0,${expr.content},1))`);
15092
15142
  } else {
15093
- lines.push(`${parentVar}.push($c(0,$n(${expr.content})))`);
15143
+ lines.push(`${parentVar}.push($vdomCreate(0,$strSafe(${expr.content}),1))`);
15094
15144
  }
15095
15145
  } else if (expr.op === "@") {
15096
- lines.push(`${parentVar}.push($c(0,$refFn($refAlt,${expr.content})))`);
15146
+ lines.push(`${parentVar}.push($vdomCreate(0,$refFn($refAlt,${expr.content})))`);
15097
15147
  } else if (expr.content) {
15098
15148
  lines.push(expr.content);
15099
15149
  }
@@ -15111,25 +15161,26 @@ function compileToVDomFunction(source, debug, file) {
15111
15161
  }
15112
15162
  const isVoid = VOID_ELEMENTS.has(tagName) && children.length === 0;
15113
15163
  const childrenArg = isVoid ? "1" : childVar;
15114
- lines.push(
15115
- `${parentVar}.push($c('${tagName}',${propsKey},${childrenArg}))`
15116
- );
15164
+ lines.push(`${parentVar}.push($vdomCreate('${tagName}',${propsKey},${childrenArg}))`);
15117
15165
  }
15118
15166
  for (const child of doc.children) {
15119
15167
  emitNode(child, rootVar);
15120
15168
  }
15121
- lines.push(`return $c($viewId,0,${rootVar})`);
15122
- const body = lines.join(";");
15169
+ lines.push(`return $vdomCreate($viewId,0,${rootVar})`);
15170
+ const varDeclStmts = [];
15171
+ for (let i = 1; i < varCounter; i++) varDeclStmts.push(`$v${i}`);
15172
+ const varDecl = varDeclStmts.length ? `let ${varDeclStmts.join(",")};` : "";
15173
+ const body = varDecl + lines.join(";");
15123
15174
  let funcBody = body;
15124
15175
  if (debug) {
15125
15176
  const filePart = file ? `\\r\\n\\tat file:${file}` : "";
15126
- funcBody = `let $dbgExpr,$dbgArt,$dbgLine;try{${body}}catch(ex){let msg='render view error:'+(ex.message||ex);msg+='${filePart}';throw msg;}`;
15177
+ funcBody = `let $dbgExpr,$dbgArt;try{${body}}catch(e){let msg='render error:'+(e.message||e);msg+='${filePart}';throw msg;}`;
15127
15178
  }
15128
15179
  const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
15129
15180
  funcBody = funcBody.replace(viewIdRegExp, `'+$viewId+'`);
15130
15181
  const refFallback = "if(!$refAlt)$refAlt=$data;";
15131
15182
  const fullSource = `${refFallback}let $splitter='\\x1e'{{VARS}};${funcBody}`;
15132
- return `($data,$viewId,$refAlt,$n,$refFn,$encUri,$encQuote)=>{${fullSource}}`;
15183
+ return `($data,$viewId,$refAlt,$strSafe,$refFn,$encUri,$encQuote)=>{${fullSource}}`;
15133
15184
  }
15134
15185
 
15135
15186
  // src/compiler/extract-global-vars.ts
@@ -15362,9 +15413,6 @@ var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
15362
15413
  // conversion, for error reporting. Only present in debug mode.
15363
15414
  // e.g. $dbgArt='{{=user.name}}'
15364
15415
  "$dbgArt",
15365
- // Debug: source line number — tracks the current line in the template
15366
- // source, for error reporting. Only present in debug mode.
15367
- "$dbgLine",
15368
15416
  // RefData alias — fallback reference lookup table.
15369
15417
  // Defaults to $data when no explicit $refAlt is provided.
15370
15418
  // Ensures $refFn() does not crash when @ operator is used without refData.
@@ -15448,19 +15496,14 @@ function compileToFunction(source, debug, file) {
15448
15496
  funcSource += source.substring(index, offset).replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
15449
15497
  index = offset + match.length;
15450
15498
  if (debug) {
15451
- let expr = source.substring(
15452
- index - match.length + 2 + (operate ? 1 : 0),
15453
- index - 2
15454
- );
15499
+ let expr = source.substring(index - match.length + 2 + (operate ? 1 : 0), index - 2);
15455
15500
  const x11 = String.fromCharCode(17);
15456
15501
  const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
15457
15502
  const artM = expr.match(artRegExp);
15458
15503
  let art = "";
15459
- let line = -1;
15460
15504
  if (artM) {
15461
15505
  expr = expr.replace(artRegExp, "");
15462
15506
  art = artM[2];
15463
- line = parseInt(artM[1], 10);
15464
15507
  } else {
15465
15508
  expr = expr.replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
15466
15509
  }
@@ -15475,8 +15518,8 @@ function compileToFunction(source, debug, file) {
15475
15518
  }
15476
15519
  funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
15477
15520
  } else if (content) {
15478
- if (line > -1) {
15479
- funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
15521
+ if (artM) {
15522
+ funcSource += `';$dbgArt='${art}';`;
15480
15523
  content = "";
15481
15524
  } else {
15482
15525
  funcSource += `';`;
@@ -15515,7 +15558,7 @@ function compileToFunction(source, debug, file) {
15515
15558
  funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
15516
15559
  if (debug) {
15517
15560
  const filePart = file ? `\\r\\n\\tat file:${file}` : "";
15518
- 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;}`;
15561
+ 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;}`;
15519
15562
  }
15520
15563
  const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
15521
15564
  funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
@@ -15535,28 +15578,30 @@ async function compileTemplate(source, options = {}) {
15535
15578
  if (virtualDom) {
15536
15579
  const funcBody2 = compileToVDomFunction(finalSource, debug, file);
15537
15580
  const funcWithVars2 = funcBody2.replace("{{VARS}}", () => varDeclarations);
15538
- return `import { vdomCreate as __larkC } from "@lark.js/mvc";
15581
+ return `import { vdomCreate as __larkVdomCreate } from "@lark.js/mvc";
15539
15582
  import { strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15540
- export default function(data, viewId, refData) {
15583
+ function __larkTemplate(data, viewId, refData) {
15541
15584
  let $data = data || {},
15542
15585
  $viewId = viewId || '',
15543
- $c = __larkC,
15544
- $n = __larkStrSafe;
15586
+ $vdomCreate = __larkVdomCreate,
15587
+ $strSafe = __larkStrSafe;
15545
15588
  return (${funcWithVars2})($data, $viewId, refData,
15546
- $n, __larkRefFn, __larkEncUri, __larkEncQuote
15589
+ $strSafe, __larkRefFn, __larkEncUri, __larkEncQuote
15547
15590
  );
15548
- }`;
15591
+ }
15592
+ export default __larkTemplate;`;
15549
15593
  }
15550
15594
  const funcBody = compileToFunction(finalSource, debug, file);
15551
15595
  const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
15552
15596
  return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
15553
- export default function(data, viewId, refData) {
15597
+ function __larkTemplate(data, viewId, refData) {
15554
15598
  let $data = data || {},
15555
15599
  $viewId = viewId || '';
15556
15600
  return (${funcWithVars})($data, $viewId, refData,
15557
15601
  __larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
15558
15602
  );
15559
- }`;
15603
+ }
15604
+ export default __larkTemplate;`;
15560
15605
  }
15561
15606
  export {
15562
15607
  compileTemplate,