@analogjs/vite-plugin-angular 3.0.0-alpha.4 → 3.0.0-alpha.41

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.
Files changed (168) hide show
  1. package/README.md +28 -0
  2. package/migrations/migrate-setup-vitest/migrate-setup-vitest.d.ts +2 -0
  3. package/migrations/migrate-setup-vitest/migrate-setup-vitest.js +49 -0
  4. package/migrations/migrate-setup-vitest/migrate-setup-vitest.js.map +1 -0
  5. package/migrations/migration.json +7 -1
  6. package/migrations/migrations.json +9 -0
  7. package/migrations/update-3-0-0/migrate-setup-vitest.d.ts +2 -0
  8. package/migrations/update-3-0-0/migrate-setup-vitest.js +36 -0
  9. package/migrations/update-3-0-0/migrate-setup-vitest.js.map +1 -0
  10. package/package.json +25 -12
  11. package/src/index.d.ts +3 -2
  12. package/src/index.js +6 -2
  13. package/src/index.js.map +1 -1
  14. package/src/lib/angular-build-optimizer-plugin.d.ts +4 -4
  15. package/src/lib/angular-build-optimizer-plugin.js +48 -62
  16. package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
  17. package/src/lib/angular-jit-plugin.d.ts +3 -3
  18. package/src/lib/angular-jit-plugin.js +42 -37
  19. package/src/lib/angular-jit-plugin.js.map +1 -1
  20. package/src/lib/angular-pending-tasks.plugin.d.ts +7 -7
  21. package/src/lib/angular-pending-tasks.plugin.js +17 -18
  22. package/src/lib/angular-pending-tasks.plugin.js.map +1 -1
  23. package/src/lib/angular-vite-plugin.d.ts +250 -40
  24. package/src/lib/angular-vite-plugin.js +2216 -964
  25. package/src/lib/angular-vite-plugin.js.map +1 -1
  26. package/src/lib/angular-vitest-plugin.d.ts +19 -15
  27. package/src/lib/angular-vitest-plugin.js +99 -114
  28. package/src/lib/angular-vitest-plugin.js.map +1 -1
  29. package/src/lib/compiler/angular-version.d.ts +19 -0
  30. package/src/lib/compiler/angular-version.js +16 -0
  31. package/src/lib/compiler/angular-version.js.map +1 -0
  32. package/src/lib/compiler/class-field-lowering.d.ts +23 -0
  33. package/src/lib/compiler/class-field-lowering.js +131 -0
  34. package/src/lib/compiler/class-field-lowering.js.map +1 -0
  35. package/src/lib/compiler/compile.d.ts +44 -0
  36. package/src/lib/compiler/compile.js +731 -0
  37. package/src/lib/compiler/compile.js.map +1 -0
  38. package/src/lib/compiler/constants.d.ts +18 -0
  39. package/src/lib/compiler/constants.js +52 -0
  40. package/src/lib/compiler/constants.js.map +1 -0
  41. package/src/lib/compiler/debug.d.ts +22 -0
  42. package/src/lib/compiler/debug.js +20 -0
  43. package/src/lib/compiler/debug.js.map +1 -0
  44. package/src/lib/compiler/defer.d.ts +47 -0
  45. package/src/lib/compiler/defer.js +138 -0
  46. package/src/lib/compiler/defer.js.map +1 -0
  47. package/src/lib/compiler/dts-reader.d.ts +35 -0
  48. package/src/lib/compiler/dts-reader.js +365 -0
  49. package/src/lib/compiler/dts-reader.js.map +1 -0
  50. package/src/lib/compiler/hmr.d.ts +16 -0
  51. package/src/lib/compiler/hmr.js +69 -0
  52. package/src/lib/compiler/hmr.js.map +1 -0
  53. package/src/lib/compiler/index.d.ts +7 -0
  54. package/src/lib/compiler/index.js +7 -0
  55. package/src/lib/compiler/jit-metadata.d.ts +14 -0
  56. package/src/lib/compiler/jit-metadata.js +146 -0
  57. package/src/lib/compiler/jit-metadata.js.map +1 -0
  58. package/src/lib/compiler/jit-transform.d.ts +24 -0
  59. package/src/lib/compiler/jit-transform.js +200 -0
  60. package/src/lib/compiler/jit-transform.js.map +1 -0
  61. package/src/lib/compiler/js-emitter.d.ts +10 -0
  62. package/src/lib/compiler/js-emitter.js +420 -0
  63. package/src/lib/compiler/js-emitter.js.map +1 -0
  64. package/src/lib/compiler/metadata.d.ts +45 -0
  65. package/src/lib/compiler/metadata.js +633 -0
  66. package/src/lib/compiler/metadata.js.map +1 -0
  67. package/src/lib/compiler/registry.d.ts +49 -0
  68. package/src/lib/compiler/registry.js +164 -0
  69. package/src/lib/compiler/registry.js.map +1 -0
  70. package/src/lib/compiler/resource-inliner.d.ts +21 -0
  71. package/src/lib/compiler/resource-inliner.js +152 -0
  72. package/src/lib/compiler/resource-inliner.js.map +1 -0
  73. package/src/lib/compiler/style-ast.d.ts +8 -0
  74. package/src/lib/compiler/style-ast.js +54 -0
  75. package/src/lib/compiler/style-ast.js.map +1 -0
  76. package/src/lib/compiler/styles.d.ts +13 -0
  77. package/src/lib/compiler/test-helpers.d.ts +7 -0
  78. package/src/lib/compiler/type-elision.d.ts +26 -0
  79. package/src/lib/compiler/type-elision.js +211 -0
  80. package/src/lib/compiler/type-elision.js.map +1 -0
  81. package/src/lib/compiler/utils.d.ts +10 -0
  82. package/src/lib/compiler/utils.js +35 -0
  83. package/src/lib/compiler/utils.js.map +1 -0
  84. package/src/lib/compiler-plugin.d.ts +11 -11
  85. package/src/lib/compiler-plugin.js +43 -44
  86. package/src/lib/compiler-plugin.js.map +1 -1
  87. package/src/lib/component-resolvers.d.ts +23 -5
  88. package/src/lib/component-resolvers.js +153 -63
  89. package/src/lib/component-resolvers.js.map +1 -1
  90. package/src/lib/fast-compile-plugin.d.ts +14 -0
  91. package/src/lib/fast-compile-plugin.js +270 -0
  92. package/src/lib/fast-compile-plugin.js.map +1 -0
  93. package/src/lib/host.d.ts +10 -8
  94. package/src/lib/host.js +113 -101
  95. package/src/lib/host.js.map +1 -1
  96. package/src/lib/live-reload-plugin.d.ts +5 -5
  97. package/src/lib/live-reload-plugin.js +61 -62
  98. package/src/lib/live-reload-plugin.js.map +1 -1
  99. package/src/lib/models.d.ts +9 -9
  100. package/src/lib/nx-folder-plugin.d.ts +5 -5
  101. package/src/lib/nx-folder-plugin.js +18 -16
  102. package/src/lib/nx-folder-plugin.js.map +1 -1
  103. package/src/lib/plugins/file-replacements.plugin.d.ts +4 -4
  104. package/src/lib/plugins/file-replacements.plugin.js +40 -62
  105. package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
  106. package/src/lib/router-plugin.d.ts +1 -1
  107. package/src/lib/router-plugin.js +23 -23
  108. package/src/lib/router-plugin.js.map +1 -1
  109. package/src/lib/style-pipeline.d.ts +15 -0
  110. package/src/lib/style-pipeline.js +31 -0
  111. package/src/lib/style-pipeline.js.map +1 -0
  112. package/src/lib/style-preprocessor.d.ts +35 -0
  113. package/src/lib/style-preprocessor.js +35 -0
  114. package/src/lib/style-preprocessor.js.map +1 -0
  115. package/src/lib/stylesheet-registry.d.ts +73 -0
  116. package/src/lib/stylesheet-registry.js +168 -0
  117. package/src/lib/stylesheet-registry.js.map +1 -0
  118. package/src/lib/tools/package.json +2 -7
  119. package/src/lib/tools/src/builders/vite/vite-build.impl.js +31 -38
  120. package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
  121. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +51 -62
  122. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
  123. package/src/lib/tools/src/index.js +0 -2
  124. package/src/lib/utils/compiler-plugin-options.d.ts +11 -11
  125. package/src/lib/utils/debug-harness.d.ts +23 -0
  126. package/src/lib/utils/debug-harness.js +88 -0
  127. package/src/lib/utils/debug-harness.js.map +1 -0
  128. package/src/lib/utils/debug-log-file.d.ts +5 -0
  129. package/src/lib/utils/debug-log-file.js +56 -0
  130. package/src/lib/utils/debug-log-file.js.map +1 -0
  131. package/src/lib/utils/debug.d.ts +28 -0
  132. package/src/lib/utils/debug.js +39 -0
  133. package/src/lib/utils/debug.js.map +1 -0
  134. package/src/lib/utils/devkit.d.ts +6 -6
  135. package/src/lib/utils/devkit.js +34 -38
  136. package/src/lib/utils/devkit.js.map +1 -1
  137. package/src/lib/utils/hmr-candidates.d.ts +28 -28
  138. package/src/lib/utils/plugin-config.d.ts +30 -0
  139. package/src/lib/utils/plugin-config.js +64 -0
  140. package/src/lib/utils/plugin-config.js.map +1 -0
  141. package/src/lib/utils/rolldown.d.ts +2 -0
  142. package/src/lib/utils/rolldown.js +12 -0
  143. package/src/lib/utils/rolldown.js.map +1 -0
  144. package/src/lib/utils/source-file-cache.d.ts +8 -15
  145. package/src/lib/utils/source-file-cache.js +35 -37
  146. package/src/lib/utils/source-file-cache.js.map +1 -1
  147. package/src/lib/utils/tailwind-reference.d.ts +12 -0
  148. package/src/lib/utils/tailwind-reference.js +99 -0
  149. package/src/lib/utils/tailwind-reference.js.map +1 -0
  150. package/src/lib/utils/virtual-ids.d.ts +8 -0
  151. package/src/lib/utils/virtual-ids.js +35 -0
  152. package/src/lib/utils/virtual-ids.js.map +1 -0
  153. package/src/lib/utils/virtual-resources.d.ts +47 -0
  154. package/src/lib/utils/virtual-resources.js +89 -0
  155. package/src/lib/utils/virtual-resources.js.map +1 -0
  156. package/src/test-setup.d.ts +2 -0
  157. package/setup-vitest.d.ts +0 -4
  158. package/setup-vitest.js +0 -215
  159. package/setup-vitest.js.map +0 -1
  160. package/src/lib/models.js +0 -1
  161. package/src/lib/models.js.map +0 -1
  162. package/src/lib/tools/README.md +0 -3
  163. package/src/lib/tools/src/index.d.ts +0 -0
  164. package/src/lib/tools/src/index.js.map +0 -1
  165. package/src/lib/utils/compiler-plugin-options.js +0 -1
  166. package/src/lib/utils/compiler-plugin-options.js.map +0 -1
  167. package/src/lib/utils/hmr-candidates.js +0 -272
  168. package/src/lib/utils/hmr-candidates.js.map +0 -1
@@ -0,0 +1,365 @@
1
+ import * as fs from "node:fs";
2
+ import * as path$1 from "node:path";
3
+ import { parseSync } from "oxc-parser";
4
+ //#region packages/vite-plugin-angular/src/lib/compiler/dts-reader.ts
5
+ /**
6
+ * Scan a single .d.ts file and extract Angular directive/component/pipe
7
+ * metadata from the static ɵdir / ɵcmp / ɵpipe type declarations.
8
+ *
9
+ * This mirrors what ngtsc's DtsMetadataReader does: it reads the type
10
+ * parameters of ɵɵDirectiveDeclaration / ɵɵComponentDeclaration /
11
+ * ɵɵPipeDeclaration to discover selectors, inputs, and outputs for
12
+ * pre-compiled Angular packages.
13
+ */
14
+ function scanDtsFile(code, fileName) {
15
+ if (!code.includes("DirectiveDeclaration") && !code.includes("ComponentDeclaration") && !code.includes("PipeDeclaration") && !code.includes("NgModuleDeclaration")) return [];
16
+ const { program } = parseSync(fileName, code);
17
+ const entries = [];
18
+ visitStatements(program.body, fileName, entries);
19
+ return entries;
20
+ }
21
+ /**
22
+ * Resolve a package's directory in node_modules, scan all its .d.ts files,
23
+ * and return RegistryEntry[] for every Angular declaration found.
24
+ *
25
+ * @param packageName e.g. "@angular/router"
26
+ * @param basePath project root (where node_modules lives)
27
+ */
28
+ function scanPackageDts(packageName, basePath) {
29
+ let pkgDir = "";
30
+ let searchBase = basePath;
31
+ while (searchBase !== path$1.dirname(searchBase)) {
32
+ const candidate = path$1.join(searchBase, "node_modules", packageName);
33
+ if (fs.existsSync(candidate)) {
34
+ pkgDir = candidate;
35
+ break;
36
+ }
37
+ searchBase = path$1.dirname(searchBase);
38
+ }
39
+ if (!pkgDir) return [];
40
+ const classToImportPath = buildClassToImportMap(packageName, pkgDir);
41
+ const typesDir = path$1.join(pkgDir, "types");
42
+ const dtsFiles = collectDtsFiles(fs.existsSync(typesDir) ? typesDir : pkgDir);
43
+ const entries = [];
44
+ for (const file of dtsFiles) try {
45
+ const fileEntries = scanDtsFile(fs.readFileSync(file, "utf-8"), file);
46
+ for (const entry of fileEntries) entry.sourcePackage = classToImportPath.get(entry.className) || subEntryFromFilePath(packageName, pkgDir, file) || packageName;
47
+ entries.push(...fileEntries);
48
+ } catch {}
49
+ return entries;
50
+ }
51
+ /**
52
+ * Read package.json exports to build a map from class name to the correct
53
+ * sub-entry import path (e.g. "MatTabNav" → "@angular/material/tabs").
54
+ *
55
+ * For each sub-entry that has a "types" field, the corresponding .d.ts file
56
+ * is read to collect declared class names and re-exported names.
57
+ */
58
+ function buildClassToImportMap(packageName, pkgDir) {
59
+ const map = /* @__PURE__ */ new Map();
60
+ try {
61
+ const pkgJson = JSON.parse(fs.readFileSync(path$1.join(pkgDir, "package.json"), "utf-8"));
62
+ if (!pkgJson.exports) return map;
63
+ for (const [key, value] of Object.entries(pkgJson.exports)) {
64
+ if (key !== "." && !key.startsWith("./")) continue;
65
+ let typesFile = typeof value === "object" && value !== null && value.types;
66
+ if (!typesFile && key === "." && typeof pkgJson.types === "string") typesFile = pkgJson.types;
67
+ if (!typesFile) continue;
68
+ const importPath = key === "." ? packageName : packageName + "/" + key.slice(2);
69
+ const fullTypesPath = path$1.resolve(pkgDir, typesFile);
70
+ if (!fs.existsSync(fullTypesPath)) continue;
71
+ collectExportedClassesFromDts(fullTypesPath, importPath, map);
72
+ }
73
+ } catch {}
74
+ return map;
75
+ }
76
+ /**
77
+ * Read a `.d.ts` entry file and add every class it exports to `map`,
78
+ * following `export * from './rel'` chains so re-exported classes from
79
+ * physically nested files (e.g. `lib/foo.d.ts`) are still mapped to the
80
+ * exporting entry's import path.
81
+ *
82
+ * Without this, packages whose root `index.d.ts` is just a barrel of
83
+ * `export * from './lib/...'` would never get their classes mapped, and the
84
+ * `subEntryFromFilePath` fallback would derive an invalid `${pkg}/lib`
85
+ * import for files living under `lib/`.
86
+ */
87
+ function collectExportedClassesFromDts(filePath, importPath, map, visited = /* @__PURE__ */ new Set()) {
88
+ if (visited.has(filePath)) return;
89
+ visited.add(filePath);
90
+ let code;
91
+ try {
92
+ code = fs.readFileSync(filePath, "utf-8");
93
+ } catch {
94
+ return;
95
+ }
96
+ let program;
97
+ try {
98
+ program = parseSync(filePath, code).program;
99
+ } catch {
100
+ return;
101
+ }
102
+ const dir = path$1.dirname(filePath);
103
+ for (const stmt of program.body || []) {
104
+ if (stmt.type === "ClassDeclaration" && stmt.id?.name) {
105
+ map.set(stmt.id.name, importPath);
106
+ continue;
107
+ }
108
+ if (stmt.type === "ExportNamedDeclaration") {
109
+ if (stmt.declaration?.type === "ClassDeclaration" && stmt.declaration.id?.name) map.set(stmt.declaration.id.name, importPath);
110
+ for (const spec of stmt.specifiers || []) {
111
+ const exportedNode = spec.exported;
112
+ const exportedName = exportedNode?.type === "Identifier" ? exportedNode.name : exportedNode?.type === "Literal" ? exportedNode.value : void 0;
113
+ if (typeof exportedName === "string") map.set(exportedName, importPath);
114
+ }
115
+ continue;
116
+ }
117
+ if (stmt.type === "ExportAllDeclaration") {
118
+ const rel = stmt.source?.value;
119
+ if (!rel || !rel.startsWith(".")) continue;
120
+ const normalizedRel = rel.replace(/\.(?:js|mjs)$/u, "");
121
+ const candidates = [path$1.resolve(dir, normalizedRel + ".d.ts"), path$1.resolve(dir, normalizedRel, "index.d.ts")];
122
+ for (const candidate of candidates) if (fs.existsSync(candidate)) {
123
+ collectExportedClassesFromDts(candidate, importPath, map, visited);
124
+ break;
125
+ }
126
+ continue;
127
+ }
128
+ }
129
+ }
130
+ /**
131
+ * Derive a sub-entry import path from a .d.ts file's location relative to the
132
+ * package root. This handles older Angular packages that keep .d.ts files in
133
+ * subdirectories (e.g. `@angular/material/tabs/index.d.ts`) instead of a
134
+ * top-level `types/` folder.
135
+ *
136
+ * Returns `undefined` when no sub-entry can be determined (e.g. file is at the
137
+ * package root, inside `types/`, or in a non-entry directory).
138
+ */
139
+ function subEntryFromFilePath(packageName, pkgDir, filePath) {
140
+ const NON_ENTRY_DIRS = new Set([
141
+ "types",
142
+ "fesm2022",
143
+ "fesm2020",
144
+ "fesm2015",
145
+ "esm2022",
146
+ "esm2020",
147
+ "esm2015",
148
+ "bundles",
149
+ "schematics",
150
+ "node_modules"
151
+ ]);
152
+ const segments = path$1.relative(pkgDir, filePath).split(path$1.sep);
153
+ if (segments.length < 2) return void 0;
154
+ const firstDir = segments[0];
155
+ if (NON_ENTRY_DIRS.has(firstDir) || firstDir.startsWith("_")) return void 0;
156
+ return packageName + "/" + firstDir;
157
+ }
158
+ /**
159
+ * Parse a source file with OXC and return the set of bare-specifier package
160
+ * names it imports (e.g. "@angular/router", "rxjs"). Relative imports are
161
+ * skipped.
162
+ */
163
+ function collectImportedPackages(code, fileName) {
164
+ const packages = /* @__PURE__ */ new Set();
165
+ const { program } = parseSync(fileName, code);
166
+ for (const stmt of program.body) {
167
+ if (stmt.type !== "ImportDeclaration") continue;
168
+ const specifier = stmt.source?.value;
169
+ if (!specifier || specifier.startsWith(".")) continue;
170
+ const parts = specifier.split("/");
171
+ packages.add(specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0]);
172
+ }
173
+ return packages;
174
+ }
175
+ /**
176
+ * Parse a source file with OXC and return the relative-path specifiers it
177
+ * re-exports via `export * from './x'`, `export * as Ns from './x'`, or
178
+ * `export { … } from './x'`. Bare-specifier re-exports are skipped.
179
+ *
180
+ * Used by the analog Vite plugin to walk library entry barrels at startup
181
+ * (e.g. `helm/select/src/index.ts` → `./lib/hlm-select`) so the underlying
182
+ * directive classes land in the registry before any consumer is compiled.
183
+ */
184
+ function collectRelativeReExports(code, fileName) {
185
+ let program;
186
+ try {
187
+ program = parseSync(fileName, code).program;
188
+ } catch {
189
+ return [];
190
+ }
191
+ const result = [];
192
+ for (const stmt of program.body || []) {
193
+ if (stmt.type !== "ExportAllDeclaration" && stmt.type !== "ExportNamedDeclaration") continue;
194
+ const specifier = stmt.source?.value;
195
+ if (!specifier || !specifier.startsWith(".")) continue;
196
+ result.push(specifier);
197
+ }
198
+ return result;
199
+ }
200
+ function visitStatements(stmts, fileName, entries) {
201
+ for (const stmt of stmts) {
202
+ const decl = stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration" ? stmt.declaration : stmt;
203
+ if (!decl) continue;
204
+ if (decl.type === "TSModuleDeclaration" && decl.body?.body) {
205
+ visitStatements(decl.body.body, fileName, entries);
206
+ continue;
207
+ }
208
+ if (decl.type !== "ClassDeclaration" || !decl.id?.name) continue;
209
+ const className = decl.id.name;
210
+ const members = decl.body?.body || [];
211
+ for (const member of members) {
212
+ if (member.type !== "PropertyDefinition" || !member.static) continue;
213
+ const propName = member.key?.name;
214
+ const typeRef = member.typeAnnotation?.typeAnnotation;
215
+ if (!typeRef || typeRef.type !== "TSTypeReference") continue;
216
+ const typeName = qualifiedName(typeRef.typeName);
217
+ const typeParams = typeRef.typeArguments?.params;
218
+ if ((propName === "ɵdir" || propName === "ɵcmp") && (typeName.includes("DirectiveDeclaration") || typeName.includes("ComponentDeclaration")) && typeParams && typeParams.length >= 5) {
219
+ const selector = literalString(typeParams[1]);
220
+ if (!selector) continue;
221
+ const inputs = extractInputs(typeParams[3]);
222
+ const outputs = extractOutputs(typeParams[4]);
223
+ entries.push({
224
+ selector: selector.split(",")[0].trim(),
225
+ kind: propName === "ɵcmp" ? "component" : "directive",
226
+ fileName,
227
+ className,
228
+ ...Object.keys(inputs).length > 0 ? { inputs } : {},
229
+ ...Object.keys(outputs).length > 0 ? { outputs } : {}
230
+ });
231
+ } else if (propName === "ɵpipe" && typeName.includes("PipeDeclaration") && typeParams && typeParams.length >= 2) {
232
+ const pipeName = literalString(typeParams[1]);
233
+ if (!pipeName) continue;
234
+ entries.push({
235
+ selector: pipeName,
236
+ kind: "pipe",
237
+ pipeName,
238
+ fileName,
239
+ className
240
+ });
241
+ } else if (propName === "ɵmod" && typeName.includes("NgModuleDeclaration") && typeParams && typeParams.length >= 4) {
242
+ const exportsParam = typeParams[3];
243
+ const exportedNames = [];
244
+ if (exportsParam?.type === "TSTupleType" && exportsParam.elementTypes) {
245
+ for (const el of exportsParam.elementTypes) if (el.type === "TSTypeQuery" && el.exprName?.type === "Identifier") exportedNames.push(el.exprName.name);
246
+ else if (el.type === "TSTypeQuery" && el.exprName?.type === "TSQualifiedName") {
247
+ const right = el.exprName.right;
248
+ if (right?.type === "Identifier") exportedNames.push(right.name);
249
+ }
250
+ }
251
+ entries.push({
252
+ selector: className,
253
+ kind: "ngmodule",
254
+ exports: exportedNames,
255
+ fileName,
256
+ className
257
+ });
258
+ }
259
+ }
260
+ }
261
+ }
262
+ /**
263
+ * Extract inputs from the type-argument at position [3].
264
+ *
265
+ * Handles two formats:
266
+ * v16+: { "prop": { "alias": "binding"; "required": false; "isSignal"?: true } }
267
+ * pre-v16: { "prop": "binding" }
268
+ */
269
+ function extractInputs(node) {
270
+ const inputs = {};
271
+ if (node?.type !== "TSTypeLiteral") return inputs;
272
+ for (const member of node.members) {
273
+ if (member.type !== "TSPropertySignature") continue;
274
+ const propName = keyName(member.key);
275
+ const innerType = member.typeAnnotation?.typeAnnotation;
276
+ if (!propName || !innerType) continue;
277
+ if (innerType.type === "TSTypeLiteral") {
278
+ let alias = propName;
279
+ let required = false;
280
+ let isSignal = false;
281
+ for (const inner of innerType.members) {
282
+ if (inner.type !== "TSPropertySignature") continue;
283
+ const key = keyName(inner.key);
284
+ const val = inner.typeAnnotation?.typeAnnotation;
285
+ if (!key || !val) continue;
286
+ if (key === "alias") alias = literalString(val) ?? propName;
287
+ else if (key === "required") required = literalBoolean(val) === true;
288
+ else if (key === "isSignal") isSignal = literalBoolean(val) === true;
289
+ }
290
+ inputs[propName] = {
291
+ classPropertyName: propName,
292
+ bindingPropertyName: alias,
293
+ isSignal,
294
+ required
295
+ };
296
+ } else {
297
+ const alias = literalString(innerType);
298
+ if (alias) inputs[propName] = {
299
+ classPropertyName: propName,
300
+ bindingPropertyName: alias,
301
+ isSignal: false,
302
+ required: false
303
+ };
304
+ }
305
+ }
306
+ return inputs;
307
+ }
308
+ /**
309
+ * Extract outputs from the type-argument at position [4].
310
+ * Format: { "propName": "eventName" }
311
+ */
312
+ function extractOutputs(node) {
313
+ const outputs = {};
314
+ if (node?.type !== "TSTypeLiteral") return outputs;
315
+ for (const member of node.members) {
316
+ if (member.type !== "TSPropertySignature") continue;
317
+ const propName = keyName(member.key);
318
+ const val = member.typeAnnotation?.typeAnnotation;
319
+ if (!propName || !val) continue;
320
+ const value = literalString(val);
321
+ if (value) outputs[propName] = value;
322
+ }
323
+ return outputs;
324
+ }
325
+ /** Get the string name from a property key (Identifier or Literal). */
326
+ function keyName(key) {
327
+ if (!key) return void 0;
328
+ if (key.type === "Identifier") return key.name;
329
+ if (key.type === "Literal" && typeof key.value === "string") return key.value;
330
+ }
331
+ /** Build a dotted name from an Identifier or TSQualifiedName. */
332
+ function qualifiedName(node) {
333
+ if (!node) return "";
334
+ if (node.type === "Identifier") return node.name;
335
+ if (node.type === "TSQualifiedName") return qualifiedName(node.left) + "." + qualifiedName(node.right);
336
+ return "";
337
+ }
338
+ /** Extract a string value from a TSLiteralType node. */
339
+ function literalString(node) {
340
+ if (node?.type === "TSLiteralType" && node.literal?.type === "Literal" && typeof node.literal.value === "string") return node.literal.value;
341
+ }
342
+ /** Extract a boolean value from a TSLiteralType node. */
343
+ function literalBoolean(node) {
344
+ if (node?.type === "TSLiteralType" && node.literal?.type === "Literal" && typeof node.literal.value === "boolean") return node.literal.value;
345
+ }
346
+ /** Recursively collect all .d.ts files under a directory. */
347
+ function collectDtsFiles(dir) {
348
+ const results = [];
349
+ let entries;
350
+ try {
351
+ entries = fs.readdirSync(dir, { withFileTypes: true });
352
+ } catch {
353
+ return results;
354
+ }
355
+ for (const entry of entries) {
356
+ const full = path$1.join(dir, entry.name);
357
+ if (entry.isDirectory() && entry.name !== "node_modules") results.push(...collectDtsFiles(full));
358
+ else if (entry.isFile() && entry.name.endsWith(".d.ts")) results.push(full);
359
+ }
360
+ return results;
361
+ }
362
+ //#endregion
363
+ export { collectImportedPackages, collectRelativeReExports, scanDtsFile, scanPackageDts };
364
+
365
+ //# sourceMappingURL=dts-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dts-reader.js","names":[],"sources":["../../../../src/lib/compiler/dts-reader.ts"],"sourcesContent":["import { parseSync } from 'oxc-parser';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { RegistryEntry, RegistryInput } from './registry.js';\n\n/**\n * Scan a single .d.ts file and extract Angular directive/component/pipe\n * metadata from the static ɵdir / ɵcmp / ɵpipe type declarations.\n *\n * This mirrors what ngtsc's DtsMetadataReader does: it reads the type\n * parameters of ɵɵDirectiveDeclaration / ɵɵComponentDeclaration /\n * ɵɵPipeDeclaration to discover selectors, inputs, and outputs for\n * pre-compiled Angular packages.\n */\nexport function scanDtsFile(code: string, fileName: string): RegistryEntry[] {\n // Fast pre-filter — skip files that can't contain Angular declarations\n if (\n !code.includes('DirectiveDeclaration') &&\n !code.includes('ComponentDeclaration') &&\n !code.includes('PipeDeclaration') &&\n !code.includes('NgModuleDeclaration')\n )\n return [];\n\n const { program } = parseSync(fileName, code);\n const entries: RegistryEntry[] = [];\n\n visitStatements(program.body, fileName, entries);\n return entries;\n}\n\n/**\n * Resolve a package's directory in node_modules, scan all its .d.ts files,\n * and return RegistryEntry[] for every Angular declaration found.\n *\n * @param packageName e.g. \"@angular/router\"\n * @param basePath project root (where node_modules lives)\n */\nexport function scanPackageDts(\n packageName: string,\n basePath: string,\n): RegistryEntry[] {\n // Walk up from basePath to find the nearest node_modules containing the package.\n // This handles monorepos where node_modules is at the workspace root,\n // not in the project subdirectory.\n let pkgDir = '';\n let searchBase = basePath;\n while (searchBase !== path.dirname(searchBase)) {\n const candidate = path.join(searchBase, 'node_modules', packageName);\n if (fs.existsSync(candidate)) {\n pkgDir = candidate;\n break;\n }\n searchBase = path.dirname(searchBase);\n }\n if (!pkgDir) return [];\n\n // Build a map from className → correct import path using package.json exports.\n // This handles packages with sub-entry points (e.g. @angular/material/tabs)\n // where re-exported classes must be imported from their origin entry point.\n const classToImportPath = buildClassToImportMap(packageName, pkgDir);\n\n // Check for a \"types\" directory first (Angular packages use this),\n // then fall back to the package root.\n const typesDir = path.join(pkgDir, 'types');\n const searchDir = fs.existsSync(typesDir) ? typesDir : pkgDir;\n\n const dtsFiles = collectDtsFiles(searchDir);\n const entries: RegistryEntry[] = [];\n\n for (const file of dtsFiles) {\n try {\n const code = fs.readFileSync(file, 'utf-8');\n const fileEntries = scanDtsFile(code, file);\n for (const entry of fileEntries) {\n entry.sourcePackage =\n classToImportPath.get(entry.className) ||\n subEntryFromFilePath(packageName, pkgDir, file) ||\n packageName;\n }\n entries.push(...fileEntries);\n } catch {\n // Skip unreadable files\n }\n }\n\n return entries;\n}\n\n/**\n * Read package.json exports to build a map from class name to the correct\n * sub-entry import path (e.g. \"MatTabNav\" → \"@angular/material/tabs\").\n *\n * For each sub-entry that has a \"types\" field, the corresponding .d.ts file\n * is read to collect declared class names and re-exported names.\n */\nfunction buildClassToImportMap(\n packageName: string,\n pkgDir: string,\n): Map<string, string> {\n const map = new Map<string, string>();\n try {\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf-8'),\n );\n if (!pkgJson.exports) return map;\n\n for (const [key, value] of Object.entries(pkgJson.exports) as [\n string,\n any,\n ][]) {\n if (key !== '.' && !key.startsWith('./')) continue;\n // Resolve types from the export entry. Some packages declare\n // `types` only at the package root (top-level package.json `types`\n // field) rather than per-export, so fall back to that for `.`.\n let typesFile: string | undefined =\n typeof value === 'object' && value !== null && value.types;\n if (!typesFile && key === '.' && typeof pkgJson.types === 'string') {\n typesFile = pkgJson.types;\n }\n if (!typesFile) continue;\n\n // Root entry (`.`) maps classes to the bare package name; sub-entries\n // (`./tabs`) map to `${packageName}/tabs`. Mapping root-exported\n // classes prevents `subEntryFromFilePath` from deriving an invalid\n // subpath like `ngx-scrollbar/lib` for files that physically live in\n // a `lib/` subdirectory but are only re-exported from the root entry.\n const importPath =\n key === '.' ? packageName : packageName + '/' + key.slice(2);\n const fullTypesPath = path.resolve(pkgDir, typesFile);\n if (!fs.existsSync(fullTypesPath)) continue;\n\n collectExportedClassesFromDts(fullTypesPath, importPath, map);\n }\n } catch {\n // No package.json or no exports — fall back to packageName\n }\n return map;\n}\n\n/**\n * Read a `.d.ts` entry file and add every class it exports to `map`,\n * following `export * from './rel'` chains so re-exported classes from\n * physically nested files (e.g. `lib/foo.d.ts`) are still mapped to the\n * exporting entry's import path.\n *\n * Without this, packages whose root `index.d.ts` is just a barrel of\n * `export * from './lib/...'` would never get their classes mapped, and the\n * `subEntryFromFilePath` fallback would derive an invalid `${pkg}/lib`\n * import for files living under `lib/`.\n */\nfunction collectExportedClassesFromDts(\n filePath: string,\n importPath: string,\n map: Map<string, string>,\n visited: Set<string> = new Set(),\n): void {\n if (visited.has(filePath)) return;\n visited.add(filePath);\n let code: string;\n try {\n code = fs.readFileSync(filePath, 'utf-8');\n } catch {\n return;\n }\n\n let program: any;\n try {\n program = parseSync(filePath, code).program;\n } catch {\n return;\n }\n\n const dir = path.dirname(filePath);\n for (const stmt of program.body || []) {\n // `declare class Foo` (top-level)\n if (stmt.type === 'ClassDeclaration' && stmt.id?.name) {\n map.set(stmt.id.name, importPath);\n continue;\n }\n\n // `export declare class Foo` / `export class Foo` /\n // `export { A, B as C } from '...'` / `export { A, B }`\n if (stmt.type === 'ExportNamedDeclaration') {\n if (\n stmt.declaration?.type === 'ClassDeclaration' &&\n stmt.declaration.id?.name\n ) {\n map.set(stmt.declaration.id.name, importPath);\n }\n for (const spec of stmt.specifiers || []) {\n // ExportSpecifier: { local, exported }\n const exportedNode = spec.exported;\n const exportedName =\n exportedNode?.type === 'Identifier'\n ? exportedNode.name\n : exportedNode?.type === 'Literal'\n ? exportedNode.value\n : undefined;\n if (typeof exportedName === 'string') {\n map.set(exportedName, importPath);\n }\n }\n continue;\n }\n\n // `export * from './rel'` and `export * as Ns from './rel'`\n if (stmt.type === 'ExportAllDeclaration') {\n const rel: string | undefined = stmt.source?.value;\n if (!rel || !rel.startsWith('.')) continue;\n // TypeScript preserves the original specifier text in emitted\n // `.d.ts` files, so NodeNext-style packages keep their `.js`\n // (or `.mjs`) extensions in re-exports — but the actual\n // declaration is at `foo.d.ts` / `foo/index.d.ts`. Strip the\n // ESM extension before probing.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const candidates = [\n path.resolve(dir, normalizedRel + '.d.ts'),\n path.resolve(dir, normalizedRel, 'index.d.ts'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n collectExportedClassesFromDts(candidate, importPath, map, visited);\n break;\n }\n }\n continue;\n }\n }\n}\n\n/**\n * Derive a sub-entry import path from a .d.ts file's location relative to the\n * package root. This handles older Angular packages that keep .d.ts files in\n * subdirectories (e.g. `@angular/material/tabs/index.d.ts`) instead of a\n * top-level `types/` folder.\n *\n * Returns `undefined` when no sub-entry can be determined (e.g. file is at the\n * package root, inside `types/`, or in a non-entry directory).\n */\nfunction subEntryFromFilePath(\n packageName: string,\n pkgDir: string,\n filePath: string,\n): string | undefined {\n const NON_ENTRY_DIRS = new Set([\n 'types',\n 'fesm2022',\n 'fesm2020',\n 'fesm2015',\n 'esm2022',\n 'esm2020',\n 'esm2015',\n 'bundles',\n 'schematics',\n 'node_modules',\n ]);\n const rel = path.relative(pkgDir, filePath);\n const segments = rel.split(path.sep);\n // File directly in pkgDir (no subdirectory) → no sub-entry\n if (segments.length < 2) return undefined;\n const firstDir = segments[0];\n // Skip internal/build directories and chunk files\n if (NON_ENTRY_DIRS.has(firstDir) || firstDir.startsWith('_'))\n return undefined;\n return packageName + '/' + firstDir;\n}\n\n/**\n * Parse a source file with OXC and return the set of bare-specifier package\n * names it imports (e.g. \"@angular/router\", \"rxjs\"). Relative imports are\n * skipped.\n */\nexport function collectImportedPackages(\n code: string,\n fileName: string,\n): Set<string> {\n const packages = new Set<string>();\n const { program } = parseSync(fileName, code);\n\n for (const stmt of program.body) {\n if (stmt.type !== 'ImportDeclaration') continue;\n const specifier: string = stmt.source?.value;\n if (!specifier || specifier.startsWith('.')) continue;\n\n const parts = specifier.split('/');\n packages.add(\n specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0],\n );\n }\n\n return packages;\n}\n\n/**\n * Parse a source file with OXC and return the relative-path specifiers it\n * re-exports via `export * from './x'`, `export * as Ns from './x'`, or\n * `export { … } from './x'`. Bare-specifier re-exports are skipped.\n *\n * Used by the analog Vite plugin to walk library entry barrels at startup\n * (e.g. `helm/select/src/index.ts` → `./lib/hlm-select`) so the underlying\n * directive classes land in the registry before any consumer is compiled.\n */\nexport function collectRelativeReExports(\n code: string,\n fileName: string,\n): string[] {\n let program: any;\n try {\n program = parseSync(fileName, code).program;\n } catch {\n return [];\n }\n const result: string[] = [];\n for (const stmt of program.body || []) {\n if (\n stmt.type !== 'ExportAllDeclaration' &&\n stmt.type !== 'ExportNamedDeclaration'\n ) {\n continue;\n }\n // ExportNamedDeclaration without `source` is `export { x }` (no\n // re-export), which we don't care about here.\n const specifier: string | undefined = stmt.source?.value;\n if (!specifier || !specifier.startsWith('.')) continue;\n result.push(specifier);\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction visitStatements(\n stmts: any[],\n fileName: string,\n entries: RegistryEntry[],\n) {\n for (const stmt of stmts) {\n // Unwrap exports: `export declare class ...` / `export default class ...`\n const decl =\n stmt.type === 'ExportNamedDeclaration' ||\n stmt.type === 'ExportDefaultDeclaration'\n ? stmt.declaration\n : stmt;\n\n if (!decl) continue;\n\n // Recurse into `declare module \"...\" { ... }` blocks\n if (decl.type === 'TSModuleDeclaration' && decl.body?.body) {\n visitStatements(decl.body.body, fileName, entries);\n continue;\n }\n\n if (decl.type !== 'ClassDeclaration' || !decl.id?.name) continue;\n const className: string = decl.id.name;\n const members: any[] = decl.body?.body || [];\n\n for (const member of members) {\n if (member.type !== 'PropertyDefinition' || !member.static) continue;\n const propName: string | undefined = member.key?.name;\n\n // Read the type annotation: e.g. `i0.ɵɵDirectiveDeclaration<...>`\n const typeRef = member.typeAnnotation?.typeAnnotation;\n if (!typeRef || typeRef.type !== 'TSTypeReference') continue;\n\n const typeName = qualifiedName(typeRef.typeName);\n const typeParams: any[] | undefined = typeRef.typeArguments?.params;\n\n if (\n (propName === 'ɵdir' || propName === 'ɵcmp') &&\n (typeName.includes('DirectiveDeclaration') ||\n typeName.includes('ComponentDeclaration')) &&\n typeParams &&\n typeParams.length >= 5\n ) {\n const selector = literalString(typeParams[1]);\n if (!selector) continue;\n\n const inputs = extractInputs(typeParams[3]);\n const outputs = extractOutputs(typeParams[4]);\n\n entries.push({\n selector: selector.split(',')[0].trim(),\n kind: propName === 'ɵcmp' ? 'component' : 'directive',\n fileName,\n className,\n ...(Object.keys(inputs).length > 0 ? { inputs } : {}),\n ...(Object.keys(outputs).length > 0 ? { outputs } : {}),\n });\n } else if (\n propName === 'ɵpipe' &&\n typeName.includes('PipeDeclaration') &&\n typeParams &&\n typeParams.length >= 2\n ) {\n const pipeName = literalString(typeParams[1]);\n if (!pipeName) continue;\n\n entries.push({\n selector: pipeName,\n kind: 'pipe',\n pipeName,\n fileName,\n className,\n });\n } else if (\n propName === 'ɵmod' &&\n typeName.includes('NgModuleDeclaration') &&\n typeParams &&\n typeParams.length >= 4\n ) {\n // ɵɵNgModuleDeclaration<Module, Declarations, Imports, Exports>\n // Extract exported class names from the 4th type param (index 3).\n const exportsParam = typeParams[3];\n const exportedNames: string[] = [];\n if (exportsParam?.type === 'TSTupleType' && exportsParam.elementTypes) {\n for (const el of exportsParam.elementTypes) {\n if (\n el.type === 'TSTypeQuery' &&\n el.exprName?.type === 'Identifier'\n ) {\n exportedNames.push(el.exprName.name);\n } else if (\n el.type === 'TSTypeQuery' &&\n el.exprName?.type === 'TSQualifiedName'\n ) {\n // e.g. typeof i2.BidiModule → extract \"BidiModule\"\n const right = el.exprName.right;\n if (right?.type === 'Identifier') {\n exportedNames.push(right.name);\n }\n }\n }\n }\n entries.push({\n selector: className,\n kind: 'ngmodule',\n exports: exportedNames,\n fileName,\n className,\n });\n }\n }\n }\n}\n\n/**\n * Extract inputs from the type-argument at position [3].\n *\n * Handles two formats:\n * v16+: { \"prop\": { \"alias\": \"binding\"; \"required\": false; \"isSignal\"?: true } }\n * pre-v16: { \"prop\": \"binding\" }\n */\nfunction extractInputs(node: any): Record<string, RegistryInput> {\n const inputs: Record<string, RegistryInput> = {};\n if (node?.type !== 'TSTypeLiteral') return inputs;\n\n for (const member of node.members) {\n if (member.type !== 'TSPropertySignature') continue;\n const propName = keyName(member.key);\n const innerType = member.typeAnnotation?.typeAnnotation;\n if (!propName || !innerType) continue;\n\n if (innerType.type === 'TSTypeLiteral') {\n // v16+ object format\n let alias = propName;\n let required = false;\n let isSignal = false;\n\n for (const inner of innerType.members) {\n if (inner.type !== 'TSPropertySignature') continue;\n const key = keyName(inner.key);\n const val = inner.typeAnnotation?.typeAnnotation;\n if (!key || !val) continue;\n\n if (key === 'alias') {\n alias = literalString(val) ?? propName;\n } else if (key === 'required') {\n required = literalBoolean(val) === true;\n } else if (key === 'isSignal') {\n isSignal = literalBoolean(val) === true;\n }\n }\n\n inputs[propName] = {\n classPropertyName: propName,\n bindingPropertyName: alias,\n isSignal,\n required,\n };\n } else {\n // pre-v16 string format\n const alias = literalString(innerType);\n if (alias) {\n inputs[propName] = {\n classPropertyName: propName,\n bindingPropertyName: alias,\n isSignal: false,\n required: false,\n };\n }\n }\n }\n\n return inputs;\n}\n\n/**\n * Extract outputs from the type-argument at position [4].\n * Format: { \"propName\": \"eventName\" }\n */\nfunction extractOutputs(node: any): Record<string, string> {\n const outputs: Record<string, string> = {};\n if (node?.type !== 'TSTypeLiteral') return outputs;\n\n for (const member of node.members) {\n if (member.type !== 'TSPropertySignature') continue;\n const propName = keyName(member.key);\n const val = member.typeAnnotation?.typeAnnotation;\n if (!propName || !val) continue;\n\n const value = literalString(val);\n if (value) outputs[propName] = value;\n }\n\n return outputs;\n}\n\n/** Get the string name from a property key (Identifier or Literal). */\nfunction keyName(key: any): string | undefined {\n if (!key) return undefined;\n if (key.type === 'Identifier') return key.name;\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value;\n return undefined;\n}\n\n/** Build a dotted name from an Identifier or TSQualifiedName. */\nfunction qualifiedName(node: any): string {\n if (!node) return '';\n if (node.type === 'Identifier') return node.name;\n if (node.type === 'TSQualifiedName')\n return qualifiedName(node.left) + '.' + qualifiedName(node.right);\n return '';\n}\n\n/** Extract a string value from a TSLiteralType node. */\nfunction literalString(node: any): string | undefined {\n if (\n node?.type === 'TSLiteralType' &&\n node.literal?.type === 'Literal' &&\n typeof node.literal.value === 'string'\n ) {\n return node.literal.value;\n }\n return undefined;\n}\n\n/** Extract a boolean value from a TSLiteralType node. */\nfunction literalBoolean(node: any): boolean | undefined {\n if (\n node?.type === 'TSLiteralType' &&\n node.literal?.type === 'Literal' &&\n typeof node.literal.value === 'boolean'\n ) {\n return node.literal.value;\n }\n return undefined;\n}\n\n/** Recursively collect all .d.ts files under a directory. */\nfunction collectDtsFiles(dir: string): string[] {\n const results: string[] = [];\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules') {\n results.push(...collectDtsFiles(full));\n } else if (entry.isFile() && entry.name.endsWith('.d.ts')) {\n results.push(full);\n }\n }\n\n return results;\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { RegistryEntry } from "./registry.js";
2
+ /**
3
+ * Generate HMR code using Angular's ɵɵreplaceMetadata for components,
4
+ * and simple field-swap + invalidation for directives/pipes.
5
+ *
6
+ * The applyMetadata callback dynamically copies all ɵ-prefixed static
7
+ * fields (ɵcmp, ɵfac, ɵdir, ɵpipe, etc.) from the newly compiled class
8
+ * to the old class reference that Angular's runtime is tracking.
9
+ *
10
+ * For components, ɵɵreplaceMetadata then merges the old/new definitions
11
+ * and recreates matching LViews in the component tree.
12
+ *
13
+ * For directives and pipes, ɵɵreplaceMetadata does not support them, so
14
+ * we fall back to a full page reload via import.meta.hot.invalidate().
15
+ */
16
+ export declare function generateHmrCode(declarations: RegistryEntry[], localDepClassNames?: string[]): string;
@@ -0,0 +1,69 @@
1
+ //#region packages/vite-plugin-angular/src/lib/compiler/hmr.ts
2
+ /**
3
+ * Generate HMR code using Angular's ɵɵreplaceMetadata for components,
4
+ * and simple field-swap + invalidation for directives/pipes.
5
+ *
6
+ * The applyMetadata callback dynamically copies all ɵ-prefixed static
7
+ * fields (ɵcmp, ɵfac, ɵdir, ɵpipe, etc.) from the newly compiled class
8
+ * to the old class reference that Angular's runtime is tracking.
9
+ *
10
+ * For components, ɵɵreplaceMetadata then merges the old/new definitions
11
+ * and recreates matching LViews in the component tree.
12
+ *
13
+ * For directives and pipes, ɵɵreplaceMetadata does not support them, so
14
+ * we fall back to a full page reload via import.meta.hot.invalidate().
15
+ */
16
+ function generateHmrCode(declarations, localDepClassNames = []) {
17
+ const components = declarations.filter((d) => d.kind === "component");
18
+ const nonComponents = declarations.filter((d) => d.kind !== "component");
19
+ const applyFns = declarations.map((c) => `
20
+ export function ɵhmr_${c.className}(type) {
21
+ for (const key of Object.getOwnPropertyNames(${c.className})) {
22
+ if (key.startsWith('ɵ')) type[key] = ${c.className}[key];
23
+ }
24
+ }`).join("\n");
25
+ const localDepsArray = localDepClassNames.length > 0 ? `[${localDepClassNames.join(", ")}]` : "[]";
26
+ const replaceBlocks = components.map((c) => `
27
+ try {
28
+ i0.ɵɵreplaceMetadata(
29
+ ${c.className},
30
+ newModule.ɵhmr_${c.className},
31
+ { i0 },
32
+ ${localDepsArray},
33
+ import.meta,
34
+ "${c.className}"
35
+ );
36
+ replaced = true;
37
+ } catch(e) {
38
+ // ɵɵreplaceMetadata failed — will fall back to page reload
39
+ }`).join("\n");
40
+ const swapBlocks = nonComponents.map((c) => `
41
+ try {
42
+ newModule.ɵhmr_${c.className}(${c.className});
43
+ swapped = true;
44
+ } catch(e) {}`).join("\n");
45
+ let acceptBody = `
46
+ if (!newModule) return;`;
47
+ if (components.length > 0) acceptBody += `
48
+ let replaced = false;${replaceBlocks}
49
+ if (!replaced) {
50
+ import.meta.hot.invalidate('Component HMR failed, reloading');
51
+ return;
52
+ }`;
53
+ if (nonComponents.length > 0) acceptBody += `
54
+ let swapped = false;${swapBlocks}
55
+ if (swapped) {
56
+ // Directive/pipe definitions updated — full reload needed for Angular
57
+ // to pick up the new behavior since ɵɵreplaceMetadata only supports components.
58
+ import.meta.hot.invalidate('Directive/pipe changed, reloading');
59
+ }`;
60
+ return `\n${applyFns}
61
+ if (import.meta.hot) {
62
+ import.meta.hot.accept((newModule) => {${acceptBody}
63
+ });
64
+ }`;
65
+ }
66
+ //#endregion
67
+ export { generateHmrCode };
68
+
69
+ //# sourceMappingURL=hmr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr.js","names":[],"sources":["../../../../src/lib/compiler/hmr.ts"],"sourcesContent":["import type { RegistryEntry } from './registry.js';\n\n/**\n * Generate HMR code using Angular's ɵɵreplaceMetadata for components,\n * and simple field-swap + invalidation for directives/pipes.\n *\n * The applyMetadata callback dynamically copies all ɵ-prefixed static\n * fields (ɵcmp, ɵfac, ɵdir, ɵpipe, etc.) from the newly compiled class\n * to the old class reference that Angular's runtime is tracking.\n *\n * For components, ɵɵreplaceMetadata then merges the old/new definitions\n * and recreates matching LViews in the component tree.\n *\n * For directives and pipes, ɵɵreplaceMetadata does not support them, so\n * we fall back to a full page reload via import.meta.hot.invalidate().\n */\nexport function generateHmrCode(\n declarations: RegistryEntry[],\n localDepClassNames: string[] = [],\n): string {\n const components = declarations.filter((d) => d.kind === 'component');\n const nonComponents = declarations.filter((d) => d.kind !== 'component');\n\n // Export applyMetadata functions so the accept callback can access them.\n // Dynamically copy all ɵ-prefixed static fields to handle ɵcmp, ɵfac,\n // ɵdir, ɵpipe, ɵmod, ɵinj, ɵprov, and any future Ivy fields.\n const applyFns = declarations\n .map(\n (c) => `\nexport function ɵhmr_${c.className}(type) {\n for (const key of Object.getOwnPropertyNames(${c.className})) {\n if (key.startsWith('ɵ')) type[key] = ${c.className}[key];\n }\n}`,\n )\n .join('\\n');\n\n // Components: use ɵɵreplaceMetadata for full LView recreation\n const localDepsArray =\n localDepClassNames.length > 0 ? `[${localDepClassNames.join(', ')}]` : '[]';\n\n const replaceBlocks = components\n .map(\n (c) => `\n try {\n i0.ɵɵreplaceMetadata(\n ${c.className},\n newModule.ɵhmr_${c.className},\n { i0 },\n ${localDepsArray},\n import.meta,\n \"${c.className}\"\n );\n replaced = true;\n } catch(e) {\n // ɵɵreplaceMetadata failed — will fall back to page reload\n }`,\n )\n .join('\\n');\n\n // Directives/pipes: swap static fields and invalidate\n const swapBlocks = nonComponents\n .map(\n (c) => `\n try {\n newModule.ɵhmr_${c.className}(${c.className});\n swapped = true;\n } catch(e) {}`,\n )\n .join('\\n');\n\n let acceptBody = `\n if (!newModule) return;`;\n\n if (components.length > 0) {\n acceptBody += `\n let replaced = false;${replaceBlocks}\n if (!replaced) {\n import.meta.hot.invalidate('Component HMR failed, reloading');\n return;\n }`;\n }\n\n if (nonComponents.length > 0) {\n acceptBody += `\n let swapped = false;${swapBlocks}\n if (swapped) {\n // Directive/pipe definitions updated — full reload needed for Angular\n // to pick up the new behavior since ɵɵreplaceMetadata only supports components.\n import.meta.hot.invalidate('Directive/pipe changed, reloading');\n }`;\n }\n\n return `\\n${applyFns}\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {${acceptBody}\n });\n}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,gBACd,cACA,qBAA+B,EAAE,EACzB;CACR,MAAM,aAAa,aAAa,QAAQ,MAAM,EAAE,SAAS,YAAY;CACrE,MAAM,gBAAgB,aAAa,QAAQ,MAAM,EAAE,SAAS,YAAY;CAKxE,MAAM,WAAW,aACd,KACE,MAAM;uBACU,EAAE,UAAU;iDACc,EAAE,UAAU;2CAClB,EAAE,UAAU;;GAGlD,CACA,KAAK,KAAK;CAGb,MAAM,iBACJ,mBAAmB,SAAS,IAAI,IAAI,mBAAmB,KAAK,KAAK,CAAC,KAAK;CAEzE,MAAM,gBAAgB,WACnB,KACE,MAAM;;;YAGD,EAAE,UAAU;2BACG,EAAE,UAAU;;YAE3B,eAAe;;aAEd,EAAE,UAAU;;;;;SAMpB,CACA,KAAK,KAAK;CAGb,MAAM,aAAa,cAChB,KACE,MAAM;;yBAEY,EAAE,UAAU,GAAG,EAAE,UAAU;;qBAG/C,CACA,KAAK,KAAK;CAEb,IAAI,aAAa;;AAGjB,KAAI,WAAW,SAAS,EACtB,eAAc;2BACS,cAAc;;;;;AAOvC,KAAI,cAAc,SAAS,EACzB,eAAc;0BACQ,WAAW;;;;;;AAQnC,QAAO,KAAK,SAAS;;2CAEoB,WAAW"}
@@ -0,0 +1,7 @@
1
+ export { compile, type CompileResult, type CompileOptions } from "./compile.js";
2
+ export { scanFile, type RegistryEntry, type ComponentRegistry } from "./registry.js";
3
+ export { scanDtsFile, scanPackageDts, collectImportedPackages, collectRelativeReExports } from "./dts-reader.js";
4
+ export { jitTransform, type JitTransformResult } from "./jit-transform.js";
5
+ export { generateHmrCode } from "./hmr.js";
6
+ export { inlineResourceUrls, extractInlineStyles } from "./resource-inliner.js";
7
+ export { debugCompile, debugRegistry, debugResolve, debugEmit } from "./debug.js";
@@ -0,0 +1,7 @@
1
+ import "./debug.js";
2
+ import "./compile.js";
3
+ import "./registry.js";
4
+ import "./dts-reader.js";
5
+ import "./jit-transform.js";
6
+ import "./hmr.js";
7
+ import "./resource-inliner.js";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Build ctorParameters for constructor DI in JIT format:
3
+ * [{ type: ServiceA }, { type: ServiceB, decorators: [{type: Optional}] }]
4
+ *
5
+ * Accepts an OXC ClassDeclaration node and the original source string.
6
+ */
7
+ export declare function buildCtorParameters(classNode: any, sourceCode: string, typeOnlyImports: Set<string>): string | null;
8
+ /**
9
+ * Build propDecorators for field decorators + signal API downleveling.
10
+ * Returns a JS object literal string or null if no props.
11
+ *
12
+ * Accepts an OXC ClassDeclaration node and the original source string.
13
+ */
14
+ export declare function buildPropDecorators(classNode: any, sourceCode: string): string | null;