@lark.js/mvc 0.0.12 → 0.0.14
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 +11 -20
- package/dist/compiler.cjs +18 -345
- package/dist/compiler.d.cts +1 -30
- package/dist/compiler.d.ts +1 -30
- package/dist/compiler.js +17 -343
- package/dist/devtool.cjs +38 -84
- package/dist/devtool.js +38 -84
- package/dist/index.cjs +45 -145
- package/dist/index.d.cts +5 -41
- package/dist/index.d.ts +5 -41
- package/dist/index.js +45 -144
- package/dist/rspack.cjs +23 -351
- package/dist/rspack.d.cts +9 -24
- package/dist/rspack.d.ts +9 -24
- package/dist/rspack.js +23 -351
- package/dist/vite.cjs +55 -365
- package/dist/vite.d.cts +17 -8
- package/dist/vite.d.ts +17 -8
- package/dist/vite.js +52 -364
- package/dist/webpack.cjs +23 -351
- package/dist/webpack.d.cts +9 -15
- package/dist/webpack.d.ts +9 -15
- package/dist/webpack.js +23 -351
- package/package.json +7 -5
- package/src/client.d.ts +0 -89
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ Third, zero runtime dependencies. `@babel/parser` / `@babel/types` are used only
|
|
|
41
41
|
|
|
42
42
|
Fourth, real DOM diff. Templates compile to functions that produce HTML strings, which are parsed into temporary DOM via `document.implementation.createHTMLDocument` and then diffed against the live DOM using keyed comparison. The advantage is that context-sensitive tags like `<table>` / `<select>` / `<svg>` are handled by the native parser. The trade-off is that large templates incur parse overhead, and SSR is not supported.
|
|
43
43
|
|
|
44
|
-
Fifth, debug-friendly. `
|
|
44
|
+
Fifth, debug-friendly. `installFrameDevtoolBridge` exposes the Frame tree to Devtool via `postMessage`. A set of `window.__lark_*` global shortcuts cover Framework / State / Router / Frame / View and HMR helpers.
|
|
45
45
|
|
|
46
46
|
Not suitable for: projects requiring SSR/streaming rendering, cross-platform needs like React Native, or projects needing off-the-shelf Chrome extension panels. For those, consider the React or Vue ecosystems.
|
|
47
47
|
|
|
@@ -735,7 +735,6 @@ Marking large static subtrees with `ldk` can completely skip rendering work. Thi
|
|
|
735
735
|
| `Frame.getAll()` | All Frames as `Map<string, Frame>` |
|
|
736
736
|
| `Frame.getRoot()` | Current root Frame; returns `undefined` if not created |
|
|
737
737
|
| `Frame.createRoot(id)` | Idempotent root creation (`Framework.boot` calls this) |
|
|
738
|
-
| `Frame.root(id)` | `@deprecated` alias, forwards to `createRoot` |
|
|
739
738
|
| `new Frame(containerId)` | Independent Frame instance for micro-frontend / embedded widget scenarios |
|
|
740
739
|
| `frame.invoke(name, args?)` | Call the owning view's method; if view not mounted, pushes to `invokeList`, flushed by `View.runInvokes(frame)` after mounting |
|
|
741
740
|
| `frame.children()` | Child Frame id array (order not guaranteed) |
|
|
@@ -838,24 +837,16 @@ new ModuleFederationPlugin({
|
|
|
838
837
|
|
|
839
838
|
After `Framework.boot` completes, the following are attached to `window`:
|
|
840
839
|
|
|
841
|
-
| Global | Value
|
|
842
|
-
| ------------------------------------ |
|
|
843
|
-
| `window.__lark_Framework` | Framework object
|
|
844
|
-
| `window.__lark_State` | State object
|
|
845
|
-
| `window.__lark_Router` | Router object
|
|
846
|
-
| `window.__lark_Frame` | Frame class
|
|
847
|
-
| `window.__lark_View` | View class
|
|
848
|
-
| `window.__lark_registerViewClass` | Function
|
|
849
|
-
| `window.__lark_invalidateViewClass` | Function
|
|
850
|
-
| `window.__lark_getViewClassRegistry` | Function
|
|
851
|
-
| `window.__lark_Debug` | boolean, must be set manually | Enable Safeguard Proxy debug checks |
|
|
852
|
-
|
|
853
|
-
### Safeguard Debug Mode
|
|
854
|
-
|
|
855
|
-
Set `window.__lark_Debug = true` before boot, and the framework wraps `State.get()` / `Router.diff()` results and `Updater.get()` return values with Safeguard Proxy:
|
|
856
|
-
|
|
857
|
-
- Warns when reading data written by another page (potential cross-page pollution).
|
|
858
|
-
- Warns immediately when assigning directly to objects returned by `State.get()` (deduplicated by key); the correct approach is `State.set(patch)` + `State.digest()`.
|
|
840
|
+
| Global | Value | Purpose |
|
|
841
|
+
| ------------------------------------ | ---------------- | ------------------------------ |
|
|
842
|
+
| `window.__lark_Framework` | Framework object | Direct access |
|
|
843
|
+
| `window.__lark_State` | State object | Direct access |
|
|
844
|
+
| `window.__lark_Router` | Router object | Direct access |
|
|
845
|
+
| `window.__lark_Frame` | Frame class | Direct access |
|
|
846
|
+
| `window.__lark_View` | View class | Direct access |
|
|
847
|
+
| `window.__lark_registerViewClass` | Function | HMR: re-register View class |
|
|
848
|
+
| `window.__lark_invalidateViewClass` | Function | HMR: remove View from registry |
|
|
849
|
+
| `window.__lark_getViewClassRegistry` | Function | HMR: read registry |
|
|
859
850
|
|
|
860
851
|
### Frame Devtool Bridge
|
|
861
852
|
|
package/dist/compiler.cjs
CHANGED
|
@@ -14518,7 +14518,7 @@ var require_lib = __commonJS({
|
|
|
14518
14518
|
options = Object.assign({}, options);
|
|
14519
14519
|
try {
|
|
14520
14520
|
options.sourceType = "module";
|
|
14521
|
-
const parser =
|
|
14521
|
+
const parser = getParser(options, input);
|
|
14522
14522
|
const ast = parser.parse();
|
|
14523
14523
|
if (parser.sawUnambiguousESM) {
|
|
14524
14524
|
return ast;
|
|
@@ -14526,7 +14526,7 @@ var require_lib = __commonJS({
|
|
|
14526
14526
|
if (parser.ambiguousScriptDifferentAst) {
|
|
14527
14527
|
try {
|
|
14528
14528
|
options.sourceType = "script";
|
|
14529
|
-
return
|
|
14529
|
+
return getParser(options, input).parse();
|
|
14530
14530
|
} catch (_unused) {
|
|
14531
14531
|
}
|
|
14532
14532
|
} else {
|
|
@@ -14536,17 +14536,17 @@ var require_lib = __commonJS({
|
|
|
14536
14536
|
} catch (moduleError) {
|
|
14537
14537
|
try {
|
|
14538
14538
|
options.sourceType = "script";
|
|
14539
|
-
return
|
|
14539
|
+
return getParser(options, input).parse();
|
|
14540
14540
|
} catch (_unused2) {
|
|
14541
14541
|
}
|
|
14542
14542
|
throw moduleError;
|
|
14543
14543
|
}
|
|
14544
14544
|
} else {
|
|
14545
|
-
return
|
|
14545
|
+
return getParser(options, input).parse();
|
|
14546
14546
|
}
|
|
14547
14547
|
}
|
|
14548
14548
|
function parseExpression(input, options) {
|
|
14549
|
-
const parser =
|
|
14549
|
+
const parser = getParser(options, input);
|
|
14550
14550
|
if (parser.options.strictMode) {
|
|
14551
14551
|
parser.state.strict = true;
|
|
14552
14552
|
}
|
|
@@ -14560,7 +14560,7 @@ var require_lib = __commonJS({
|
|
|
14560
14560
|
return tokenTypes2;
|
|
14561
14561
|
}
|
|
14562
14562
|
var tokTypes = generateExportedTokenTypes(tt);
|
|
14563
|
-
function
|
|
14563
|
+
function getParser(options, input) {
|
|
14564
14564
|
let cls = Parser;
|
|
14565
14565
|
const pluginsMap = /* @__PURE__ */ new Map();
|
|
14566
14566
|
if (options != null && options.plugins) {
|
|
@@ -14609,8 +14609,7 @@ var require_lib = __commonJS({
|
|
|
14609
14609
|
var compiler_exports = {};
|
|
14610
14610
|
__export(compiler_exports, {
|
|
14611
14611
|
compileTemplate: () => compileTemplate,
|
|
14612
|
-
extractGlobalVars: () =>
|
|
14613
|
-
extractGlobalVarsSwc: () => extractGlobalVars
|
|
14612
|
+
extractGlobalVars: () => extractGlobalVars
|
|
14614
14613
|
});
|
|
14615
14614
|
module.exports = __toCommonJS(compiler_exports);
|
|
14616
14615
|
|
|
@@ -15147,334 +15146,9 @@ function compileToVDomFunction(source, debug, file) {
|
|
|
15147
15146
|
return `($data,$viewId,$refAlt,$n,$refFn,$encUri,$encQuote)=>{${fullSource}}`;
|
|
15148
15147
|
}
|
|
15149
15148
|
|
|
15150
|
-
// src/compiler/swc/extract-global-vars.ts
|
|
15151
|
-
var parseSyncFn = null;
|
|
15152
|
-
var parseSyncLoadAttempted = false;
|
|
15153
|
-
async function getParser() {
|
|
15154
|
-
if (!parseSyncLoadAttempted) {
|
|
15155
|
-
parseSyncLoadAttempted = true;
|
|
15156
|
-
try {
|
|
15157
|
-
const swc = await import("@swc/core");
|
|
15158
|
-
parseSyncFn = swc.parseSync;
|
|
15159
|
-
} catch (err) {
|
|
15160
|
-
console.error("failed to load @swc/core", err);
|
|
15161
|
-
}
|
|
15162
|
-
}
|
|
15163
|
-
return parseSyncFn;
|
|
15164
|
-
}
|
|
15165
|
-
async function extractGlobalVars(source) {
|
|
15166
|
-
const { protectedSource, comments: _comments } = protectComments(source);
|
|
15167
|
-
const viewEventProcessed = processViewEvents(protectedSource);
|
|
15168
|
-
const converted = convertArtSyntax(viewEventProcessed, false);
|
|
15169
|
-
const template = restoreComments(converted, _comments);
|
|
15170
|
-
const templateCmdRegExp = /<%([@=!:])?([\s\S]*?)%>|$/g;
|
|
15171
|
-
const fnParts = [];
|
|
15172
|
-
const htmlStore = {};
|
|
15173
|
-
let htmlIndex = 0;
|
|
15174
|
-
let lastIndex = 0;
|
|
15175
|
-
const htmlKey = String.fromCharCode(5);
|
|
15176
|
-
template.replace(
|
|
15177
|
-
templateCmdRegExp,
|
|
15178
|
-
(match, operate, content, offset) => {
|
|
15179
|
-
const start = operate ? 3 : 2;
|
|
15180
|
-
const htmlText = template.substring(lastIndex, offset + start);
|
|
15181
|
-
const key = htmlKey + htmlIndex++ + htmlKey;
|
|
15182
|
-
htmlStore[key] = htmlText;
|
|
15183
|
-
lastIndex = offset + match.length - 2;
|
|
15184
|
-
if (operate && content.trim()) {
|
|
15185
|
-
fnParts.push(';"' + key + '";', "[" + content + "]");
|
|
15186
|
-
} else {
|
|
15187
|
-
fnParts.push(';"' + key + '";', content || "");
|
|
15188
|
-
}
|
|
15189
|
-
return match;
|
|
15190
|
-
}
|
|
15191
|
-
);
|
|
15192
|
-
let fn = fnParts.join("");
|
|
15193
|
-
fn = `(function(){${fn}})`;
|
|
15194
|
-
const parseSync = await getParser();
|
|
15195
|
-
if (!parseSync) {
|
|
15196
|
-
return fallbackExtractVariables(source);
|
|
15197
|
-
}
|
|
15198
|
-
let ast;
|
|
15199
|
-
try {
|
|
15200
|
-
ast = parseSync(fn, {
|
|
15201
|
-
syntax: "ecmascript",
|
|
15202
|
-
target: "es2022"
|
|
15203
|
-
});
|
|
15204
|
-
} catch {
|
|
15205
|
-
return fallbackExtractVariables(source);
|
|
15206
|
-
}
|
|
15207
|
-
const globalExists = {};
|
|
15208
|
-
for (const name of BUILTIN_GLOBALS) globalExists[name] = 1;
|
|
15209
|
-
const globalVars = /* @__PURE__ */ Object.create(null);
|
|
15210
|
-
const fnNodes = [];
|
|
15211
|
-
walkSwcAst(ast, {
|
|
15212
|
-
VariableDeclarator(node) {
|
|
15213
|
-
if (node.id.type === "Identifier") {
|
|
15214
|
-
const name = node.id.value;
|
|
15215
|
-
globalExists[name] = node.init ? 3 : 2;
|
|
15216
|
-
}
|
|
15217
|
-
},
|
|
15218
|
-
FunctionDeclaration(node) {
|
|
15219
|
-
if (node.identifier) {
|
|
15220
|
-
globalExists[node.identifier.value] = 3;
|
|
15221
|
-
}
|
|
15222
|
-
fnNodes.push(node);
|
|
15223
|
-
},
|
|
15224
|
-
FunctionExpression(node) {
|
|
15225
|
-
fnNodes.push(node);
|
|
15226
|
-
},
|
|
15227
|
-
ArrowFunctionExpression(node) {
|
|
15228
|
-
fnNodes.push(node);
|
|
15229
|
-
},
|
|
15230
|
-
CallExpression(node) {
|
|
15231
|
-
if (node.callee.type === "Identifier") {
|
|
15232
|
-
globalExists[node.callee.value] = 1;
|
|
15233
|
-
}
|
|
15234
|
-
}
|
|
15235
|
-
});
|
|
15236
|
-
const functionParams = /* @__PURE__ */ Object.create(null);
|
|
15237
|
-
for (const fnNode of fnNodes) {
|
|
15238
|
-
const patterns = getParamPatterns(fnNode);
|
|
15239
|
-
for (const pat of patterns) {
|
|
15240
|
-
if (pat.type === "Identifier") {
|
|
15241
|
-
functionParams[pat.value] = 1;
|
|
15242
|
-
} else if (pat.type === "AssignmentPattern" && pat.left.type === "Identifier") {
|
|
15243
|
-
functionParams[pat.left.value] = 1;
|
|
15244
|
-
} else if (pat.type === "RestElement" && pat.argument.type === "Identifier") {
|
|
15245
|
-
functionParams[pat.argument.value] = 1;
|
|
15246
|
-
}
|
|
15247
|
-
}
|
|
15248
|
-
}
|
|
15249
|
-
walkSwcAst(ast, {
|
|
15250
|
-
Identifier(node) {
|
|
15251
|
-
const name = node.value;
|
|
15252
|
-
if (globalExists[name]) return;
|
|
15253
|
-
if (functionParams[name]) return;
|
|
15254
|
-
globalVars[name] = 1;
|
|
15255
|
-
},
|
|
15256
|
-
AssignmentExpression(node) {
|
|
15257
|
-
if (node.left.type === "Identifier") {
|
|
15258
|
-
const name = node.left.value;
|
|
15259
|
-
if (!globalExists[name] || globalExists[name] === 1) {
|
|
15260
|
-
globalExists[name] = (globalExists[name] || 0) + 1;
|
|
15261
|
-
}
|
|
15262
|
-
}
|
|
15263
|
-
}
|
|
15264
|
-
});
|
|
15265
|
-
return Object.keys(globalVars);
|
|
15266
|
-
}
|
|
15267
|
-
function getParamPatterns(fnNode) {
|
|
15268
|
-
if (fnNode.type === "ArrowFunctionExpression") {
|
|
15269
|
-
return fnNode.params;
|
|
15270
|
-
}
|
|
15271
|
-
return fnNode.params.map((p) => p.pat);
|
|
15272
|
-
}
|
|
15273
|
-
function fallbackExtractVariables(source) {
|
|
15274
|
-
const vars = /* @__PURE__ */ new Set();
|
|
15275
|
-
const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
|
|
15276
|
-
let m;
|
|
15277
|
-
while ((m = outputRegExp.exec(source)) !== null) {
|
|
15278
|
-
vars.add(m[1]);
|
|
15279
|
-
}
|
|
15280
|
-
const eachRegExp = /\{\{forOf\s+([a-zA-Z_$][\w$]*)\s+as/g;
|
|
15281
|
-
while ((m = eachRegExp.exec(source)) !== null) {
|
|
15282
|
-
vars.add(m[1]);
|
|
15283
|
-
}
|
|
15284
|
-
const ifRegExp = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
|
|
15285
|
-
while ((m = ifRegExp.exec(source)) !== null) {
|
|
15286
|
-
vars.add(m[1]);
|
|
15287
|
-
}
|
|
15288
|
-
return Array.from(vars).filter((v) => !BUILTIN_GLOBALS.has(v));
|
|
15289
|
-
}
|
|
15290
|
-
function walkSwcAst(ast, visitors) {
|
|
15291
|
-
function visit(node) {
|
|
15292
|
-
const type = node.type;
|
|
15293
|
-
if (visitors[type]) {
|
|
15294
|
-
visitors[type](node);
|
|
15295
|
-
}
|
|
15296
|
-
for (const key of Object.keys(node)) {
|
|
15297
|
-
if (key === "type" || key === "span" || key === "ctxt") continue;
|
|
15298
|
-
if (type === "MemberExpression" && key === "property") {
|
|
15299
|
-
const me = node;
|
|
15300
|
-
if (me.property.type !== "Computed") continue;
|
|
15301
|
-
}
|
|
15302
|
-
if (type === "KeyValueProperty" && key === "key") {
|
|
15303
|
-
const kv = node;
|
|
15304
|
-
if (kv.key.type !== "Computed") continue;
|
|
15305
|
-
}
|
|
15306
|
-
if (type === "MethodProperty" && key === "key") {
|
|
15307
|
-
const mp = node;
|
|
15308
|
-
if (mp.key.type !== "Computed") continue;
|
|
15309
|
-
}
|
|
15310
|
-
const child = Reflect.get(node, key);
|
|
15311
|
-
if (Array.isArray(child)) {
|
|
15312
|
-
for (const item of child) {
|
|
15313
|
-
if (isSwcNode(item)) visit(item);
|
|
15314
|
-
}
|
|
15315
|
-
} else if (isSwcNode(child)) {
|
|
15316
|
-
visit(child);
|
|
15317
|
-
}
|
|
15318
|
-
}
|
|
15319
|
-
}
|
|
15320
|
-
visit(ast);
|
|
15321
|
-
}
|
|
15322
|
-
function isSwcNode(v) {
|
|
15323
|
-
return !!v && typeof v === "object" && typeof v.type === "string";
|
|
15324
|
-
}
|
|
15325
|
-
var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
|
|
15326
|
-
// ─── Template runtime helpers (injected by compileToFunction) ───────
|
|
15327
|
-
//
|
|
15328
|
-
// These variables appear in the generated template function signature
|
|
15329
|
-
// or body. They must be excluded from extractGlobalVars() so that
|
|
15330
|
-
// they are not mistaken for user data variables and destructured from $data.
|
|
15331
|
-
// SPLITTER character constant (same as \x1e), used as namespace separator
|
|
15332
|
-
// for refData keys, event attribute encoding, and internal data structures.
|
|
15333
|
-
// Declared as: let $splitter='\x1e'
|
|
15334
|
-
"$splitter",
|
|
15335
|
-
// Data — the data object passed from Updater to the template function.
|
|
15336
|
-
// User variables are destructured from $data at the top of the function:
|
|
15337
|
-
// let {name, age} = $data;
|
|
15338
|
-
// This is the first parameter of the generated arrow function.
|
|
15339
|
-
"$data",
|
|
15340
|
-
// Null-safe toString: v => '' + (v == null ? '' : v)
|
|
15341
|
-
// Converts null/undefined to empty string, otherwise calls toString().
|
|
15342
|
-
// Wraps every {{!raw}} output to prevent "null" / "undefined" rendering.
|
|
15343
|
-
"$strSafe",
|
|
15344
|
-
// HTML entity encoder: v => $strSafe(v).replace(/[&<>"'`]/g, entityMap)
|
|
15345
|
-
// Encodes &, <, >, ", ', ` to HTML entities (& < etc.)
|
|
15346
|
-
// Applied to all {{=escaped}} and {{:binding}} outputs.
|
|
15347
|
-
"$encHtml",
|
|
15348
|
-
// HTML entity map — internal object used by $encHtml:
|
|
15349
|
-
// {'&':'amp','<':'gt','>':'gt','"':'#34','\'':'#39','`':'#96'}
|
|
15350
|
-
// Not a standalone function; referenced inside $encHtml's closure.
|
|
15351
|
-
"$entMap",
|
|
15352
|
-
// HTML entity RegExp — internal regexp used by $encHtml:
|
|
15353
|
-
// /[&<>"'`]/g
|
|
15354
|
-
"$entReg",
|
|
15355
|
-
// HTML entity replacer function — internal helper used by $encHtml:
|
|
15356
|
-
// m => '&' + $entMap[m] + ';'
|
|
15357
|
-
// Maps matched character to its entity string.
|
|
15358
|
-
"$entFn",
|
|
15359
|
-
// Output buffer — the string accumulator for rendered HTML.
|
|
15360
|
-
// All template output is appended via $out += '...'.
|
|
15361
|
-
// Declared as: let $out = ''
|
|
15362
|
-
"$out",
|
|
15363
|
-
// Reference lookup: (refData, value) => key
|
|
15364
|
-
// Finds or allocates a SPLITTER-prefixed key in refData for a given
|
|
15365
|
-
// object reference. Used by {{@ref}} operator for passing object
|
|
15366
|
-
// references to child views via v-lark attributes.
|
|
15367
|
-
"$refFn",
|
|
15368
|
-
// URI encoder: v => encodeURIComponent($strSafe(v)).replace(/[!')(*]/g, extraMap)
|
|
15369
|
-
// Extends encodeURIComponent with encoding of ! ' ( ) *.
|
|
15370
|
-
// Applied to values in @event URL parameters and {{!uri}} contexts.
|
|
15371
|
-
"$encUri",
|
|
15372
|
-
// URI encode map — internal object used by $encUri:
|
|
15373
|
-
// {'!':'%21','\'':'%27','(':'%28',')':'%29','*':'%2A'}
|
|
15374
|
-
"$uriMap",
|
|
15375
|
-
// URI encode replacer — internal helper used by $encUri:
|
|
15376
|
-
// m => $uriMap[m]
|
|
15377
|
-
"$uriFn",
|
|
15378
|
-
// URI encode regexp — internal regexp used by $encUri:
|
|
15379
|
-
// /[!')(*]/g
|
|
15380
|
-
"$uriReg",
|
|
15381
|
-
// Quote encoder: v => $strSafe(v).replace(/['"\\]/g, '\\$&')
|
|
15382
|
-
// Escapes quotes and backslashes for safe embedding in HTML attribute
|
|
15383
|
-
// values (e.g. data-json='...').
|
|
15384
|
-
"$encQuote",
|
|
15385
|
-
// Quote encode regexp — internal regexp used by $encQuote:
|
|
15386
|
-
// /['"\\]/g
|
|
15387
|
-
"$qReg",
|
|
15388
|
-
// View ID — the unique identifier of the owning View instance.
|
|
15389
|
-
// Injected into @event attribute values at render time so that
|
|
15390
|
-
// EventDelegator can dispatch events to the correct View handler.
|
|
15391
|
-
// The \x1f placeholder in compiled output is replaced with '+$viewId+'.
|
|
15392
|
-
"$viewId",
|
|
15393
|
-
// Debug: current expression text — stores the template expression being
|
|
15394
|
-
// evaluated, for error reporting. Only present in debug mode.
|
|
15395
|
-
// e.g. $dbgExpr='<%=user.name%>'
|
|
15396
|
-
"$dbgExpr",
|
|
15397
|
-
// Debug: original art syntax — stores the {{}} template syntax before
|
|
15398
|
-
// conversion, for error reporting. Only present in debug mode.
|
|
15399
|
-
// e.g. $dbgArt='{{=user.name}}'
|
|
15400
|
-
"$dbgArt",
|
|
15401
|
-
// Debug: source line number — tracks the current line in the template
|
|
15402
|
-
// source, for error reporting. Only present in debug mode.
|
|
15403
|
-
"$dbgLine",
|
|
15404
|
-
// RefData alias — fallback reference lookup table.
|
|
15405
|
-
// Defaults to $data when no explicit $refAlt is provided.
|
|
15406
|
-
// Ensures $refFn() does not crash when @ operator is used without refData.
|
|
15407
|
-
"$refAlt",
|
|
15408
|
-
// Temporary variable — used by the compiler for intermediate
|
|
15409
|
-
// expression results in generated code (e.g. loop variables,
|
|
15410
|
-
// conditional branches). Declared as: let $tmp
|
|
15411
|
-
"$tmp",
|
|
15412
|
-
// JS literals
|
|
15413
|
-
"undefined",
|
|
15414
|
-
"null",
|
|
15415
|
-
"true",
|
|
15416
|
-
"false",
|
|
15417
|
-
"NaN",
|
|
15418
|
-
"Infinity",
|
|
15419
|
-
// JS built-in globals
|
|
15420
|
-
"window",
|
|
15421
|
-
"self",
|
|
15422
|
-
"globalThis",
|
|
15423
|
-
"document",
|
|
15424
|
-
"console",
|
|
15425
|
-
"JSON",
|
|
15426
|
-
"Math",
|
|
15427
|
-
"Intl",
|
|
15428
|
-
"Promise",
|
|
15429
|
-
"Symbol",
|
|
15430
|
-
"Number",
|
|
15431
|
-
"String",
|
|
15432
|
-
"Boolean",
|
|
15433
|
-
"Array",
|
|
15434
|
-
"Object",
|
|
15435
|
-
"Date",
|
|
15436
|
-
"RegExp",
|
|
15437
|
-
"Error",
|
|
15438
|
-
"TypeError",
|
|
15439
|
-
"RangeError",
|
|
15440
|
-
"SyntaxError",
|
|
15441
|
-
"Map",
|
|
15442
|
-
"Set",
|
|
15443
|
-
"WeakMap",
|
|
15444
|
-
"WeakSet",
|
|
15445
|
-
"Proxy",
|
|
15446
|
-
"Reflect",
|
|
15447
|
-
"ArrayBuffer",
|
|
15448
|
-
"DataView",
|
|
15449
|
-
"Float32Array",
|
|
15450
|
-
"Float64Array",
|
|
15451
|
-
"Int8Array",
|
|
15452
|
-
"Int16Array",
|
|
15453
|
-
"Int32Array",
|
|
15454
|
-
"Uint8Array",
|
|
15455
|
-
"Uint16Array",
|
|
15456
|
-
"Uint32Array",
|
|
15457
|
-
"Uint8ClampedArray",
|
|
15458
|
-
// Functions
|
|
15459
|
-
"parseInt",
|
|
15460
|
-
"parseFloat",
|
|
15461
|
-
"isNaN",
|
|
15462
|
-
"isFinite",
|
|
15463
|
-
"encodeURIComponent",
|
|
15464
|
-
"decodeURIComponent",
|
|
15465
|
-
"encodeURI",
|
|
15466
|
-
"decodeURI",
|
|
15467
|
-
// SWC helpers
|
|
15468
|
-
"arguments",
|
|
15469
|
-
"this",
|
|
15470
|
-
"require",
|
|
15471
|
-
// Lark framework
|
|
15472
|
-
"Lark"
|
|
15473
|
-
]);
|
|
15474
|
-
|
|
15475
15149
|
// src/compiler/extract-global-vars.ts
|
|
15476
15150
|
var import_parser = __toESM(require_lib(), 1);
|
|
15477
|
-
async function
|
|
15151
|
+
async function extractGlobalVars(source) {
|
|
15478
15152
|
const { protectedSource, comments: _comments } = protectComments(source);
|
|
15479
15153
|
const viewEventProcessed = processViewEvents(protectedSource);
|
|
15480
15154
|
const converted = convertArtSyntax(viewEventProcessed, false);
|
|
@@ -15511,10 +15185,10 @@ async function extractGlobalVars2(source) {
|
|
|
15511
15185
|
allowAwaitOutsideFunction: true
|
|
15512
15186
|
});
|
|
15513
15187
|
} catch {
|
|
15514
|
-
return
|
|
15188
|
+
return fallbackExtractVariables(source);
|
|
15515
15189
|
}
|
|
15516
15190
|
const globalExists = {};
|
|
15517
|
-
for (const name of
|
|
15191
|
+
for (const name of BUILTIN_GLOBALS) globalExists[name] = 1;
|
|
15518
15192
|
const globalVars = /* @__PURE__ */ Object.create(null);
|
|
15519
15193
|
const fnRange = [];
|
|
15520
15194
|
walkAst(ast, {
|
|
@@ -15573,22 +15247,22 @@ async function extractGlobalVars2(source) {
|
|
|
15573
15247
|
});
|
|
15574
15248
|
return Object.keys(globalVars);
|
|
15575
15249
|
}
|
|
15576
|
-
function
|
|
15250
|
+
function fallbackExtractVariables(source) {
|
|
15577
15251
|
const vars = /* @__PURE__ */ new Set();
|
|
15578
15252
|
const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
|
|
15579
15253
|
let m;
|
|
15580
15254
|
while ((m = outputRegExp.exec(source)) !== null) {
|
|
15581
15255
|
vars.add(m[1]);
|
|
15582
15256
|
}
|
|
15583
|
-
const
|
|
15584
|
-
while ((m =
|
|
15257
|
+
const forOfRegExp = /\{\{forOf\s+([a-zA-Z_$][\w$]*)\s+as/g;
|
|
15258
|
+
while ((m = forOfRegExp.exec(source)) !== null) {
|
|
15585
15259
|
vars.add(m[1]);
|
|
15586
15260
|
}
|
|
15587
15261
|
const ifRegExp = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
|
|
15588
15262
|
while ((m = ifRegExp.exec(source)) !== null) {
|
|
15589
15263
|
vars.add(m[1]);
|
|
15590
15264
|
}
|
|
15591
|
-
return Array.from(vars).filter((v) => !
|
|
15265
|
+
return Array.from(vars).filter((v) => !BUILTIN_GLOBALS.has(v));
|
|
15592
15266
|
}
|
|
15593
15267
|
function walkAst(ast, visitors) {
|
|
15594
15268
|
function visit(node) {
|
|
@@ -15626,7 +15300,7 @@ function walkAst(ast, visitors) {
|
|
|
15626
15300
|
function isAstNode(v) {
|
|
15627
15301
|
return !!v && typeof v === "object" && typeof v.type === "string";
|
|
15628
15302
|
}
|
|
15629
|
-
var
|
|
15303
|
+
var BUILTIN_GLOBALS = /* @__PURE__ */ new Set([
|
|
15630
15304
|
// ─── Template runtime helpers (injected by compileToFunction) ───────
|
|
15631
15305
|
//
|
|
15632
15306
|
// These variables appear in the generated template function signature
|
|
@@ -15865,8 +15539,8 @@ function compileToFunction(source, debug, file) {
|
|
|
15865
15539
|
return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
|
|
15866
15540
|
}
|
|
15867
15541
|
async function compileTemplate(source, options = {}) {
|
|
15868
|
-
const { debug = false, file, virtualDom = false
|
|
15869
|
-
const globalVars = options.globalVars ?? await
|
|
15542
|
+
const { debug = false, file, virtualDom = false } = options;
|
|
15543
|
+
const globalVars = options.globalVars ?? await extractGlobalVars(source);
|
|
15870
15544
|
const { protectedSource, comments } = protectComments(source);
|
|
15871
15545
|
const converted = convertArtSyntax(protectedSource, debug);
|
|
15872
15546
|
const viewEventProcessed = processViewEvents(converted);
|
|
@@ -15901,6 +15575,5 @@ export default function(data, viewId, refData) {
|
|
|
15901
15575
|
// Annotate the CommonJS export names for ESM import in node:
|
|
15902
15576
|
0 && (module.exports = {
|
|
15903
15577
|
compileTemplate,
|
|
15904
|
-
extractGlobalVars
|
|
15905
|
-
extractGlobalVarsSwc
|
|
15578
|
+
extractGlobalVars
|
|
15906
15579
|
});
|
package/dist/compiler.d.cts
CHANGED
|
@@ -8,8 +8,6 @@ interface CompileOptions {
|
|
|
8
8
|
file?: string;
|
|
9
9
|
/** Generate VDOM output instead of HTML string (default: false) */
|
|
10
10
|
virtualDom?: boolean;
|
|
11
|
-
/** Use SWC instead of Babel for parsing (default: false) */
|
|
12
|
-
useSwc?: boolean;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
/**
|
|
@@ -28,33 +26,6 @@ interface CompileOptions {
|
|
|
28
26
|
*/
|
|
29
27
|
declare function compileTemplate(source: string, options?: CompileOptions): Promise<string>;
|
|
30
28
|
|
|
31
|
-
/**
|
|
32
|
-
* Extract global variable names from a template source using AST analysis.
|
|
33
|
-
*
|
|
34
|
-
* 1. Convert template commands (<% %> blocks) into a form parseable by an AST parser
|
|
35
|
-
* 2. Walk the AST to find all Identifier nodes
|
|
36
|
-
* 3. Track variable declarations (VariableDeclarator, FunctionDeclaration) as local vars
|
|
37
|
-
* 4. Track function parameters as local vars
|
|
38
|
-
* 5. Remaining identifiers that are not local and not in the exclusion list are "global" —
|
|
39
|
-
* they must be passed in as part of the data context ($$)
|
|
40
|
-
*
|
|
41
|
-
* This replaces the old regex-based `extractVariables()` with proper scope analysis,
|
|
42
|
-
* eliminating false positives from local template variables and function parameters.
|
|
43
|
-
*
|
|
44
|
-
* @param source - The raw HTML template content (with {{ }} syntax)
|
|
45
|
-
* @returns Array of global variable names found in the template
|
|
46
|
-
*/
|
|
47
|
-
declare function extractGlobalVars$1(source: string): Promise<string[]>;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Extract global variable names from a template source using SWC AST analysis.
|
|
51
|
-
*
|
|
52
|
-
* 1. Convert template commands ({{ }} blocks) into a form parseable by SWC
|
|
53
|
-
* 2. Walk the AST to find all Identifier nodes
|
|
54
|
-
* 3. Track variable declarations (VariableDeclarator, FunctionDeclaration) as local vars
|
|
55
|
-
* 4. Track function parameters as local vars
|
|
56
|
-
* 5. Remaining identifiers that are not local and not in the exclusion list are "global"
|
|
57
|
-
*/
|
|
58
29
|
/**
|
|
59
30
|
* Extract global variable names from a template source using AST analysis.
|
|
60
31
|
*
|
|
@@ -73,4 +44,4 @@ declare function extractGlobalVars$1(source: string): Promise<string[]>;
|
|
|
73
44
|
*/
|
|
74
45
|
declare function extractGlobalVars(source: string): Promise<string[]>;
|
|
75
46
|
|
|
76
|
-
export { compileTemplate, extractGlobalVars
|
|
47
|
+
export { compileTemplate, extractGlobalVars };
|
package/dist/compiler.d.ts
CHANGED
|
@@ -8,8 +8,6 @@ interface CompileOptions {
|
|
|
8
8
|
file?: string;
|
|
9
9
|
/** Generate VDOM output instead of HTML string (default: false) */
|
|
10
10
|
virtualDom?: boolean;
|
|
11
|
-
/** Use SWC instead of Babel for parsing (default: false) */
|
|
12
|
-
useSwc?: boolean;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
/**
|
|
@@ -28,33 +26,6 @@ interface CompileOptions {
|
|
|
28
26
|
*/
|
|
29
27
|
declare function compileTemplate(source: string, options?: CompileOptions): Promise<string>;
|
|
30
28
|
|
|
31
|
-
/**
|
|
32
|
-
* Extract global variable names from a template source using AST analysis.
|
|
33
|
-
*
|
|
34
|
-
* 1. Convert template commands (<% %> blocks) into a form parseable by an AST parser
|
|
35
|
-
* 2. Walk the AST to find all Identifier nodes
|
|
36
|
-
* 3. Track variable declarations (VariableDeclarator, FunctionDeclaration) as local vars
|
|
37
|
-
* 4. Track function parameters as local vars
|
|
38
|
-
* 5. Remaining identifiers that are not local and not in the exclusion list are "global" —
|
|
39
|
-
* they must be passed in as part of the data context ($$)
|
|
40
|
-
*
|
|
41
|
-
* This replaces the old regex-based `extractVariables()` with proper scope analysis,
|
|
42
|
-
* eliminating false positives from local template variables and function parameters.
|
|
43
|
-
*
|
|
44
|
-
* @param source - The raw HTML template content (with {{ }} syntax)
|
|
45
|
-
* @returns Array of global variable names found in the template
|
|
46
|
-
*/
|
|
47
|
-
declare function extractGlobalVars$1(source: string): Promise<string[]>;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Extract global variable names from a template source using SWC AST analysis.
|
|
51
|
-
*
|
|
52
|
-
* 1. Convert template commands ({{ }} blocks) into a form parseable by SWC
|
|
53
|
-
* 2. Walk the AST to find all Identifier nodes
|
|
54
|
-
* 3. Track variable declarations (VariableDeclarator, FunctionDeclaration) as local vars
|
|
55
|
-
* 4. Track function parameters as local vars
|
|
56
|
-
* 5. Remaining identifiers that are not local and not in the exclusion list are "global"
|
|
57
|
-
*/
|
|
58
29
|
/**
|
|
59
30
|
* Extract global variable names from a template source using AST analysis.
|
|
60
31
|
*
|
|
@@ -73,4 +44,4 @@ declare function extractGlobalVars$1(source: string): Promise<string[]>;
|
|
|
73
44
|
*/
|
|
74
45
|
declare function extractGlobalVars(source: string): Promise<string[]>;
|
|
75
46
|
|
|
76
|
-
export { compileTemplate, extractGlobalVars
|
|
47
|
+
export { compileTemplate, extractGlobalVars };
|