@llui/vite-plugin 0.0.29 → 0.0.30
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-cache.d.ts +20 -0
- package/dist/compiler-cache.d.ts.map +1 -0
- package/dist/compiler-cache.js +20 -0
- package/dist/compiler-cache.js.map +1 -0
- package/dist/transform.d.ts +28 -0
- package/dist/transform.d.ts.map +1 -1
- package/dist/transform.js +92 -3
- package/dist/transform.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface BindingSourceEntry {
|
|
2
|
+
bindingIndex: number;
|
|
3
|
+
file: string;
|
|
4
|
+
line: number;
|
|
5
|
+
column: number;
|
|
6
|
+
}
|
|
7
|
+
export interface CompilerCacheEntry {
|
|
8
|
+
preSource: string;
|
|
9
|
+
postSource: string;
|
|
10
|
+
msgMaskMap: Record<string, number>;
|
|
11
|
+
bindingSources: BindingSourceEntry[];
|
|
12
|
+
}
|
|
13
|
+
export declare class CompilerCache {
|
|
14
|
+
private readonly cache;
|
|
15
|
+
set(componentName: string, entry: CompilerCacheEntry): void;
|
|
16
|
+
get(componentName: string): CompilerCacheEntry | undefined;
|
|
17
|
+
has(componentName: string): boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const compilerCache: CompilerCache;
|
|
20
|
+
//# sourceMappingURL=compiler-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler-cache.d.ts","sourceRoot":"","sources":["../src/compiler-cache.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,cAAc,EAAE,kBAAkB,EAAE,CAAA;CACrC;AAID,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAE9D,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAQ3D,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1D,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;CAGpC;AAED,eAAO,MAAM,aAAa,eAAsB,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const MAX_ENTRIES = 50;
|
|
2
|
+
export class CompilerCache {
|
|
3
|
+
cache = new Map();
|
|
4
|
+
set(componentName, entry) {
|
|
5
|
+
if (this.cache.has(componentName))
|
|
6
|
+
this.cache.delete(componentName);
|
|
7
|
+
this.cache.set(componentName, entry);
|
|
8
|
+
if (this.cache.size > MAX_ENTRIES) {
|
|
9
|
+
this.cache.delete(this.cache.keys().next().value);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
get(componentName) {
|
|
13
|
+
return this.cache.get(componentName);
|
|
14
|
+
}
|
|
15
|
+
has(componentName) {
|
|
16
|
+
return this.cache.has(componentName);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export const compilerCache = new CompilerCache();
|
|
20
|
+
//# sourceMappingURL=compiler-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler-cache.js","sourceRoot":"","sources":["../src/compiler-cache.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,GAAG,EAAE,CAAA;AAEtB,MAAM,OAAO,aAAa;IACP,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAA;IAE9D,GAAG,CAAC,aAAqB,EAAE,KAAyB;QAClD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QACnE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;QACpC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IAED,GAAG,CAAC,aAAqB;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IACtC,CAAC;IAED,GAAG,CAAC,aAAqB;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IACtC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAA","sourcesContent":["export interface BindingSourceEntry {\n bindingIndex: number\n file: string\n line: number\n column: number\n}\n\nexport interface CompilerCacheEntry {\n preSource: string\n postSource: string\n msgMaskMap: Record<string, number>\n bindingSources: BindingSourceEntry[]\n}\n\nconst MAX_ENTRIES = 50\n\nexport class CompilerCache {\n private readonly cache = new Map<string, CompilerCacheEntry>()\n\n set(componentName: string, entry: CompilerCacheEntry): void {\n if (this.cache.has(componentName)) this.cache.delete(componentName)\n this.cache.set(componentName, entry)\n if (this.cache.size > MAX_ENTRIES) {\n this.cache.delete(this.cache.keys().next().value!)\n }\n }\n\n get(componentName: string): CompilerCacheEntry | undefined {\n return this.cache.get(componentName)\n }\n\n has(componentName: string): boolean {\n return this.cache.has(componentName)\n }\n}\n\nexport const compilerCache = new CompilerCache()\n"]}
|
package/dist/transform.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
1
2
|
/**
|
|
2
3
|
* Transform a source file containing @llui/dom imports.
|
|
3
4
|
* Returns the transformed source or null if no transformation needed.
|
|
@@ -47,4 +48,31 @@ export declare function transformUseClientSsr(source: string, _filename: string)
|
|
|
47
48
|
* without parsing the whole file twice.
|
|
48
49
|
*/
|
|
49
50
|
export declare function hasUseClientDirective(source: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Extract the view function body (the value of the `view:` property) from
|
|
53
|
+
* a component() config object literal. Uses a regex heuristic — good enough
|
|
54
|
+
* for round-tripping source for dev/agent tools.
|
|
55
|
+
*/
|
|
56
|
+
export declare function extractViewBody(code: string): string | null;
|
|
57
|
+
/**
|
|
58
|
+
* Extract the component `name:` string literal from a component() call's
|
|
59
|
+
* first argument object literal in the source text.
|
|
60
|
+
*/
|
|
61
|
+
export declare function extractComponentNameFromConfig(node: ts.CallExpression): string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Generate Object.defineProperty calls for __preSource, __postSource,
|
|
64
|
+
* __msgMaskMap, and __bindingSources on a component variable. These are
|
|
65
|
+
* non-enumerable so they don't appear in JSON.stringify(componentDef) but are
|
|
66
|
+
* visible to devtools.
|
|
67
|
+
*/
|
|
68
|
+
export declare function generateCompilerCacheProps(varName: string, componentName: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* After the full output string is assembled, update each cached component's
|
|
71
|
+
* postSource (extract view body from the transformed output), then append
|
|
72
|
+
* Object.defineProperty calls for all four compiler-cache properties.
|
|
73
|
+
*/
|
|
74
|
+
export declare function appendCompilerCacheProps(output: string, componentDecls: Array<{
|
|
75
|
+
varName: string;
|
|
76
|
+
componentName: string;
|
|
77
|
+
}>): string;
|
|
50
78
|
//# sourceMappingURL=transform.d.ts.map
|
package/dist/transform.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAiL3B;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,UAAQ,EACf,iBAAiB,UAAQ,EACzB,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,OAAO,UAAQ,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CA8TnD;AAwoID,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,wBAAwB,GAAG,IAAI,CAoGjC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CA4B7D;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,GAAG,MAAM,GAAG,IAAI,CAcrF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CASzF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,GAChE,MAAM,CAYR"}
|
package/dist/transform.js
CHANGED
|
@@ -5,6 +5,7 @@ import { extractMsgAnnotations } from './msg-annotations.js';
|
|
|
5
5
|
import { extractStateSchema } from './state-schema.js';
|
|
6
6
|
import { computeSchemaHash } from './schema-hash.js';
|
|
7
7
|
import { extractBindingDescriptors } from './binding-descriptors.js';
|
|
8
|
+
import { compilerCache } from './compiler-cache.js';
|
|
8
9
|
function createMaskLiteral(f, mask) {
|
|
9
10
|
if (mask >= 0)
|
|
10
11
|
return f.createNumericLiteral(mask);
|
|
@@ -323,6 +324,22 @@ export function transformLlui(source, _filename, devMode = false, emitAgentMetad
|
|
|
323
324
|
if (bindingDescriptors.length > 0) {
|
|
324
325
|
result = injectBindingDescriptors(result ?? node, bindingDescriptors, f);
|
|
325
326
|
}
|
|
327
|
+
// Populate compiler cache — preSource and msgMaskMap are known now;
|
|
328
|
+
// postSource is filled in after the full output is assembled.
|
|
329
|
+
const cachedComponentName = extractComponentNameFromConfig(node);
|
|
330
|
+
if (cachedComponentName) {
|
|
331
|
+
const preSource = extractViewBody(source) ?? '';
|
|
332
|
+
const msgMaskMap = {};
|
|
333
|
+
for (const [path, bit] of fieldBits) {
|
|
334
|
+
msgMaskMap[path] = bit;
|
|
335
|
+
}
|
|
336
|
+
compilerCache.set(cachedComponentName, {
|
|
337
|
+
preSource,
|
|
338
|
+
postSource: '',
|
|
339
|
+
msgMaskMap,
|
|
340
|
+
bindingSources: [],
|
|
341
|
+
});
|
|
342
|
+
}
|
|
326
343
|
}
|
|
327
344
|
if (devMode) {
|
|
328
345
|
result = injectComponentMeta(result ?? node, node, sourceFile, _filename, f);
|
|
@@ -350,8 +367,8 @@ export function transformLlui(source, _filename, devMode = false, emitAgentMetad
|
|
|
350
367
|
transformed = cleanupImports(transformed, lluiImport, importedHelpers, safeToRemove, usesElSplit, usesElTemplate, usesMemo, usesApplyBinding, usesCloneStaticTemplate, f);
|
|
351
368
|
if (edits.length === 0)
|
|
352
369
|
return null;
|
|
353
|
-
// Find component declarations for HMR
|
|
354
|
-
const componentDecls = devMode ? findComponentDeclarations(sourceFile, lluiImport) : [];
|
|
370
|
+
// Find component declarations for HMR and agent metadata
|
|
371
|
+
const componentDecls = devMode || emitAgentMetadata ? findComponentDeclarations(sourceFile, lluiImport) : [];
|
|
355
372
|
// Build per-statement edits by comparing original vs transformed.
|
|
356
373
|
// Only emit edits for statements that actually changed.
|
|
357
374
|
// Untouched code keeps its original positions → accurate source maps.
|
|
@@ -371,7 +388,10 @@ export function transformLlui(source, _filename, devMode = false, emitAgentMetad
|
|
|
371
388
|
const { top: _top, bottom: _bottom } = devMode
|
|
372
389
|
? generateDevCode(componentDecls, mcpPort)
|
|
373
390
|
: { top: '', bottom: '' };
|
|
374
|
-
|
|
391
|
+
let output = (_top ? _top + '\n' : '') + printer.printFile(transformed) + (_bottom ? '\n' + _bottom : '');
|
|
392
|
+
if (devMode || emitAgentMetadata) {
|
|
393
|
+
output = appendCompilerCacheProps(output, componentDecls);
|
|
394
|
+
}
|
|
375
395
|
return { output, edits: [{ start: 0, end: source.length, replacement: output }] };
|
|
376
396
|
}
|
|
377
397
|
// Compare ignoring trailing semicolons and whitespace (printer adds them)
|
|
@@ -403,6 +423,13 @@ export function transformLlui(source, _filename, devMode = false, emitAgentMetad
|
|
|
403
423
|
for (const edit of sorted) {
|
|
404
424
|
output = output.slice(0, edit.start) + edit.replacement + output.slice(edit.end);
|
|
405
425
|
}
|
|
426
|
+
// After output is assembled, update postSource in cache and emit non-enumerable props
|
|
427
|
+
if ((devMode || emitAgentMetadata) && componentDecls.length > 0) {
|
|
428
|
+
const cacheProps = appendCompilerCacheProps(output, componentDecls);
|
|
429
|
+
if (cacheProps !== output) {
|
|
430
|
+
output = cacheProps;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
406
433
|
return { output, edits: finalEdits };
|
|
407
434
|
}
|
|
408
435
|
// ── HMR ──────────────────────────────────────────────────────────
|
|
@@ -3405,4 +3432,66 @@ export function hasUseClientDirective(source) {
|
|
|
3405
3432
|
}
|
|
3406
3433
|
return source.startsWith("'use client'", i) || source.startsWith('"use client"', i);
|
|
3407
3434
|
}
|
|
3435
|
+
// ── Compiler cache helpers ────────────────────────────────────────
|
|
3436
|
+
/**
|
|
3437
|
+
* Extract the view function body (the value of the `view:` property) from
|
|
3438
|
+
* a component() config object literal. Uses a regex heuristic — good enough
|
|
3439
|
+
* for round-tripping source for dev/agent tools.
|
|
3440
|
+
*/
|
|
3441
|
+
export function extractViewBody(code) {
|
|
3442
|
+
const match = /\bview\s*:\s*([\s\S]*?)(?=,\s*(?:onEffect|update|init|name|onMsg)\s*:|}\s*\))/m.exec(code);
|
|
3443
|
+
return match?.[1]?.trim() ?? null;
|
|
3444
|
+
}
|
|
3445
|
+
/**
|
|
3446
|
+
* Extract the component `name:` string literal from a component() call's
|
|
3447
|
+
* first argument object literal in the source text.
|
|
3448
|
+
*/
|
|
3449
|
+
export function extractComponentNameFromConfig(node) {
|
|
3450
|
+
const configArg = node.arguments[0];
|
|
3451
|
+
if (!configArg || !ts.isObjectLiteralExpression(configArg))
|
|
3452
|
+
return null;
|
|
3453
|
+
for (const prop of configArg.properties) {
|
|
3454
|
+
if (ts.isPropertyAssignment(prop) &&
|
|
3455
|
+
ts.isIdentifier(prop.name) &&
|
|
3456
|
+
prop.name.text === 'name' &&
|
|
3457
|
+
ts.isStringLiteral(prop.initializer)) {
|
|
3458
|
+
return prop.initializer.text;
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
return null;
|
|
3462
|
+
}
|
|
3463
|
+
/**
|
|
3464
|
+
* Generate Object.defineProperty calls for __preSource, __postSource,
|
|
3465
|
+
* __msgMaskMap, and __bindingSources on a component variable. These are
|
|
3466
|
+
* non-enumerable so they don't appear in JSON.stringify(componentDef) but are
|
|
3467
|
+
* visible to devtools.
|
|
3468
|
+
*/
|
|
3469
|
+
export function generateCompilerCacheProps(varName, componentName) {
|
|
3470
|
+
const entry = compilerCache.get(componentName);
|
|
3471
|
+
if (!entry)
|
|
3472
|
+
return '';
|
|
3473
|
+
return (`\nObject.defineProperty(${varName}, '__preSource', { value: ${JSON.stringify(entry.preSource)}, enumerable: false, configurable: true })` +
|
|
3474
|
+
`\nObject.defineProperty(${varName}, '__postSource', { value: ${JSON.stringify(entry.postSource)}, enumerable: false, configurable: true })` +
|
|
3475
|
+
`\nObject.defineProperty(${varName}, '__msgMaskMap', { value: ${JSON.stringify(entry.msgMaskMap)}, enumerable: false, configurable: true })` +
|
|
3476
|
+
`\nObject.defineProperty(${varName}, '__bindingSources', { value: ${JSON.stringify(entry.bindingSources)}, enumerable: false, configurable: true })`);
|
|
3477
|
+
}
|
|
3478
|
+
/**
|
|
3479
|
+
* After the full output string is assembled, update each cached component's
|
|
3480
|
+
* postSource (extract view body from the transformed output), then append
|
|
3481
|
+
* Object.defineProperty calls for all four compiler-cache properties.
|
|
3482
|
+
*/
|
|
3483
|
+
export function appendCompilerCacheProps(output, componentDecls) {
|
|
3484
|
+
let result = output;
|
|
3485
|
+
for (const { varName, componentName } of componentDecls) {
|
|
3486
|
+
const existing = compilerCache.get(componentName);
|
|
3487
|
+
if (!existing)
|
|
3488
|
+
continue;
|
|
3489
|
+
// Update the cache entry with the post-transform view body
|
|
3490
|
+
const postSource = extractViewBody(output) ?? '';
|
|
3491
|
+
compilerCache.set(componentName, { ...existing, postSource });
|
|
3492
|
+
// Append non-enumerable property definitions
|
|
3493
|
+
result += generateCompilerCacheProps(varName, componentName);
|
|
3494
|
+
}
|
|
3495
|
+
return result;
|
|
3496
|
+
}
|
|
3408
3497
|
//# sourceMappingURL=transform.js.map
|