@llui/compiler 0.3.1 → 0.4.0

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,42 @@
1
+ /**
2
+ * Single source of truth for the compiler's emission name registry.
3
+ *
4
+ * Two disjoint sets:
5
+ *
6
+ * - `COMPILER_RENAMEABLE_KEYS` — property keys the compiler synthesizes
7
+ * onto `component({...})` literals. The runtime reads these via
8
+ * property access (`def.__view`, `def.__prefixes`, etc.) inside the
9
+ * same bundle that the compiler emitted them into. Their producer and
10
+ * consumer are colocated in the bundle, so the vite-plugin's post-
11
+ * bundle property-rename pass can shorten them to `$a`/`$b`/… without
12
+ * breaking the contract.
13
+ *
14
+ * - `COMPILER_DOM_INTERNAL_IMPORTS` — runtime helpers the compiler
15
+ * references by NAME (not by property key) via an
16
+ * `import { __cloneStaticTemplate } from '@llui/dom/internal'`
17
+ * declaration. These cross a module boundary at consumer build time.
18
+ * Anything the rename pass touches that ends up in an import specifier
19
+ * would be rewritten to `$X`, which the source package never exports,
20
+ * and rolldown fails the build with `MISSING_EXPORT`. **These names
21
+ * must NEVER be renamed.**
22
+ *
23
+ * The two sets are disjoint by construction — the type-level
24
+ * `Extract<...>` assertion below fails compilation if any name appears
25
+ * in both lists. New compiler-emitted names land in whichever list
26
+ * matches their lifetime; if you accidentally add one to both, `tsc`
27
+ * tells you before the bug ships.
28
+ *
29
+ * Subpath choice matters: the helpers live at `@llui/dom/internal`, not
30
+ * at the root `@llui/dom`, because the rename regex matches any
31
+ * `__`-prefixed identifier in the bundle. By hosting the helpers on a
32
+ * subpath whose import specifier never gets touched by the rename, we
33
+ * keep both the regex and the runtime export surface internally
34
+ * consistent without needing an AST-aware rename pass.
35
+ */
36
+ export declare const COMPILER_RENAMEABLE_KEYS: readonly ["__view", "__view$", "__prefixes", "__handlers", "__compilerVersion", "__directUpdate", "__mask", "__maskHi", "__maskLegend", "__perItem", "__rowUpd", "__rowUpdate", "__schemaHash", "__tpl", "__msgSchema", "__msgAnnotations", "__bindingDescriptors", "__stateSchema", "__effectSchema", "__componentMeta", "__renderToString", "__update", "__dirty"];
37
+ export type CompilerRenameableKey = (typeof COMPILER_RENAMEABLE_KEYS)[number];
38
+ export declare const COMPILER_DOM_INTERNAL_IMPORTS: readonly ["__bindUncertain", "__cloneStaticTemplate", "__runPhase2", "__handleMsg", "__registerScopeVariants", "__clientOnlyStub"];
39
+ export type CompilerDomInternalImport = (typeof COMPILER_DOM_INTERNAL_IMPORTS)[number];
40
+ /** Module specifier the compiler emits for the internal-helper imports. */
41
+ export declare const DOM_INTERNAL_MODULE_SPECIFIER = "@llui/dom/internal";
42
+ //# sourceMappingURL=emit-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-names.d.ts","sourceRoot":"","sources":["../src/emit-names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,eAAO,MAAM,wBAAwB,sWAwB3B,CAAA;AAEV,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7E,eAAO,MAAM,6BAA6B,oIAOhC,CAAA;AAEV,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAA;AAUtF,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B,uBAAuB,CAAA"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Single source of truth for the compiler's emission name registry.
3
+ *
4
+ * Two disjoint sets:
5
+ *
6
+ * - `COMPILER_RENAMEABLE_KEYS` — property keys the compiler synthesizes
7
+ * onto `component({...})` literals. The runtime reads these via
8
+ * property access (`def.__view`, `def.__prefixes`, etc.) inside the
9
+ * same bundle that the compiler emitted them into. Their producer and
10
+ * consumer are colocated in the bundle, so the vite-plugin's post-
11
+ * bundle property-rename pass can shorten them to `$a`/`$b`/… without
12
+ * breaking the contract.
13
+ *
14
+ * - `COMPILER_DOM_INTERNAL_IMPORTS` — runtime helpers the compiler
15
+ * references by NAME (not by property key) via an
16
+ * `import { __cloneStaticTemplate } from '@llui/dom/internal'`
17
+ * declaration. These cross a module boundary at consumer build time.
18
+ * Anything the rename pass touches that ends up in an import specifier
19
+ * would be rewritten to `$X`, which the source package never exports,
20
+ * and rolldown fails the build with `MISSING_EXPORT`. **These names
21
+ * must NEVER be renamed.**
22
+ *
23
+ * The two sets are disjoint by construction — the type-level
24
+ * `Extract<...>` assertion below fails compilation if any name appears
25
+ * in both lists. New compiler-emitted names land in whichever list
26
+ * matches their lifetime; if you accidentally add one to both, `tsc`
27
+ * tells you before the bug ships.
28
+ *
29
+ * Subpath choice matters: the helpers live at `@llui/dom/internal`, not
30
+ * at the root `@llui/dom`, because the rename regex matches any
31
+ * `__`-prefixed identifier in the bundle. By hosting the helpers on a
32
+ * subpath whose import specifier never gets touched by the rename, we
33
+ * keep both the regex and the runtime export surface internally
34
+ * consistent without needing an AST-aware rename pass.
35
+ */
36
+ export const COMPILER_RENAMEABLE_KEYS = [
37
+ '__view',
38
+ '__view$',
39
+ '__prefixes',
40
+ '__handlers',
41
+ '__compilerVersion',
42
+ '__directUpdate',
43
+ '__mask',
44
+ '__maskHi',
45
+ '__maskLegend',
46
+ '__perItem',
47
+ '__rowUpd',
48
+ '__rowUpdate',
49
+ '__schemaHash',
50
+ '__tpl',
51
+ '__msgSchema',
52
+ '__msgAnnotations',
53
+ '__bindingDescriptors',
54
+ '__stateSchema',
55
+ '__effectSchema',
56
+ '__componentMeta',
57
+ '__renderToString',
58
+ '__update',
59
+ '__dirty',
60
+ ];
61
+ export const COMPILER_DOM_INTERNAL_IMPORTS = [
62
+ '__bindUncertain',
63
+ '__cloneStaticTemplate',
64
+ '__runPhase2',
65
+ '__handleMsg',
66
+ '__registerScopeVariants',
67
+ '__clientOnlyStub',
68
+ ];
69
+ const _disjointnessProof = true;
70
+ void _disjointnessProof;
71
+ /** Module specifier the compiler emits for the internal-helper imports. */
72
+ export const DOM_INTERNAL_MODULE_SPECIFIER = '@llui/dom/internal';
73
+ //# sourceMappingURL=emit-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-names.js","sourceRoot":"","sources":["../src/emit-names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,mBAAmB;IACnB,gBAAgB;IAChB,QAAQ;IACR,UAAU;IACV,cAAc;IACd,WAAW;IACX,UAAU;IACV,aAAa;IACb,cAAc;IACd,OAAO;IACP,aAAa;IACb,kBAAkB;IAClB,sBAAsB;IACtB,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,UAAU;IACV,SAAS;CACD,CAAA;AAIV,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,iBAAiB;IACjB,uBAAuB;IACvB,aAAa;IACb,aAAa;IACb,yBAAyB;IACzB,kBAAkB;CACV,CAAA;AASV,MAAM,kBAAkB,GAA2C,IAAI,CAAA;AACvE,KAAK,kBAAkB,CAAA;AAEvB,2EAA2E;AAC3E,MAAM,CAAC,MAAM,6BAA6B,GAAG,oBAAoB,CAAA","sourcesContent":["/**\n * Single source of truth for the compiler's emission name registry.\n *\n * Two disjoint sets:\n *\n * - `COMPILER_RENAMEABLE_KEYS` — property keys the compiler synthesizes\n * onto `component({...})` literals. The runtime reads these via\n * property access (`def.__view`, `def.__prefixes`, etc.) inside the\n * same bundle that the compiler emitted them into. Their producer and\n * consumer are colocated in the bundle, so the vite-plugin's post-\n * bundle property-rename pass can shorten them to `$a`/`$b`/… without\n * breaking the contract.\n *\n * - `COMPILER_DOM_INTERNAL_IMPORTS` — runtime helpers the compiler\n * references by NAME (not by property key) via an\n * `import { __cloneStaticTemplate } from '@llui/dom/internal'`\n * declaration. These cross a module boundary at consumer build time.\n * Anything the rename pass touches that ends up in an import specifier\n * would be rewritten to `$X`, which the source package never exports,\n * and rolldown fails the build with `MISSING_EXPORT`. **These names\n * must NEVER be renamed.**\n *\n * The two sets are disjoint by construction — the type-level\n * `Extract<...>` assertion below fails compilation if any name appears\n * in both lists. New compiler-emitted names land in whichever list\n * matches their lifetime; if you accidentally add one to both, `tsc`\n * tells you before the bug ships.\n *\n * Subpath choice matters: the helpers live at `@llui/dom/internal`, not\n * at the root `@llui/dom`, because the rename regex matches any\n * `__`-prefixed identifier in the bundle. By hosting the helpers on a\n * subpath whose import specifier never gets touched by the rename, we\n * keep both the regex and the runtime export surface internally\n * consistent without needing an AST-aware rename pass.\n */\n\nexport const COMPILER_RENAMEABLE_KEYS = [\n '__view',\n '__view$',\n '__prefixes',\n '__handlers',\n '__compilerVersion',\n '__directUpdate',\n '__mask',\n '__maskHi',\n '__maskLegend',\n '__perItem',\n '__rowUpd',\n '__rowUpdate',\n '__schemaHash',\n '__tpl',\n '__msgSchema',\n '__msgAnnotations',\n '__bindingDescriptors',\n '__stateSchema',\n '__effectSchema',\n '__componentMeta',\n '__renderToString',\n '__update',\n '__dirty',\n] as const\n\nexport type CompilerRenameableKey = (typeof COMPILER_RENAMEABLE_KEYS)[number]\n\nexport const COMPILER_DOM_INTERNAL_IMPORTS = [\n '__bindUncertain',\n '__cloneStaticTemplate',\n '__runPhase2',\n '__handleMsg',\n '__registerScopeVariants',\n '__clientOnlyStub',\n] as const\n\nexport type CompilerDomInternalImport = (typeof COMPILER_DOM_INTERNAL_IMPORTS)[number]\n\n// Compile-time proof that the two sets are disjoint. If any name appears\n// in both lists, `Extract<...>` resolves to that name's string literal\n// instead of `never`, and the assignment fails. Move the offending name\n// to one list or the other; never both.\ntype _Disjoint = Extract<CompilerRenameableKey, CompilerDomInternalImport>\nconst _disjointnessProof: _Disjoint extends never ? true : false = true\nvoid _disjointnessProof\n\n/** Module specifier the compiler emits for the internal-helper imports. */\nexport const DOM_INTERNAL_MODULE_SPECIFIER = '@llui/dom/internal'\n"]}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './emit-names.js';
1
2
  export * from './accessor-resolver.js';
2
3
  export * from './binding-descriptors.js';
3
4
  export * from './collect-deps.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,4BAA4B,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AASzD,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,oBAAoB,EACpB,KAAK,2BAA2B,GACjC,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,GACxB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AACzF,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,GACvB,MAAM,6BAA6B,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,4BAA4B,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AASzD,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,oBAAoB,EACpB,KAAK,2BAA2B,GACjC,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,GACxB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AACzF,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,GACvB,MAAM,6BAA6B,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // @llui/compiler — engine. Adapters consume through these re-exports.
2
2
  // Migration in progress (see docs/proposals/v2-compiler/v2a.md §4.4).
3
+ export * from './emit-names.js';
3
4
  export * from './accessor-resolver.js';
4
5
  export * from './binding-descriptors.js';
5
6
  export * from './collect-deps.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,sEAAsE;AACtE,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,4BAA4B,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,wEAAwE;AACxE,2EAA2E;AAC3E,uEAAuE;AACvE,oEAAoE;AACpE,wEAAwE;AACxE,qEAAqE;AACrE,6BAA6B;AAC7B,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAgC,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EACL,cAAc,EACd,cAAc,GAGf,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,oBAAoB,GAErB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,cAAc,EAA8B,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,eAAe,EAA+B,MAAM,yBAAyB,CAAA;AACtF,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAGrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,gBAAgB,EAAgC,MAAM,0BAA0B,CAAA;AACzF,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,6BAA6B,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA","sourcesContent":["// @llui/compiler — engine. Adapters consume through these re-exports.\n// Migration in progress (see docs/proposals/v2-compiler/v2a.md §4.4).\nexport * from './accessor-resolver.js'\nexport * from './binding-descriptors.js'\nexport * from './collect-deps.js'\nexport * from './compiler-cache.js'\nexport * from './cross-file-resolver.js'\nexport * from './cross-file-walker.js'\nexport * from './diagnostic.js'\nexport * from './manifest.js'\nexport * from './module.js'\nexport * from './version.js'\nexport * from './introspection-factory.js'\nexport { findComponentCalls } from './modules/_shared.js'\n// Introspection modules (schemaHashModule, msg-schema, msg-annotations,\n// state-schema, binding-descriptors) moved to @llui/compiler-introspection\n// in v2c/decomp-26. Adapters that previously imported these names from\n// @llui/compiler must now import from @llui/compiler-introspection.\n// BINDING_DESCRIPTORS_SLOT is re-exported from introspection-factory.js\n// (above) so the orchestrator can read the slot without depending on\n// the introspection package.\n// componentMetaModule moved to @llui/compiler-devtools (v2c/decomp-27).\nexport { maskLegendModule, type MaskLegendModuleOptions } from './modules/mask-legend.js'\nexport { compilerStampModule } from './modules/compiler-stamp.js'\nexport {\n eachMemoModule,\n EACH_MEMO_SLOT,\n type EachMemoModuleOptions,\n type EachMemoSlot,\n} from './modules/each-memo.js'\nexport {\n structuralMaskModule,\n type StructuralMaskModuleOptions,\n} from './modules/structural-mask.js'\nexport { textMaskModule, type TextMaskModuleOptions } from './modules/text-mask.js'\nexport { itemDedupModule, type ItemDedupModuleOptions } from './modules/item-dedup.js'\nexport {\n elementRewriteModule,\n ELEMENT_REWRITE_SLOT,\n type ElementRewriteModuleOptions,\n type ElementRewriteSlot,\n} from './modules/element-rewrite.js'\nexport { rowFactoryModule, type RowFactoryModuleOptions } from './modules/row-factory.js'\nexport {\n coreSynthesisModule,\n CORE_SYNTHESIS_SLOT,\n type CoreSynthesisModuleOptions,\n type CoreSynthesisSlot,\n} from './modules/core-synthesis.js'\nexport * from './msg-annotations.js'\nexport * from './msg-schema.js'\nexport * from './schema-hash.js'\nexport * from './state-schema.js'\nexport * from './transform.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,sEAAsE;AACtE,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,4BAA4B,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,wEAAwE;AACxE,2EAA2E;AAC3E,uEAAuE;AACvE,oEAAoE;AACpE,wEAAwE;AACxE,qEAAqE;AACrE,6BAA6B;AAC7B,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAgC,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EACL,cAAc,EACd,cAAc,GAGf,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,oBAAoB,GAErB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,cAAc,EAA8B,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,eAAe,EAA+B,MAAM,yBAAyB,CAAA;AACtF,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAGrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,gBAAgB,EAAgC,MAAM,0BAA0B,CAAA;AACzF,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,6BAA6B,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA","sourcesContent":["// @llui/compiler — engine. Adapters consume through these re-exports.\n// Migration in progress (see docs/proposals/v2-compiler/v2a.md §4.4).\nexport * from './emit-names.js'\nexport * from './accessor-resolver.js'\nexport * from './binding-descriptors.js'\nexport * from './collect-deps.js'\nexport * from './compiler-cache.js'\nexport * from './cross-file-resolver.js'\nexport * from './cross-file-walker.js'\nexport * from './diagnostic.js'\nexport * from './manifest.js'\nexport * from './module.js'\nexport * from './version.js'\nexport * from './introspection-factory.js'\nexport { findComponentCalls } from './modules/_shared.js'\n// Introspection modules (schemaHashModule, msg-schema, msg-annotations,\n// state-schema, binding-descriptors) moved to @llui/compiler-introspection\n// in v2c/decomp-26. Adapters that previously imported these names from\n// @llui/compiler must now import from @llui/compiler-introspection.\n// BINDING_DESCRIPTORS_SLOT is re-exported from introspection-factory.js\n// (above) so the orchestrator can read the slot without depending on\n// the introspection package.\n// componentMetaModule moved to @llui/compiler-devtools (v2c/decomp-27).\nexport { maskLegendModule, type MaskLegendModuleOptions } from './modules/mask-legend.js'\nexport { compilerStampModule } from './modules/compiler-stamp.js'\nexport {\n eachMemoModule,\n EACH_MEMO_SLOT,\n type EachMemoModuleOptions,\n type EachMemoSlot,\n} from './modules/each-memo.js'\nexport {\n structuralMaskModule,\n type StructuralMaskModuleOptions,\n} from './modules/structural-mask.js'\nexport { textMaskModule, type TextMaskModuleOptions } from './modules/text-mask.js'\nexport { itemDedupModule, type ItemDedupModuleOptions } from './modules/item-dedup.js'\nexport {\n elementRewriteModule,\n ELEMENT_REWRITE_SLOT,\n type ElementRewriteModuleOptions,\n type ElementRewriteSlot,\n} from './modules/element-rewrite.js'\nexport { rowFactoryModule, type RowFactoryModuleOptions } from './modules/row-factory.js'\nexport {\n coreSynthesisModule,\n CORE_SYNTHESIS_SLOT,\n type CoreSynthesisModuleOptions,\n type CoreSynthesisSlot,\n} from './modules/core-synthesis.js'\nexport * from './msg-annotations.js'\nexport * from './msg-schema.js'\nexport * from './schema-hash.js'\nexport * from './state-schema.js'\nexport * from './transform.js'\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"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"}
package/dist/transform.js CHANGED
@@ -718,6 +718,20 @@ export function transformLlui(source, _filename, devMode = false, emitAgentMetad
718
718
  ? generateDevCode(componentDecls, mcpPort)
719
719
  : { top: '', bottom: '' };
720
720
  let output = (_top ? _top + '\n' : '') + printer.printFile(transformed) + (_bottom ? '\n' + _bottom : '');
721
+ // Inject the `@llui/dom/internal` import on the fallback path too.
722
+ // The per-statement edit loop (where the normal injection lives)
723
+ // never ran to completion in this branch, so do it inline.
724
+ const internalEditFb = buildInternalImportEdit(lluiImport, usesBindUncertain, usesCloneStaticTemplate, usesApplyBinding, scopeRegistrationsInjected);
725
+ if (internalEditFb) {
726
+ // Place right after the public `@llui/dom` import in the
727
+ // printed output. The printer normalizes the import to a
728
+ // single line; locate it by string match.
729
+ const m = output.match(/import\s*\{[^}]*\}\s*from\s*['"]@llui\/dom['"];?\n/);
730
+ if (m && m.index !== undefined) {
731
+ const insertAt = m.index + m[0].length;
732
+ output = output.slice(0, insertAt) + internalEditFb.replacement + output.slice(insertAt);
733
+ }
734
+ }
721
735
  if (devMode || emitAgentMetadata) {
722
736
  output = appendCompilerCacheProps(output, componentDecls);
723
737
  }
@@ -738,6 +752,14 @@ export function transformLlui(source, _filename, devMode = false, emitAgentMetad
738
752
  finalEdits.push({ start: origStart, end: origEnd, replacement });
739
753
  }
740
754
  }
755
+ // Compiler-emitted internal helpers ride on `@llui/dom/internal`,
756
+ // not on the public `@llui/dom` barrel. Insert the import as a
757
+ // text-level edit (not an AST statement) so it doesn't disturb the
758
+ // origin↔transformed index pairing the per-statement diff relies on.
759
+ // See cleanupImports' NOTE and buildInternalImportEdit's docstring.
760
+ const internalEdit = buildInternalImportEdit(lluiImport, usesBindUncertain, usesCloneStaticTemplate, usesApplyBinding, scopeRegistrationsInjected);
761
+ if (internalEdit)
762
+ finalEdits.push(internalEdit);
741
763
  // Dev setup: enable* must run BEFORE user's mountApp (top of file),
742
764
  // but import.meta.hot.accept needs to reference user's component vars
743
765
  // (bottom of file). So split the injection.
@@ -976,12 +998,19 @@ const VIEW_BAG_FIELD_TO_PRIMITIVE = {
976
998
  * Idempotent — returns `call` unchanged when:
977
999
  * • the config arg is not an object literal
978
1000
  * • no `view:` property exists, or its value is not an arrow/function
979
- * • the view's first parameter is not an ObjectBindingPattern
980
1001
  * • the config arg already has a `__view` property (re-run safety)
981
1002
  *
982
1003
  * Bag fields that aren't in `VIEW_BAG_FIELD_TO_PRIMITIVE` (e.g. unknown
983
- * names from a user-typed View extension) are skipped so the runtime falls
984
- * back to `createView` for any access to them.
1004
+ * names from a user-typed View extension) are skipped the runtime
1005
+ * cannot fabricate them, so accessing them at runtime is the user's
1006
+ * problem (matches dev-mode behavior).
1007
+ *
1008
+ * Identifier-style view params (`view: (h) => ...` or `view: (send) => ...`)
1009
+ * can't be statically narrowed to a known subset of primitives — `h` may
1010
+ * be passed to helpers, destructured later, or read dynamically. For
1011
+ * those we emit `__view: ($send) => createView($send)` so the runtime
1012
+ * gets the full bag. The instance-level `_viewBag` cache on
1013
+ * `getInstanceViewBag` means this is still one allocation per mount.
985
1014
  */
986
1015
  function injectViewBag(call, needed, f) {
987
1016
  const configArg = call.arguments[0];
@@ -1008,51 +1037,67 @@ function injectViewBag(call, needed, f) {
1008
1037
  }
1009
1038
  if (!viewFn)
1010
1039
  return call;
1011
- // Inspect the first parameter — must be an ObjectBindingPattern.
1012
- const firstParam = viewFn.parameters[0];
1013
- if (!firstParam || !ts.isObjectBindingPattern(firstParam.name))
1014
- return call;
1015
- const entries = [];
1016
- for (const elem of firstParam.name.elements) {
1017
- const localName = ts.isIdentifier(elem.name) ? elem.name.text : null;
1018
- const sourceName = elem.propertyName && ts.isIdentifier(elem.propertyName) ? elem.propertyName.text : localName;
1019
- if (!localName || !sourceName)
1020
- continue;
1021
- if (sourceName === 'send') {
1022
- entries.push({ localName, primitive: null });
1023
- continue;
1024
- }
1025
- const primitive = VIEW_BAG_FIELD_TO_PRIMITIVE[sourceName];
1026
- if (!primitive)
1027
- continue; // unknown name — let the runtime fail at runtime if accessed
1028
- entries.push({ localName, primitive });
1029
- }
1030
- if (entries.length === 0)
1031
- return call;
1032
- // Synthesize: __view: ($send) => ({ localA: $send, localB: text, localC: each, ... })
1033
- // We use a fixed parameter name `$send` to avoid shadowing — the bag
1034
- // entries that map to send use this identifier.
1035
1040
  const sendParamName = f.createIdentifier('$send');
1036
- const bagProps = [];
1037
- for (const e of entries) {
1038
- if (e.primitive === null) {
1039
- // local name send parameter
1040
- bagProps.push(e.localName === '$send'
1041
- ? f.createShorthandPropertyAssignment(sendParamName)
1042
- : f.createPropertyAssignment(f.createIdentifier(e.localName), sendParamName));
1043
- }
1044
- else if (e.localName === e.primitive) {
1045
- bagProps.push(f.createShorthandPropertyAssignment(f.createIdentifier(e.localName)));
1046
- needed.add(e.primitive);
1041
+ // Build the __view factory body. Two shapes:
1042
+ //
1043
+ // Destructured param — `view: ({ send, text, each }) => ...`
1044
+ // emit `__view: ($send) => ({ send: $send, text, each })`
1045
+ // (tree-shakes unused primitives — the Tier 1.2 size cut).
1046
+ //
1047
+ // Identifier / no param — `view: (h) => ...`, `view: () => ...`,
1048
+ // `view: (send) => ...`, etc.
1049
+ // emit `__view: ($send) => createView($send)`
1050
+ // The compiler can't see which fields `h` is accessed on (it
1051
+ // may be passed to a helper, destructured later, read by
1052
+ // name dynamically). Full bag, instance-cached.
1053
+ const firstParam = viewFn.parameters[0];
1054
+ const isDestructured = !!firstParam && ts.isObjectBindingPattern(firstParam.name);
1055
+ let factoryBody;
1056
+ if (isDestructured) {
1057
+ const entries = [];
1058
+ for (const elem of firstParam.name.elements) {
1059
+ const localName = ts.isIdentifier(elem.name) ? elem.name.text : null;
1060
+ const sourceName = elem.propertyName && ts.isIdentifier(elem.propertyName) ? elem.propertyName.text : localName;
1061
+ if (!localName || !sourceName)
1062
+ continue;
1063
+ if (sourceName === 'send') {
1064
+ entries.push({ localName, primitive: null });
1065
+ continue;
1066
+ }
1067
+ const primitive = VIEW_BAG_FIELD_TO_PRIMITIVE[sourceName];
1068
+ if (!primitive)
1069
+ continue; // unknown name — accessing it at runtime is the user's problem
1070
+ entries.push({ localName, primitive });
1047
1071
  }
1048
- else {
1049
- bagProps.push(f.createPropertyAssignment(f.createIdentifier(e.localName), f.createIdentifier(e.primitive)));
1050
- needed.add(e.primitive);
1072
+ const bagProps = [];
1073
+ for (const e of entries) {
1074
+ if (e.primitive === null) {
1075
+ bagProps.push(e.localName === '$send'
1076
+ ? f.createShorthandPropertyAssignment(sendParamName)
1077
+ : f.createPropertyAssignment(f.createIdentifier(e.localName), sendParamName));
1078
+ }
1079
+ else if (e.localName === e.primitive) {
1080
+ bagProps.push(f.createShorthandPropertyAssignment(f.createIdentifier(e.localName)));
1081
+ needed.add(e.primitive);
1082
+ }
1083
+ else {
1084
+ bagProps.push(f.createPropertyAssignment(f.createIdentifier(e.localName), f.createIdentifier(e.primitive)));
1085
+ needed.add(e.primitive);
1086
+ }
1051
1087
  }
1088
+ factoryBody = f.createParenthesizedExpression(f.createObjectLiteralExpression(bagProps, false));
1089
+ }
1090
+ else {
1091
+ // Identifier-style or zero-arg view: emit `createView($send)` and
1092
+ // pull `createView` into the file imports via cleanupImports.
1093
+ needed.add('createView');
1094
+ factoryBody = f.createCallExpression(f.createIdentifier('createView'), undefined, [
1095
+ sendParamName,
1096
+ ]);
1052
1097
  }
1053
1098
  const viewBagFactory = f.createArrowFunction(undefined, undefined, [
1054
1099
  f.createParameterDeclaration(undefined, undefined, sendParamName, undefined, undefined, undefined),
1055
- ], undefined, f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), f.createParenthesizedExpression(f.createObjectLiteralExpression(bagProps, false)));
1100
+ ], undefined, f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factoryBody);
1056
1101
  const newConfig = f.createObjectLiteralExpression([...configArg.properties, f.createPropertyAssignment('__view', viewBagFactory)], true);
1057
1102
  return f.createCallExpression(call.expression, call.typeArguments, [
1058
1103
  newConfig,
@@ -1181,50 +1226,37 @@ function cleanupImports(sf, lluiImport, _helpers, compiled, usesElSplit, usesElT
1181
1226
  const clause = lluiImport.importClause;
1182
1227
  if (!clause?.namedBindings || !ts.isNamedImports(clause.namedBindings))
1183
1228
  return sf;
1184
- const remaining = clause.namedBindings.elements.filter((spec) => !compiled.has(spec.name.text));
1185
- const hasElSplit = clause.namedBindings.elements.some((s) => s.name.text === 'elSplit');
1186
- if (!hasElSplit && usesElSplit) {
1187
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('elSplit')));
1188
- }
1189
- const hasBindUncertain = clause.namedBindings.elements.some((s) => s.name.text === '__bindUncertain');
1190
- if (!hasBindUncertain && usesBindUncertain) {
1191
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('__bindUncertain')));
1192
- }
1193
- const hasElTemplate = clause.namedBindings.elements.some((s) => s.name.text === 'elTemplate');
1194
- if (!hasElTemplate && usesElTemplate) {
1195
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('elTemplate')));
1196
- }
1197
- const hasCloneStaticTemplate = clause.namedBindings.elements.some((s) => s.name.text === '__cloneStaticTemplate');
1198
- if (!hasCloneStaticTemplate && usesCloneStaticTemplate) {
1199
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('__cloneStaticTemplate')));
1200
- }
1201
- const hasMemo = clause.namedBindings.elements.some((s) => s.name.text === 'memo');
1202
- if (!hasMemo && usesMemo) {
1203
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('memo')));
1204
- }
1205
- if (usesApplyBinding) {
1206
- if (!clause.namedBindings.elements.some((s) => s.name.text === '__runPhase2')) {
1207
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('__runPhase2')));
1208
- }
1209
- if (!clause.namedBindings.elements.some((s) => s.name.text === '__handleMsg')) {
1210
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('__handleMsg')));
1229
+ // Public-surface imports stay on `from '@llui/dom'`. Compiler-emitted
1230
+ // runtime helpers go on a separate `from '@llui/dom/internal'`
1231
+ // declaration so the vite-plugin's post-bundle property-rename pass
1232
+ // never rewrites an import specifier against a public export name.
1233
+ // See emit-names.ts § COMPILER_DOM_INTERNAL_IMPORTS for the contract.
1234
+ const namedBindings = clause.namedBindings;
1235
+ const remaining = namedBindings.elements.filter((spec) => !compiled.has(spec.name.text));
1236
+ const publicHas = (name) => remaining.some((s) => s.name.text === name) ||
1237
+ namedBindings.elements.some((s) => s.name.text === name);
1238
+ const addPublic = (name) => {
1239
+ if (!publicHas(name)) {
1240
+ remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier(name)));
1211
1241
  }
1212
- }
1213
- // The connect-pattern injector (binding-descriptors.ts) emits
1214
- // `__registerScopeVariants([...])` calls; ensure the runtime
1215
- // helper is imported when at least one was inserted.
1216
- const hasRegisterScopeVariants = clause.namedBindings.elements.some((s) => s.name.text === '__registerScopeVariants');
1217
- if (!hasRegisterScopeVariants && usesRegisterScopeVariants) {
1218
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier('__registerScopeVariants')));
1219
- }
1220
- // v0.4 size-cut (Tier 1.2): add @llui/dom imports for each primitive
1221
- // referenced by synthesized __view factories. `ctx` is the destructured
1222
- // bag name; its primitive is `useContext` (the only rename pair).
1223
- for (const prim of viewBagPrimitivesNeeded) {
1224
- if (!clause.namedBindings.elements.some((s) => s.name.text === prim)) {
1225
- remaining.push(f.createImportSpecifier(false, undefined, f.createIdentifier(prim)));
1226
- }
1227
- }
1242
+ };
1243
+ if (usesElSplit)
1244
+ addPublic('elSplit');
1245
+ if (usesElTemplate)
1246
+ addPublic('elTemplate');
1247
+ if (usesMemo)
1248
+ addPublic('memo');
1249
+ for (const prim of viewBagPrimitivesNeeded)
1250
+ addPublic(prim);
1251
+ // NOTE: the compiler-emitted internal helpers (`__bindUncertain`,
1252
+ // `__cloneStaticTemplate`, `__runPhase2`, `__handleMsg`,
1253
+ // `__registerScopeVariants`) are NOT added here. They live on
1254
+ // `@llui/dom/internal`, and the outer transform pipeline inserts a
1255
+ // separate `from '@llui/dom/internal'` import via a text-level edit
1256
+ // (see `buildInternalImportEdit`). Inserting a new ImportDeclaration
1257
+ // here would break the caller's per-statement origin↔transformed
1258
+ // index pairing — the statement count would change and trailing
1259
+ // statements would silently drop out of the edit list.
1228
1260
  const newBindings = f.createNamedImports(remaining);
1229
1261
  // New TS 6 signature: first arg is `phaseModifier` (undefined =
1230
1262
  // regular import; `ts.SyntaxKind.TypeKeyword` = `import type`).
@@ -1238,8 +1270,7 @@ function cleanupImports(sf, lluiImport, _helpers, compiled, usesElSplit, usesElT
1238
1270
  ts.isStringLiteral(stmt.moduleSpecifier) &&
1239
1271
  stmt.moduleSpecifier.text === '@llui/dom' &&
1240
1272
  // `phaseModifier === ts.SyntaxKind.TypeKeyword` is `import type
1241
- // …`; we only want to rewrite value imports. Replaces deprecated
1242
- // `isTypeOnly` from the TS<6 API.
1273
+ // …`; we only want to rewrite value imports.
1243
1274
  stmt.importClause?.phaseModifier !== ts.SyntaxKind.TypeKeyword) {
1244
1275
  replaced = true;
1245
1276
  return newImportDecl;
@@ -1248,6 +1279,40 @@ function cleanupImports(sf, lluiImport, _helpers, compiled, usesElSplit, usesElT
1248
1279
  });
1249
1280
  return f.updateSourceFile(sf, statements);
1250
1281
  }
1282
+ /**
1283
+ * Build a single text-insert edit that places
1284
+ * `import { ... } from '@llui/dom/internal'` immediately after the
1285
+ * existing `import { ... } from '@llui/dom'` statement (or appends it
1286
+ * at the start of the file if no @llui/dom import is found, though
1287
+ * the caller has already short-circuited in that case).
1288
+ *
1289
+ * Returns null when no internal helpers are needed. The edit is text-
1290
+ * level (not AST) so it does NOT alter `transformed.statements.length`,
1291
+ * keeping the per-statement origin↔transformed pairing intact.
1292
+ */
1293
+ function buildInternalImportEdit(lluiImport, usesBindUncertain, usesCloneStaticTemplate, usesApplyBinding, usesRegisterScopeVariants) {
1294
+ const names = new Set();
1295
+ if (usesBindUncertain)
1296
+ names.add('__bindUncertain');
1297
+ if (usesCloneStaticTemplate)
1298
+ names.add('__cloneStaticTemplate');
1299
+ if (usesApplyBinding) {
1300
+ names.add('__runPhase2');
1301
+ names.add('__handleMsg');
1302
+ }
1303
+ if (usesRegisterScopeVariants)
1304
+ names.add('__registerScopeVariants');
1305
+ if (names.size === 0)
1306
+ return null;
1307
+ const sortedNames = [...names].sort();
1308
+ const importLine = `import { ${sortedNames.join(', ')} } from '@llui/dom/internal'\n`;
1309
+ const insertAt = lluiImport.getEnd();
1310
+ // The lluiImport's getEnd() points to the position right after the
1311
+ // statement's trailing `;` or `'\n'`. Emit the new import on a fresh
1312
+ // line — `\n` prefix guarantees that even if the original import had
1313
+ // no trailing newline.
1314
+ return { start: insertAt, end: insertAt, replacement: '\n' + importLine };
1315
+ }
1251
1316
  // ── __msgSchema injection ────────────────────────────────────────
1252
1317
  // `injectStateSchema` was the inline emitter for `__stateSchema`.
1253
1318
  // Migrated to `stateSchemaModule` + the registry bridge (v2c/decomp-3).