@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.
@@ -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"]}
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAgLA;;;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,CAiSnD;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"}
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
- const output = (_top ? _top + '\n' : '') + printer.printFile(transformed) + (_bottom ? '\n' + _bottom : '');
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