@lark.js/mvc 0.0.3 → 0.0.5
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/README.md +872 -727
- package/dist/{chunk-Y72BUONO.js → chunk-IIIY575B.js} +108 -97
- package/dist/index.cjs +1718 -1115
- package/dist/index.d.cts +1857 -731
- package/dist/index.d.ts +1857 -731
- package/dist/index.js +1708 -1111
- package/dist/runtime.cjs +70 -0
- package/dist/runtime.d.cts +29 -0
- package/dist/runtime.d.ts +29 -0
- package/dist/runtime.js +41 -0
- package/dist/vite.cjs +108 -97
- package/dist/vite.d.cts +3 -3
- package/dist/vite.d.ts +3 -3
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +108 -97
- package/dist/webpack.js +1 -1
- package/package.json +21 -8
- package/src/client.d.ts +80 -0
package/dist/runtime.cjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/runtime.ts
|
|
21
|
+
var runtime_exports = {};
|
|
22
|
+
__export(runtime_exports, {
|
|
23
|
+
encHtml: () => encHtml,
|
|
24
|
+
encQuote: () => encQuote,
|
|
25
|
+
encUri: () => encUri,
|
|
26
|
+
refFn: () => refFn,
|
|
27
|
+
strSafe: () => strSafe
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(runtime_exports);
|
|
30
|
+
var HTML_ENT_MAP = {
|
|
31
|
+
"&": "amp",
|
|
32
|
+
"<": "lt",
|
|
33
|
+
">": "gt",
|
|
34
|
+
'"': "#34",
|
|
35
|
+
"'": "#39",
|
|
36
|
+
"`": "#96"
|
|
37
|
+
};
|
|
38
|
+
var HTML_ENT_REGEXP = /[&<>"`']/g;
|
|
39
|
+
var strSafe = (v) => "" + (v == null ? "" : v);
|
|
40
|
+
var encHtml = (v) => strSafe(v).replace(HTML_ENT_REGEXP, (m) => "&" + HTML_ENT_MAP[m] + ";");
|
|
41
|
+
var URI_ENT_MAP = {
|
|
42
|
+
"!": "%21",
|
|
43
|
+
"'": "%27",
|
|
44
|
+
"(": "%28",
|
|
45
|
+
")": "%29",
|
|
46
|
+
"*": "%2A"
|
|
47
|
+
};
|
|
48
|
+
var URI_ENT_REGEXP = /[!')(*]/g;
|
|
49
|
+
var encUri = (v) => encodeURIComponent(strSafe(v)).replace(URI_ENT_REGEXP, (m) => URI_ENT_MAP[m]);
|
|
50
|
+
var QUOTE_REGEXP = /['"\\]/g;
|
|
51
|
+
var encQuote = (v) => strSafe(v).replace(QUOTE_REGEXP, "\\$&");
|
|
52
|
+
var refFn = (ref, value, key) => {
|
|
53
|
+
const SPLITTER = "";
|
|
54
|
+
const counter = ref[SPLITTER];
|
|
55
|
+
for (let i = counter; --i; ) {
|
|
56
|
+
key = SPLITTER + i;
|
|
57
|
+
if (ref[key] === value) return key;
|
|
58
|
+
}
|
|
59
|
+
key = SPLITTER + ref[SPLITTER]++;
|
|
60
|
+
ref[key] = value;
|
|
61
|
+
return key;
|
|
62
|
+
};
|
|
63
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
64
|
+
0 && (module.exports = {
|
|
65
|
+
encHtml,
|
|
66
|
+
encQuote,
|
|
67
|
+
encUri,
|
|
68
|
+
refFn,
|
|
69
|
+
strSafe
|
|
70
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template runtime helpers.
|
|
3
|
+
*
|
|
4
|
+
* Compiled templates import these helpers from `@lark.js/mvc/runtime` instead
|
|
5
|
+
* of inlining the implementations. That keeps each compiled `.html` module
|
|
6
|
+
* small — no more ~400 bytes of duplicated helper code per template.
|
|
7
|
+
*
|
|
8
|
+
* The helpers below are aliased to `$strSafe / $encHtml / $encUri / $encQuote /
|
|
9
|
+
* $refFn` inside the IIFE that the compiler produces — see `compiler.ts`.
|
|
10
|
+
*/
|
|
11
|
+
/** Null-safe `String(value)` — `null`/`undefined` become `""`. */
|
|
12
|
+
declare const strSafe: (v: unknown) => string;
|
|
13
|
+
/** HTML-escape a value for safe embedding in markup. */
|
|
14
|
+
declare const encHtml: (v: unknown) => string;
|
|
15
|
+
/** Percent-encode a value, with extra characters escaped for stricter URIs. */
|
|
16
|
+
declare const encUri: (v: unknown) => string;
|
|
17
|
+
/** Backslash-escape quotes and backslashes for attribute string contents. */
|
|
18
|
+
declare const encQuote: (v: unknown) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Look up (or assign) a stable refData token for an object value.
|
|
21
|
+
*
|
|
22
|
+
* Templates use `{{@expr}}` to pass live JS values (objects/functions) through
|
|
23
|
+
* the DOM by writing the token into an attribute, then resolving it back to
|
|
24
|
+
* the original value when the event fires. `refData[SPLITTER]` holds the
|
|
25
|
+
* monotonic counter; `refData[SPLITTER + n]` holds the slot.
|
|
26
|
+
*/
|
|
27
|
+
declare const refFn: (ref: Record<string, unknown>, value: unknown, key: string) => string;
|
|
28
|
+
|
|
29
|
+
export { encHtml, encQuote, encUri, refFn, strSafe };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template runtime helpers.
|
|
3
|
+
*
|
|
4
|
+
* Compiled templates import these helpers from `@lark.js/mvc/runtime` instead
|
|
5
|
+
* of inlining the implementations. That keeps each compiled `.html` module
|
|
6
|
+
* small — no more ~400 bytes of duplicated helper code per template.
|
|
7
|
+
*
|
|
8
|
+
* The helpers below are aliased to `$strSafe / $encHtml / $encUri / $encQuote /
|
|
9
|
+
* $refFn` inside the IIFE that the compiler produces — see `compiler.ts`.
|
|
10
|
+
*/
|
|
11
|
+
/** Null-safe `String(value)` — `null`/`undefined` become `""`. */
|
|
12
|
+
declare const strSafe: (v: unknown) => string;
|
|
13
|
+
/** HTML-escape a value for safe embedding in markup. */
|
|
14
|
+
declare const encHtml: (v: unknown) => string;
|
|
15
|
+
/** Percent-encode a value, with extra characters escaped for stricter URIs. */
|
|
16
|
+
declare const encUri: (v: unknown) => string;
|
|
17
|
+
/** Backslash-escape quotes and backslashes for attribute string contents. */
|
|
18
|
+
declare const encQuote: (v: unknown) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Look up (or assign) a stable refData token for an object value.
|
|
21
|
+
*
|
|
22
|
+
* Templates use `{{@expr}}` to pass live JS values (objects/functions) through
|
|
23
|
+
* the DOM by writing the token into an attribute, then resolving it back to
|
|
24
|
+
* the original value when the event fires. `refData[SPLITTER]` holds the
|
|
25
|
+
* monotonic counter; `refData[SPLITTER + n]` holds the slot.
|
|
26
|
+
*/
|
|
27
|
+
declare const refFn: (ref: Record<string, unknown>, value: unknown, key: string) => string;
|
|
28
|
+
|
|
29
|
+
export { encHtml, encQuote, encUri, refFn, strSafe };
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/runtime.ts
|
|
2
|
+
var HTML_ENT_MAP = {
|
|
3
|
+
"&": "amp",
|
|
4
|
+
"<": "lt",
|
|
5
|
+
">": "gt",
|
|
6
|
+
'"': "#34",
|
|
7
|
+
"'": "#39",
|
|
8
|
+
"`": "#96"
|
|
9
|
+
};
|
|
10
|
+
var HTML_ENT_REGEXP = /[&<>"`']/g;
|
|
11
|
+
var strSafe = (v) => "" + (v == null ? "" : v);
|
|
12
|
+
var encHtml = (v) => strSafe(v).replace(HTML_ENT_REGEXP, (m) => "&" + HTML_ENT_MAP[m] + ";");
|
|
13
|
+
var URI_ENT_MAP = {
|
|
14
|
+
"!": "%21",
|
|
15
|
+
"'": "%27",
|
|
16
|
+
"(": "%28",
|
|
17
|
+
")": "%29",
|
|
18
|
+
"*": "%2A"
|
|
19
|
+
};
|
|
20
|
+
var URI_ENT_REGEXP = /[!')(*]/g;
|
|
21
|
+
var encUri = (v) => encodeURIComponent(strSafe(v)).replace(URI_ENT_REGEXP, (m) => URI_ENT_MAP[m]);
|
|
22
|
+
var QUOTE_REGEXP = /['"\\]/g;
|
|
23
|
+
var encQuote = (v) => strSafe(v).replace(QUOTE_REGEXP, "\\$&");
|
|
24
|
+
var refFn = (ref, value, key) => {
|
|
25
|
+
const SPLITTER = "";
|
|
26
|
+
const counter = ref[SPLITTER];
|
|
27
|
+
for (let i = counter; --i; ) {
|
|
28
|
+
key = SPLITTER + i;
|
|
29
|
+
if (ref[key] === value) return key;
|
|
30
|
+
}
|
|
31
|
+
key = SPLITTER + ref[SPLITTER]++;
|
|
32
|
+
ref[key] = value;
|
|
33
|
+
return key;
|
|
34
|
+
};
|
|
35
|
+
export {
|
|
36
|
+
encHtml,
|
|
37
|
+
encQuote,
|
|
38
|
+
encUri,
|
|
39
|
+
refFn,
|
|
40
|
+
strSafe
|
|
41
|
+
};
|
package/dist/vite.cjs
CHANGED
|
@@ -14737,7 +14737,7 @@ function convertArtSyntax(source, debug) {
|
|
|
14737
14737
|
}
|
|
14738
14738
|
if (blockStack.length > 0) {
|
|
14739
14739
|
const unclosed = blockStack.map((b) => `"${b.ctrl}" at line ${b.line}`).join(", ");
|
|
14740
|
-
throw new Error(`[@lark/mvc error] unclosed block(s): ${unclosed}`);
|
|
14740
|
+
throw new Error(`[@lark.js/mvc error] unclosed block(s): ${unclosed}`);
|
|
14741
14741
|
}
|
|
14742
14742
|
return result.join("");
|
|
14743
14743
|
}
|
|
@@ -14814,7 +14814,7 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
14814
14814
|
return `${debugPrefix}<%for(${forExpr}){%>`;
|
|
14815
14815
|
}
|
|
14816
14816
|
const tokens = code.split(/\s+/);
|
|
14817
|
-
const keyword = tokens.shift();
|
|
14817
|
+
const keyword = tokens.shift() ?? "";
|
|
14818
14818
|
switch (keyword) {
|
|
14819
14819
|
case "if": {
|
|
14820
14820
|
blockStack.push({ ctrl: "if", line: lineNo });
|
|
@@ -14831,12 +14831,12 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
14831
14831
|
}
|
|
14832
14832
|
return `${debugPrefix}<%}else{%>`;
|
|
14833
14833
|
}
|
|
14834
|
-
case "
|
|
14835
|
-
blockStack.push({ ctrl: "
|
|
14834
|
+
case "forOf": {
|
|
14835
|
+
blockStack.push({ ctrl: "forOf", line: lineNo });
|
|
14836
14836
|
const object = tokens[0];
|
|
14837
14837
|
if (tokens.length > 1 && tokens[1] !== "as") {
|
|
14838
14838
|
throw new Error(
|
|
14839
|
-
`[@lark/mvc error] bad
|
|
14839
|
+
`[@lark.js/mvc error] bad forOf syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forOf list as item [index]}}`
|
|
14840
14840
|
);
|
|
14841
14841
|
}
|
|
14842
14842
|
const restTokens = tokens.slice(2);
|
|
@@ -14858,12 +14858,12 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
14858
14858
|
}
|
|
14859
14859
|
return `${debugPrefix}<%for(let ${index}=0${refExpr},${refObjCount}=${refObj}.length${lastCount};${index}<${refObjCount};${index}++){${firstAndLast}${valueDecl}%>`;
|
|
14860
14860
|
}
|
|
14861
|
-
case "
|
|
14862
|
-
blockStack.push({ ctrl: "
|
|
14861
|
+
case "forIn": {
|
|
14862
|
+
blockStack.push({ ctrl: "forIn", line: lineNo });
|
|
14863
14863
|
const object = tokens[0];
|
|
14864
14864
|
if (tokens.length > 1 && tokens[1] !== "as") {
|
|
14865
14865
|
throw new Error(
|
|
14866
|
-
`[@lark/mvc error] bad
|
|
14866
|
+
`[@lark.js/mvc error] bad forIn syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{for-in obj as val [key]}}`
|
|
14867
14867
|
);
|
|
14868
14868
|
}
|
|
14869
14869
|
const restTokens2 = tokens.slice(2);
|
|
@@ -14883,19 +14883,19 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
14883
14883
|
case "set":
|
|
14884
14884
|
return `${debugPrefix}<%let ${tokens.join(" ")};%>`;
|
|
14885
14885
|
case "/if":
|
|
14886
|
-
case "/
|
|
14887
|
-
case "/
|
|
14886
|
+
case "/forOf":
|
|
14887
|
+
case "/forIn":
|
|
14888
14888
|
case "/for": {
|
|
14889
14889
|
const expectedCtrl = keyword.substring(1);
|
|
14890
14890
|
const last = blockStack.pop();
|
|
14891
14891
|
if (!last) {
|
|
14892
14892
|
throw new Error(
|
|
14893
|
-
`[@lark/mvc error] unexpected {{${code}}}: no matching open block`
|
|
14893
|
+
`[@lark.js/mvc error] unexpected {{${code}}}: no matching open block`
|
|
14894
14894
|
);
|
|
14895
14895
|
}
|
|
14896
14896
|
if (last.ctrl !== expectedCtrl) {
|
|
14897
14897
|
throw new Error(
|
|
14898
|
-
`[@lark/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
|
|
14898
|
+
`[@lark.js/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
|
|
14899
14899
|
);
|
|
14900
14900
|
}
|
|
14901
14901
|
return `${debugPrefix}<%}%>`;
|
|
@@ -14959,7 +14959,7 @@ function parseAsExpr(expr) {
|
|
|
14959
14959
|
function compileToFunction(source, debug, file) {
|
|
14960
14960
|
const matcher = /<%([@=!:])?([\s\S]*?)%>|$/g;
|
|
14961
14961
|
let index = 0;
|
|
14962
|
-
let funcSource = `$
|
|
14962
|
+
let funcSource = `$out+='`;
|
|
14963
14963
|
let hasAtRule = false;
|
|
14964
14964
|
const escapeSlashRegExp = /\\|'/g;
|
|
14965
14965
|
const escapeBreakReturnRegExp = /\r|\n/g;
|
|
@@ -14985,17 +14985,17 @@ function compileToFunction(source, debug, file) {
|
|
|
14985
14985
|
}
|
|
14986
14986
|
if (operate === "@") {
|
|
14987
14987
|
hasAtRule = true;
|
|
14988
|
-
funcSource += `'+($
|
|
14988
|
+
funcSource += `'+($dbgExpr='<%${operate + expr}%>',$refFn($refAlt,${content}))+'`;
|
|
14989
14989
|
} else if (operate === "=" || operate === ":") {
|
|
14990
|
-
funcSource += `'+($
|
|
14990
|
+
funcSource += `'+($dbgExpr='<%${operate + expr}%>',$encHtml(${content}))+'`;
|
|
14991
14991
|
} else if (operate === "!") {
|
|
14992
|
-
if (!content.startsWith("$
|
|
14993
|
-
content = `$
|
|
14992
|
+
if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
|
|
14993
|
+
content = `$strSafe(${content})`;
|
|
14994
14994
|
}
|
|
14995
|
-
funcSource += `'+($
|
|
14995
|
+
funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
|
|
14996
14996
|
} else if (content) {
|
|
14997
14997
|
if (line > -1) {
|
|
14998
|
-
funcSource += `';$
|
|
14998
|
+
funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
|
|
14999
14999
|
content = "";
|
|
15000
15000
|
} else {
|
|
15001
15001
|
funcSource += `';`;
|
|
@@ -15004,19 +15004,19 @@ function compileToFunction(source, debug, file) {
|
|
|
15004
15004
|
funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
|
|
15005
15005
|
}
|
|
15006
15006
|
if (expr) {
|
|
15007
|
-
funcSource += `$
|
|
15007
|
+
funcSource += `$dbgExpr='<%${expr}%>';`;
|
|
15008
15008
|
}
|
|
15009
|
-
funcSource += content + `;$
|
|
15009
|
+
funcSource += content + `;$out+='`;
|
|
15010
15010
|
}
|
|
15011
15011
|
} else {
|
|
15012
15012
|
if (operate === "@") {
|
|
15013
15013
|
hasAtRule = true;
|
|
15014
|
-
funcSource += `'+$
|
|
15014
|
+
funcSource += `'+$refFn($refAlt,${content})+'`;
|
|
15015
15015
|
} else if (operate === "=" || operate === ":") {
|
|
15016
|
-
funcSource += `'+$
|
|
15016
|
+
funcSource += `'+$encHtml(${content})+'`;
|
|
15017
15017
|
} else if (operate === "!") {
|
|
15018
|
-
if (!content.startsWith("$
|
|
15019
|
-
content = `$
|
|
15018
|
+
if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
|
|
15019
|
+
content = `$strSafe(${content})`;
|
|
15020
15020
|
}
|
|
15021
15021
|
funcSource += `'+${content}+'`;
|
|
15022
15022
|
} else if (content) {
|
|
@@ -15024,28 +15024,24 @@ function compileToFunction(source, debug, file) {
|
|
|
15024
15024
|
if (funcSource.endsWith(`+'';`)) {
|
|
15025
15025
|
funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
|
|
15026
15026
|
}
|
|
15027
|
-
funcSource += `${content};$
|
|
15027
|
+
funcSource += `${content};$out+='`;
|
|
15028
15028
|
}
|
|
15029
15029
|
}
|
|
15030
15030
|
return match;
|
|
15031
15031
|
});
|
|
15032
15032
|
funcSource += `';`;
|
|
15033
|
-
funcSource = funcSource.replace(/\$
|
|
15034
|
-
funcSource = funcSource.replace(/\$
|
|
15033
|
+
funcSource = funcSource.replace(/\$out\+='';/g, "");
|
|
15034
|
+
funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
|
|
15035
15035
|
if (debug) {
|
|
15036
15036
|
const filePart = file ? `\\r\\n\\tat file:${file}` : "";
|
|
15037
|
-
funcSource = `let $
|
|
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;}`;
|
|
15038
15038
|
}
|
|
15039
15039
|
const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
|
|
15040
15040
|
funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
|
|
15041
|
-
|
|
15042
|
-
const
|
|
15043
|
-
const
|
|
15044
|
-
|
|
15045
|
-
const refFallback = "if(!$$ref)$$ref=$$;";
|
|
15046
|
-
const fns = `${refFallback}${encode}${encodeURIMore}${encodeQuote}${atRule};`;
|
|
15047
|
-
const fullSource = `${fns}let $g='\\x1e',$_temp,$p=''{{VARS}};${funcSource}return $p`;
|
|
15048
|
-
return `($$,$viewId,$$ref,$e,$n,$eu,$i,$eq)=>{${fullSource}}`;
|
|
15041
|
+
void hasAtRule;
|
|
15042
|
+
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}}`;
|
|
15049
15045
|
}
|
|
15050
15046
|
function compileTemplate(source, options = {}) {
|
|
15051
15047
|
const { debug = false, globalVars = [], file } = options;
|
|
@@ -15054,17 +15050,14 @@ function compileTemplate(source, options = {}) {
|
|
|
15054
15050
|
const viewEventProcessed = processViewEvents(converted);
|
|
15055
15051
|
const finalSource = restoreComments(viewEventProcessed, comments);
|
|
15056
15052
|
const funcBody = compileToFunction(finalSource, debug, file);
|
|
15057
|
-
const varDeclarations = globalVars.map((key) => `,${key}
|
|
15053
|
+
const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
|
|
15058
15054
|
const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
|
|
15059
|
-
return `
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
/* $eu */ null,
|
|
15066
|
-
/* $i */ null,
|
|
15067
|
-
/* $eq */ null
|
|
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
|
|
15068
15061
|
);
|
|
15069
15062
|
}`;
|
|
15070
15063
|
}
|
|
@@ -15173,7 +15166,7 @@ function fallbackExtractVariables(source) {
|
|
|
15173
15166
|
while ((m = outputRegExp.exec(source)) !== null) {
|
|
15174
15167
|
vars.add(m[1]);
|
|
15175
15168
|
}
|
|
15176
|
-
const eachRegExp = /\{\{
|
|
15169
|
+
const eachRegExp = /\{\{forOf\s+([a-zA-Z_$][\w$]*)\s+as/g;
|
|
15177
15170
|
while ((m = eachRegExp.exec(source)) !== null) {
|
|
15178
15171
|
vars.add(m[1]);
|
|
15179
15172
|
}
|
|
@@ -15189,82 +15182,100 @@ function walkAst(ast, visitors) {
|
|
|
15189
15182
|
if (visitors[type]) {
|
|
15190
15183
|
visitors[type](node);
|
|
15191
15184
|
}
|
|
15185
|
+
const bag = node;
|
|
15192
15186
|
for (const key of Object.keys(node)) {
|
|
15193
15187
|
if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
|
|
15194
15188
|
continue;
|
|
15195
|
-
if (type === "MemberExpression" && key === "property"
|
|
15196
|
-
|
|
15197
|
-
|
|
15198
|
-
continue;
|
|
15189
|
+
if (type === "MemberExpression" && key === "property") {
|
|
15190
|
+
const me = node;
|
|
15191
|
+
if (!me.computed) continue;
|
|
15199
15192
|
}
|
|
15200
|
-
if (type === "
|
|
15201
|
-
|
|
15193
|
+
if (type === "ObjectProperty" && key === "key") {
|
|
15194
|
+
const op = node;
|
|
15195
|
+
if (!op.computed) continue;
|
|
15202
15196
|
}
|
|
15203
|
-
|
|
15197
|
+
if (type === "ObjectMethod" && key === "key") {
|
|
15198
|
+
const om = node;
|
|
15199
|
+
if (!om.computed) continue;
|
|
15200
|
+
}
|
|
15201
|
+
const child = bag[key];
|
|
15204
15202
|
if (Array.isArray(child)) {
|
|
15205
15203
|
for (const item of child) {
|
|
15206
|
-
if (item
|
|
15207
|
-
visit(item);
|
|
15208
|
-
}
|
|
15204
|
+
if (isAstNode(item)) visit(item);
|
|
15209
15205
|
}
|
|
15210
|
-
} else if (child
|
|
15206
|
+
} else if (isAstNode(child)) {
|
|
15211
15207
|
visit(child);
|
|
15212
15208
|
}
|
|
15213
15209
|
}
|
|
15214
15210
|
}
|
|
15215
15211
|
visit(ast);
|
|
15216
15212
|
}
|
|
15213
|
+
function isAstNode(v) {
|
|
15214
|
+
return !!v && typeof v === "object" && typeof v.type === "string";
|
|
15215
|
+
}
|
|
15217
15216
|
var BUILTIN_GLOBALS = {
|
|
15218
15217
|
// ─── Template runtime helpers (injected by compileToFunction) ───────
|
|
15219
15218
|
//
|
|
15220
15219
|
// These variables appear in the generated template function signature
|
|
15221
15220
|
// or body. They must be excluded from extractGlobalVars() so that
|
|
15222
|
-
// they are not mistaken for user data variables and destructured from
|
|
15221
|
+
// they are not mistaken for user data variables and destructured from $data.
|
|
15223
15222
|
// SPLITTER character constant (same as \x1e), used as namespace separator
|
|
15224
15223
|
// for refData keys, event attribute encoding, and internal data structures.
|
|
15225
|
-
// Declared as: let $
|
|
15226
|
-
$
|
|
15227
|
-
//
|
|
15228
|
-
// User variables are destructured from
|
|
15229
|
-
// let {name, age} =
|
|
15224
|
+
// Declared as: let $splitter='\x1e'
|
|
15225
|
+
$splitter: 1,
|
|
15226
|
+
// Data — the data object passed from Updater to the template function.
|
|
15227
|
+
// User variables are destructured from $data at the top of the function:
|
|
15228
|
+
// let {name, age} = $data;
|
|
15230
15229
|
// This is the first parameter of the generated arrow function.
|
|
15231
|
-
|
|
15230
|
+
$data: 1,
|
|
15232
15231
|
// Null-safe toString: v => '' + (v == null ? '' : v)
|
|
15233
15232
|
// Converts null/undefined to empty string, otherwise calls toString().
|
|
15234
15233
|
// Wraps every {{!raw}} output to prevent "null" / "undefined" rendering.
|
|
15235
|
-
$
|
|
15236
|
-
// HTML entity encoder: v => $
|
|
15234
|
+
$strSafe: 1,
|
|
15235
|
+
// HTML entity encoder: v => $strSafe(v).replace(/[&<>"'`]/g, entityMap)
|
|
15237
15236
|
// Encodes &, <, >, ", ', ` to HTML entities (& < etc.)
|
|
15238
15237
|
// Applied to all {{=escaped}} and {{:binding}} outputs.
|
|
15239
|
-
$
|
|
15240
|
-
// HTML entity map — internal object used by $
|
|
15238
|
+
$encHtml: 1,
|
|
15239
|
+
// HTML entity map — internal object used by $encHtml:
|
|
15241
15240
|
// {'&':'amp','<':'gt','>':'gt','"':'#34','\'':'#39','`':'#96'}
|
|
15242
|
-
// Not a standalone function; referenced inside $
|
|
15243
|
-
$
|
|
15244
|
-
// HTML entity RegExp — internal regexp used by $
|
|
15241
|
+
// Not a standalone function; referenced inside $encHtml's closure.
|
|
15242
|
+
$entMap: 1,
|
|
15243
|
+
// HTML entity RegExp — internal regexp used by $encHtml:
|
|
15245
15244
|
// /[&<>"'`]/g
|
|
15246
|
-
$
|
|
15247
|
-
// HTML entity replacer function — internal helper used by $
|
|
15248
|
-
// m => '&' + $
|
|
15249
|
-
// Maps
|
|
15250
|
-
$
|
|
15245
|
+
$entReg: 1,
|
|
15246
|
+
// HTML entity replacer function — internal helper used by $encHtml:
|
|
15247
|
+
// m => '&' + $entMap[m] + ';'
|
|
15248
|
+
// Maps matched character to its entity string.
|
|
15249
|
+
$entFn: 1,
|
|
15251
15250
|
// Output buffer — the string accumulator for rendered HTML.
|
|
15252
|
-
// All template output is appended via $
|
|
15253
|
-
// Declared as: let $
|
|
15254
|
-
$
|
|
15251
|
+
// All template output is appended via $out += '...'.
|
|
15252
|
+
// Declared as: let $out = ''
|
|
15253
|
+
$out: 1,
|
|
15255
15254
|
// Reference lookup: (refData, value) => key
|
|
15256
15255
|
// Finds or allocates a SPLITTER-prefixed key in refData for a given
|
|
15257
15256
|
// object reference. Used by {{@ref}} operator for passing object
|
|
15258
15257
|
// references to child views via v-lark attributes.
|
|
15259
|
-
$
|
|
15260
|
-
// URI encoder: v => encodeURIComponent($
|
|
15258
|
+
$refFn: 1,
|
|
15259
|
+
// URI encoder: v => encodeURIComponent($strSafe(v)).replace(/[!')(*]/g, extraMap)
|
|
15261
15260
|
// Extends encodeURIComponent with encoding of ! ' ( ) *.
|
|
15262
15261
|
// Applied to values in @event URL parameters and {{!uri}} contexts.
|
|
15263
|
-
$
|
|
15264
|
-
//
|
|
15262
|
+
$encUri: 1,
|
|
15263
|
+
// URI encode map — internal object used by $encUri:
|
|
15264
|
+
// {'!':'%21','\'':'%27','(':'%28',')':'%29','*':'%2A'}
|
|
15265
|
+
$uriMap: 1,
|
|
15266
|
+
// URI encode replacer — internal helper used by $encUri:
|
|
15267
|
+
// m => $uriMap[m]
|
|
15268
|
+
$uriFn: 1,
|
|
15269
|
+
// URI encode regexp — internal regexp used by $encUri:
|
|
15270
|
+
// /[!')(*]/g
|
|
15271
|
+
$uriReg: 1,
|
|
15272
|
+
// Quote encoder: v => $strSafe(v).replace(/['"\\]/g, '\\$&')
|
|
15265
15273
|
// Escapes quotes and backslashes for safe embedding in HTML attribute
|
|
15266
15274
|
// values (e.g. data-json='...').
|
|
15267
|
-
$
|
|
15275
|
+
$encQuote: 1,
|
|
15276
|
+
// Quote encode regexp — internal regexp used by $encQuote:
|
|
15277
|
+
// /['"\\]/g
|
|
15278
|
+
$qReg: 1,
|
|
15268
15279
|
// View ID — the unique identifier of the owning View instance.
|
|
15269
15280
|
// Injected into @event attribute values at render time so that
|
|
15270
15281
|
// EventDelegator can dispatch events to the correct View handler.
|
|
@@ -15272,23 +15283,23 @@ var BUILTIN_GLOBALS = {
|
|
|
15272
15283
|
$viewId: 1,
|
|
15273
15284
|
// Debug: current expression text — stores the template expression being
|
|
15274
15285
|
// evaluated, for error reporting. Only present in debug mode.
|
|
15275
|
-
// e.g. $
|
|
15276
|
-
$
|
|
15286
|
+
// e.g. $dbgExpr='<%=user.name%>'
|
|
15287
|
+
$dbgExpr: 1,
|
|
15277
15288
|
// Debug: original art syntax — stores the {{}} template syntax before
|
|
15278
15289
|
// conversion, for error reporting. Only present in debug mode.
|
|
15279
|
-
// e.g. $
|
|
15280
|
-
$
|
|
15290
|
+
// e.g. $dbgArt='{{=user.name}}'
|
|
15291
|
+
$dbgArt: 1,
|
|
15281
15292
|
// Debug: source line number — tracks the current line in the template
|
|
15282
15293
|
// source, for error reporting. Only present in debug mode.
|
|
15283
|
-
$
|
|
15284
|
-
//
|
|
15285
|
-
// Defaults to
|
|
15286
|
-
// Ensures $
|
|
15287
|
-
|
|
15294
|
+
$dbgLine: 1,
|
|
15295
|
+
// RefData alias — fallback reference lookup table.
|
|
15296
|
+
// Defaults to $data when no explicit $refAlt is provided.
|
|
15297
|
+
// Ensures $refFn() does not crash when @ operator is used without refData.
|
|
15298
|
+
$refAlt: 1,
|
|
15288
15299
|
// Temporary variable — used by the compiler for intermediate
|
|
15289
15300
|
// expression results in generated code (e.g. loop variables,
|
|
15290
|
-
// conditional branches). Declared as: let $
|
|
15291
|
-
$
|
|
15301
|
+
// conditional branches). Declared as: let $tmp
|
|
15302
|
+
$tmp: 1,
|
|
15292
15303
|
// JS literals
|
|
15293
15304
|
undefined: 1,
|
|
15294
15305
|
null: 1,
|
package/dist/vite.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @lark/
|
|
4
|
+
* @lark.js/mvc Vite Plugin for Template Compilation
|
|
5
5
|
*
|
|
6
|
-
* Compiles .html template files using @lark/
|
|
6
|
+
* Compiles .html template files using @lark.js/mvc template syntax
|
|
7
7
|
* into JS function modules at build/dev time.
|
|
8
8
|
*
|
|
9
9
|
* 0 configuration — just add the plugin and it works.
|
|
@@ -16,7 +16,7 @@ import { Plugin } from 'vite';
|
|
|
16
16
|
*
|
|
17
17
|
* Usage in vite.config.ts:
|
|
18
18
|
* ```ts
|
|
19
|
-
* import { larkMvcPlugin } from '@lark/
|
|
19
|
+
* import { larkMvcPlugin } from '@lark.js/mvc/vite';
|
|
20
20
|
*
|
|
21
21
|
* export default defineConfig({
|
|
22
22
|
* plugins: [larkMvcPlugin()],
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @lark/
|
|
4
|
+
* @lark.js/mvc Vite Plugin for Template Compilation
|
|
5
5
|
*
|
|
6
|
-
* Compiles .html template files using @lark/
|
|
6
|
+
* Compiles .html template files using @lark.js/mvc template syntax
|
|
7
7
|
* into JS function modules at build/dev time.
|
|
8
8
|
*
|
|
9
9
|
* 0 configuration — just add the plugin and it works.
|
|
@@ -16,7 +16,7 @@ import { Plugin } from 'vite';
|
|
|
16
16
|
*
|
|
17
17
|
* Usage in vite.config.ts:
|
|
18
18
|
* ```ts
|
|
19
|
-
* import { larkMvcPlugin } from '@lark/
|
|
19
|
+
* import { larkMvcPlugin } from '@lark.js/mvc/vite';
|
|
20
20
|
*
|
|
21
21
|
* export default defineConfig({
|
|
22
22
|
* plugins: [larkMvcPlugin()],
|