@analogjs/vite-plugin-angular 3.0.0-alpha.98 → 3.0.0-beta.1

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 (90) hide show
  1. package/migrations/migrate-setup-vitest/migrate-setup-vitest.js.map +1 -1
  2. package/migrations/update-3-0-0/migrate-setup-vitest.js +3 -2
  3. package/migrations/update-3-0-0/migrate-setup-vitest.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/lib/analog-plugin-interop.js +1 -1
  6. package/src/lib/analog-plugin-interop.js.map +1 -1
  7. package/src/lib/angular-build-optimizer-plugin.js +1 -1
  8. package/src/lib/angular-build-optimizer-plugin.js.map +1 -1
  9. package/src/lib/angular-jit-plugin.js +3 -4
  10. package/src/lib/angular-jit-plugin.js.map +1 -1
  11. package/src/lib/angular-vite-plugin.js +11 -8
  12. package/src/lib/angular-vite-plugin.js.map +1 -1
  13. package/src/lib/angular-vitest-plugin.js +1 -1
  14. package/src/lib/angular-vitest-plugin.js.map +1 -1
  15. package/src/lib/compilation-api/compilation-api-plugin.js +6 -5
  16. package/src/lib/compilation-api/compilation-api-plugin.js.map +1 -1
  17. package/src/lib/compilation-api/index.js +2 -1
  18. package/src/lib/compiler/angular-version.js +1 -1
  19. package/src/lib/compiler/angular-version.js.map +1 -1
  20. package/src/lib/compiler/class-field-lowering.js.map +1 -1
  21. package/src/lib/compiler/compile.js +24 -22
  22. package/src/lib/compiler/compile.js.map +1 -1
  23. package/src/lib/compiler/constants.js +4 -4
  24. package/src/lib/compiler/constants.js.map +1 -1
  25. package/src/lib/compiler/debug.js.map +1 -1
  26. package/src/lib/compiler/defer.js +1 -1
  27. package/src/lib/compiler/defer.js.map +1 -1
  28. package/src/lib/compiler/dts-reader.js +1 -1
  29. package/src/lib/compiler/dts-reader.js.map +1 -1
  30. package/src/lib/compiler/hmr.js.map +1 -1
  31. package/src/lib/compiler/index.js +9 -8
  32. package/src/lib/compiler/jit-metadata.d.ts +2 -0
  33. package/src/lib/compiler/jit-metadata.js +9 -4
  34. package/src/lib/compiler/jit-metadata.js.map +1 -1
  35. package/src/lib/compiler/jit-transform.js +60 -34
  36. package/src/lib/compiler/jit-transform.js.map +1 -1
  37. package/src/lib/compiler/js-emitter.js +2 -4
  38. package/src/lib/compiler/js-emitter.js.map +1 -1
  39. package/src/lib/compiler/metadata.js +26 -18
  40. package/src/lib/compiler/metadata.js.map +1 -1
  41. package/src/lib/compiler/registry.js.map +1 -1
  42. package/src/lib/compiler/resource-inliner.js.map +1 -1
  43. package/src/lib/compiler/style-ast.js.map +1 -1
  44. package/src/lib/compiler/type-elision.js +2 -2
  45. package/src/lib/compiler/type-elision.js.map +1 -1
  46. package/src/lib/compiler/utils.js +7 -5
  47. package/src/lib/compiler/utils.js.map +1 -1
  48. package/src/lib/compiler-plugin.js +7 -0
  49. package/src/lib/compiler-plugin.js.map +1 -1
  50. package/src/lib/component-resolvers.js +1 -1
  51. package/src/lib/component-resolvers.js.map +1 -1
  52. package/src/lib/encapsulation-plugin.js +3 -2
  53. package/src/lib/encapsulation-plugin.js.map +1 -1
  54. package/src/lib/fast-compile-plugin.js +3 -2
  55. package/src/lib/fast-compile-plugin.js.map +1 -1
  56. package/src/lib/host.js.map +1 -1
  57. package/src/lib/hot-update-batch.js +1 -1
  58. package/src/lib/hot-update-batch.js.map +1 -1
  59. package/src/lib/live-reload-plugin.js.map +1 -1
  60. package/src/lib/nx-folder-plugin.js.map +1 -1
  61. package/src/lib/plugins/file-replacements.plugin.js.map +1 -1
  62. package/src/lib/router-plugin.js.map +1 -1
  63. package/src/lib/style-preprocessor.js.map +1 -1
  64. package/src/lib/stylesheet-registry.js.map +1 -1
  65. package/src/lib/tools/src/builders/vite/vite-build.impl.js +2 -1
  66. package/src/lib/tools/src/builders/vite/vite-build.impl.js.map +1 -1
  67. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js +2 -1
  68. package/src/lib/tools/src/builders/vite-dev-server/dev-server.impl.js.map +1 -1
  69. package/src/lib/utils/compilation-shared.js.map +1 -1
  70. package/src/lib/utils/css-extension-resolver.js.map +1 -1
  71. package/src/lib/utils/css-preprocessor-workers.js.map +1 -1
  72. package/src/lib/utils/debug-harness.js.map +1 -1
  73. package/src/lib/utils/debug-log-file.js +2 -1
  74. package/src/lib/utils/debug-log-file.js.map +1 -1
  75. package/src/lib/utils/debug.js.map +1 -1
  76. package/src/lib/utils/devkit.js +1 -1
  77. package/src/lib/utils/devkit.js.map +1 -1
  78. package/src/lib/utils/jit-inline-styles.d.ts +3 -2
  79. package/src/lib/utils/jit-inline-styles.js +9 -5
  80. package/src/lib/utils/jit-inline-styles.js.map +1 -1
  81. package/src/lib/utils/plugin-config.js.map +1 -1
  82. package/src/lib/utils/rolldown.js.map +1 -1
  83. package/src/lib/utils/safe-module-paths.js.map +1 -1
  84. package/src/lib/utils/transform-cache.js.map +1 -1
  85. package/src/lib/utils/tsconfig-resolver.js +2 -1
  86. package/src/lib/utils/tsconfig-resolver.js.map +1 -1
  87. package/src/lib/utils/virtual-ids.js.map +1 -1
  88. package/src/lib/utils/virtual-resources.js.map +1 -1
  89. package/src/lib/virtual-modules-plugin.js +4 -1
  90. package/src/lib/virtual-modules-plugin.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"fast-compile-plugin.js","names":[],"sources":["../../../src/lib/fast-compile-plugin.ts"],"sourcesContent":["import { promises as fsPromises } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { parseSync } from 'oxc-parser';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport { normalizePath, Plugin, preprocessCSS, ResolvedConfig } from 'vite';\n\nimport {\n compile,\n scanFile,\n scanPackageDts,\n collectImportedPackages,\n collectRelativeReExports,\n collectAllImports,\n jitTransform,\n inlineResourceUrls,\n extractInlineStyles,\n generateHmrCode,\n debugCompile,\n debugRegistry,\n ANGULAR_DECORATOR_CALL_RE,\n type ComponentRegistry,\n} from './compiler/index.js';\n\nimport {\n TS_EXT_REGEX,\n getTsConfigPath,\n createDepOptimizerConfig,\n isProdMode,\n type TsConfigResolutionContext,\n} from './utils/plugin-config.js';\nimport { releaseCssPreprocessorWorkers } from './utils/css-preprocessor-workers.js';\nimport { VIRTUAL_RAW_PREFIX, toVirtualRawId } from './utils/virtual-ids.js';\nimport {\n loadVirtualRawModule,\n rewriteHtmlRawImport,\n} from './utils/virtual-resources.js';\nimport { markStylePathSafe } from './utils/safe-module-paths.js';\nimport {\n discoverAnalogIntegrations,\n type ComponentRegistryEntries,\n type TransformFilter,\n} from './analog-plugin-interop.js';\n\nexport interface FastCompilePluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n fastCompileMode?: 'full' | 'partial';\n}\n\n/**\n * Directory that `compilerOptions.paths` targets resolve against. Mirrors\n * TypeScript: `baseUrl` when set, otherwise the directory of the config\n * that declares `paths` (`pathsBasePath`, since `baseUrl` is optional\n * from TS 4.1).\n */\nexport function getPathsBasePath(\n options: { baseUrl?: string; pathsBasePath?: string } | undefined,\n fallback: string,\n): string {\n return options?.baseUrl ?? options?.pathsBasePath ?? fallback;\n}\n\nexport function fastCompilePlugin(\n pluginOptions: FastCompilePluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let transformFilter: TransformFilter | undefined;\n let componentRegistries: ComponentRegistryEntries[] = [];\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // fast-compile plugin state\n const registry: ComponentRegistry = new Map();\n const resourceToSource = new Map<string, string>();\n const scannedDtsPackages = new Set<string>();\n let projectRoot = '';\n let useDefineForClassFields = true;\n\n /**\n * Scan a file into the registry, then recursively walk its relative\n * `export *` / `export { … } from './x'` chain so any underlying\n * directive classes also land in the registry. Used both at\n * `buildStart` (for tsconfig path entries) and at dev time (file\n * `add` and `handleHotUpdate`) so newly added barrels stay in sync\n * without requiring a server restart.\n *\n * The `visited` set prevents infinite recursion within a single\n * top-level call. Each fresh scan should pass an empty set (so HMR\n * re-scans aren't blocked by buildStart's earlier visits).\n *\n * `fileContents`/`scanResults` are cold-start dedup caches scoped to a\n * single `initFastCompile` call. HMR/watcher callers must omit them so\n * an edited file is always re-read from disk.\n */\n async function scanBarrelExports(\n file: string,\n visited: Set<string> = new Set(),\n overwrite = false,\n fileContents?: Map<string, string>,\n scanResults?: Map<string, ReturnType<typeof scanFile>>,\n ): Promise<void> {\n if (visited.has(file)) return;\n visited.add(file);\n let code: string;\n try {\n code =\n fileContents?.get(file) ?? (await fsPromises.readFile(file, 'utf-8'));\n fileContents?.set(file, code);\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: failed to read %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return;\n }\n // Single parse shared by scanFile and collectRelativeReExports. On a\n // parse error each consumer re-parses on its own, preserving their\n // individual failure semantics (scanFile throws past its pre-filter;\n // collectRelativeReExports swallows and returns []).\n let program: ReturnType<typeof parseSync>['program'] | undefined;\n try {\n program = parseSync(file, code).program;\n } catch {\n program = undefined;\n }\n let entries = scanResults?.get(file);\n if (!entries) {\n entries = scanFile(code, file, program);\n scanResults?.set(file, entries);\n }\n for (const entry of entries) {\n // At buildStart we want stable registry entries (don't overwrite\n // an earlier scan with a barrel re-scan); HMR explicitly asks\n // for overwrite so updated metadata replaces stale entries.\n if (overwrite || !registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n // Collect every relative re-export specifier via OXC AST so\n // recursive scans can't trip over each other (a shared `/g` regex\n // would have its `lastIndex` reset by each recursive call and\n // silently skip half of an outer barrel's re-exports, which\n // previously left directives like `HlmRadioGroup` unregistered).\n const dir = dirname(file);\n for (const rel of collectRelativeReExports(code, file, program)) {\n // NodeNext-style libraries write `export * from './foo.js'`\n // even though the source is `./foo.ts`. Strip the ESM\n // extension before probing or the candidates would be\n // `foo.js.ts` / `foo.js/index.ts`, which never exist.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const reExportCandidates = [\n resolve(dir, normalizedRel + '.ts'),\n resolve(dir, normalizedRel, 'index.ts'),\n ];\n let resolved = false;\n for (const candidate of reExportCandidates) {\n try {\n await fsPromises.access(candidate);\n await scanBarrelExports(\n candidate,\n visited,\n overwrite,\n fileContents,\n scanResults,\n );\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved && debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: %s re-export %s did not resolve to %o',\n file,\n rel,\n reExportCandidates,\n );\n }\n }\n }\n\n async function initFastCompile() {\n if (pluginOptions.jit) return; // JIT: no registry scan needed\n\n // Scan all source files to build the registry\n registry.clear();\n scannedDtsPackages.clear();\n const resolvedTsConfigPath = resolveTsConfigPath();\n projectRoot = dirname(resolvedTsConfigPath);\n const config = compilerCli.readConfiguration(resolvedTsConfigPath);\n useDefineForClassFields = config.options?.useDefineForClassFields ?? true;\n\n // Collect candidate files: tsconfig rootNames PLUS the entry points\n // named in `compilerOptions.paths`. App tsconfigs typically only\n // include the app's own sources, so workspace library entry barrels\n // (e.g. `HlmSelectImports = [HlmSelect, HlmSelectContent, ...] as\n // const`) live outside `rootNames` and would otherwise miss the\n // initial scan. The compiler then can't see that `HlmSelectImports`\n // is a tuple barrel and emits the bare identifier into the parent\n // component's `dependencies()` list, where Angular's runtime\n // silently drops it because arrays don't have a directive def.\n const candidates = new Set<string>(config.rootNames);\n const tsPaths = config.options?.paths;\n const baseUrl = getPathsBasePath(config.options, projectRoot);\n // Cold-start dedup caches shared by the three scan phases below\n // (candidates scan, walkImports, scanBarrelExports). Scoped to this\n // init call only — HMR/watcher re-scans must hit disk fresh.\n const fileContents = new Map<string, string>();\n const scanResults = new Map<string, ReturnType<typeof scanFile>>();\n if (tsPaths) {\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n // Skip wildcard patterns — entry barrels are normally exact\n // file paths like \"libs/helm/select/src/index.ts\".\n if (target.includes('*')) continue;\n candidates.add(resolve(baseUrl, target));\n }\n }\n }\n const results = await Promise.all(\n Array.from(candidates).map(async (file) => {\n try {\n const code = await fsPromises.readFile(file, 'utf-8');\n fileContents.set(file, code);\n const entries = scanFile(code, file);\n scanResults.set(file, entries);\n return entries;\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'initFastCompile: skipping unreadable %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return []; // Skip unreadable files\n }\n }),\n );\n\n for (const entries of results) {\n for (const entry of entries) {\n registry.set(entry.className, entry);\n }\n }\n\n // Walk the transitive import graph from the root files so the registry also\n // contains declarations that live in files not directly in tsconfig\n // `files`/`include` (transitively-imported app sources) and in workspace\n // libraries reached through wildcard `paths` (e.g. `@bitwarden/*`). Without\n // this, a non-standalone component's owning module can't classify its\n // declarations and `ɵɵsetComponentScope` is never emitted for it. Only\n // relative imports and `paths`-mapped (project/workspace) bare specifiers are\n // followed; true `node_modules` packages are left to the lazy `.d.ts` scanner.\n // Return *all* candidate base paths a bare specifier maps to. A `paths`\n // entry can list several fallback targets (e.g. a built `dist` path first\n // and the workspace `src` second); the caller probes them in order.\n const resolvePathSpecifier = (spec: string): string[] => {\n if (!tsPaths) return [];\n for (const [key, targets] of Object.entries(tsPaths)) {\n const list = targets as string[];\n if (key.endsWith('/*')) {\n const prefix = key.slice(0, -1);\n if (spec.startsWith(prefix)) {\n // `split('*').join(...)` substitutes the single tsconfig `*`\n // wildcard without `String.replace`'s first-match-only behavior or\n // `$`-pattern interpretation of the replacement.\n return list.map((t) =>\n resolve(baseUrl, t.split('*').join(spec.slice(prefix.length))),\n );\n }\n } else if (key === spec) {\n return list.map((t) => resolve(baseUrl, t));\n }\n }\n return [];\n };\n const probeToSource = async (base: string): Promise<string | null> => {\n const candidates = base.endsWith('.ts')\n ? [base]\n : [base + '.ts', resolve(base, 'index.ts')];\n for (const candidate of candidates) {\n try {\n await fsPromises.access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n };\n // Memoize fs probes per absolute base path. The cache stores the\n // Promise (not the settled value) so concurrent walks racing on the\n // same base collapse into a single probe.\n const baseResolveCache = new Map<string, Promise<string | null>>();\n const resolveToSource = (base: string): Promise<string | null> => {\n let probe = baseResolveCache.get(base);\n if (!probe) {\n probe = probeToSource(base);\n baseResolveCache.set(base, probe);\n }\n return probe;\n };\n // Probe each `paths` target in order; first one that resolves to source wins.\n const resolveFirstSource = async (\n bases: string[],\n ): Promise<string | null> => {\n for (const base of bases) {\n const resolved = await resolveToSource(base);\n if (resolved) return resolved;\n }\n return null;\n };\n const importWalkVisited = new Set<string>();\n // Paths-mapped resolution doesn't depend on the importer, so bare\n // specifiers can be memoized by their raw text. Relative specifiers\n // must NOT be — the same './foo' resolves differently per directory.\n const bareSpecResolveCache = new Map<string, Promise<string | null>>();\n const walkImports = async (file: string): Promise<void> => {\n if (importWalkVisited.has(file)) return;\n importWalkVisited.add(file);\n let code: string;\n try {\n code =\n fileContents.get(file) ?? (await fsPromises.readFile(file, 'utf-8'));\n fileContents.set(file, code);\n } catch {\n return;\n }\n // Single parse shared by scanFile, collectImportedPackages, and\n // collectAllImports. On a parse error each consumer re-parses on\n // its own, preserving their individual failure semantics.\n let program: ReturnType<typeof parseSync>['program'] | undefined;\n try {\n program = parseSync(file, code).program;\n } catch {\n program = undefined;\n }\n let entries = scanResults.get(file);\n if (!entries) {\n entries = scanFile(code, file, program);\n scanResults.set(file, entries);\n }\n for (const entry of entries) {\n if (!registry.has(entry.className))\n registry.set(entry.className, entry);\n }\n // Pre-scan the `.d.ts` of every external package this file imports (and,\n // transitively, packages those packages' NgModules re-export — e.g.\n // BrowserModule → CommonModule → NgIf). Doing this at buildStart means the\n // registry is complete before any component transforms, so non-standalone\n // component scope resolves regardless of file transform order.\n for (const pkg of collectImportedPackages(code, file, program)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n try {\n for (const entry of scanPackageDts(\n pkg,\n projectRoot,\n scannedDtsPackages,\n )) {\n if (!registry.has(entry.className))\n registry.set(entry.className, entry);\n }\n } catch {\n // Package may not have .d.ts or not be Angular\n }\n }\n const dir = dirname(file);\n const targets = await Promise.all(\n collectAllImports(code, file, program).map((spec) => {\n if (spec.startsWith('.')) {\n return resolveToSource(\n resolve(dir, spec.replace(/\\.(?:js|mjs)$/u, '')),\n );\n }\n let resolved = bareSpecResolveCache.get(spec);\n if (!resolved) {\n resolved = resolveFirstSource(resolvePathSpecifier(spec));\n bareSpecResolveCache.set(spec, resolved);\n }\n return resolved;\n }),\n );\n await Promise.all(\n targets.filter((t): t is string => !!t).map((t) => walkImports(t)),\n );\n };\n await Promise.all(config.rootNames.map((file) => walkImports(file)));\n\n // Library barrels typically `export * from './lib/...'` rather than\n // declaring directives directly, so the entry file alone gives us\n // the tuple consts but not the directive classes they reference.\n // Walk the relative `export *` chain so the underlying classes also\n // land in the registry. Use a SHARED visited set across all\n // barrels so recursive walks don't double-scan a file that's\n // re-exported from multiple entry points.\n const buildStartVisited = new Set<string>();\n if (tsPaths) {\n const barrelCandidates: string[] = [];\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n if (target.includes('*')) continue;\n barrelCandidates.push(resolve(baseUrl, target));\n }\n }\n await Promise.all(\n barrelCandidates.map((c) =>\n scanBarrelExports(\n c,\n buildStartVisited,\n false,\n fileContents,\n scanResults,\n ),\n ),\n );\n }\n debugRegistry(\n 'initFastCompile done: %d entries from %d candidate files',\n registry.size,\n candidates.size,\n );\n }\n\n function ensureDtsRegistryForSource(\n code: string,\n id: string,\n program?: ReturnType<typeof parseSync>['program'],\n ) {\n for (const pkg of collectImportedPackages(code, id, program)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n\n try {\n const dtsEntries = scanPackageDts(pkg, projectRoot, scannedDtsPackages);\n for (const entry of dtsEntries) {\n if (!registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n } catch {\n // Package may not have .d.ts files or may not be Angular\n }\n }\n }\n\n async function handleFastCompileTransform(\n code: string,\n id: string,\n ): Promise<{ code: string; map: any } | undefined> {\n if (!ANGULAR_DECORATOR_CALL_RE.test(code)) {\n // Non-Angular file — strip TS-only syntax ourselves so barrels\n // like `export { Foo, type Bar } from './x'` and other TS-only\n // forms don't leak unstripped to Rolldown. In rolldown-vite the\n // built-in `vite:oxc` strip is registered as a Rust-side native\n // plugin (`viteTransformPlugin` from `rolldown/experimental`); if\n // its hook-filter treats files our `transform.filter.id.include`\n // claimed as already-handled, no JS-side fallback runs and raw\n // TS reaches the parser → `SyntaxError: Unexpected identifier`.\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(code, id, {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n })\n : await vite.transformWithEsbuild(code, id, {\n loader: 'ts',\n sourcemap: true,\n });\n return { code: stripped.code, map: stripped.map };\n }\n\n // JIT mode\n if (pluginOptions.jit) {\n const result = jitTransform(code, id);\n // Strip TypeScript-only syntax (e.g. `readonly`, parameter property\n // modifiers, type annotations on fields) so the output is valid JS\n // for Rolldown. `angularVitestSourcemapPlugin` normally runs this\n // strip downstream in tests, but it is intentionally skipped on\n // StackBlitz / WebContainer — and the production build pipeline\n // does not register it either — so the JIT path must self-strip\n // to stay safe across environments.\n //\n // Pass the jitTransform map as `inMap` so OXC/esbuild emit a map\n // composed with the original `.ts` source — without this, debug\n // stack traces and breakpoints land on the wrong lines once the\n // strip removes any TS-only token. `jitTransform` returns\n // `map: null` for files with no Angular class (no edits made);\n // passing that to OXC/esbuild as `inMap` throws, so coerce to\n // `undefined` in that case.\n const inMap = result.map ?? undefined;\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(\n result.code,\n id,\n {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n },\n inMap,\n )\n : await vite.transformWithEsbuild(\n result.code,\n id,\n { loader: 'ts', sourcemap: true },\n inMap,\n );\n return { code: stripped.code, map: stripped.map };\n }\n\n // Inline external templateUrl/styleUrl(s) into the source before compilation.\n // `styleExtensions` carries the source extension of each inlined external\n // style so it can be preprocessed by its own file type (e.g. an external\n // `.scss` styleUrl) regardless of the `inlineStylesExtension` option.\n const inlined = await inlineResourceUrls(code, id);\n code = inlined.code;\n const { styleExtensions } = inlined;\n\n // Track inlined resources for HMR. `compile()` only reports resources it\n // reads through its own fallback (a templateUrl/styleUrl the inliner did\n // NOT already inline), so files inlined here must be recorded here or a\n // later edit to them never invalidates the owning module.\n for (const dep of inlined.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Single OXC parse of the post-inline source, shared by every AST\n // consumer below. `inlineResourceUrls` parsed the PRE-inline string,\n // so its program can never be reused here.\n const { program: oxcProgram } = parseSync(id, code);\n\n // Pre-resolve inline styles that need preprocessing (SCSS/Sass/Less). Run\n // whenever a style needs a non-`css` preprocessor — either the configured\n // `inlineStylesExtension` for truly-inline styles, or an external styleUrl's\n // own extension.\n let resolvedInlineStyles: Map<number, string> | undefined;\n\n const inlineExt = pluginOptions.inlineStylesExtension;\n const styleNeedsPreprocess = (ext: string) => ext !== '' && ext !== 'css';\n\n if (styleNeedsPreprocess(inlineExt) || styleExtensions.size > 0) {\n const styleStrings = extractInlineStyles(code, id, oxcProgram);\n\n if (styleStrings.length > 0) {\n resolvedInlineStyles = new Map();\n for (let i = 0; i < styleStrings.length; i++) {\n // External styleUrls are preprocessed by their own extension; truly\n // inline `styles: [...]` fall back to `inlineStylesExtension`.\n const ext = styleExtensions.get(i) ?? inlineExt;\n if (!styleNeedsPreprocess(ext)) continue;\n try {\n const fakePath = id.replace(/\\.ts$/, `.inline-${i}.${ext}`);\n const processed = await preprocessCSS(\n styleStrings[i],\n fakePath,\n resolvedConfig,\n );\n resolvedInlineStyles.set(i, processed.code);\n } catch (e) {\n if (debugCompile.enabled) {\n debugCompile(\n 'inline style #%d preprocessing failed in %s: %s',\n i,\n id,\n (e as Error)?.message,\n );\n }\n // Skip styles that can't be preprocessed\n }\n }\n if (resolvedInlineStyles.size === 0) resolvedInlineStyles = undefined;\n }\n }\n\n ensureDtsRegistryForSource(code, id, oxcProgram);\n\n // Merge registries contributed through `analog.setup()` into this\n // compile's lookup view. Out-of-tree compilers register directive\n // metadata for classes fastCompile can't reach through its\n // tsconfig-driven scan (e.g. `.tsrx` files compiled by `@tsrx/analog`).\n // Without this merge, a TS `@Component({ imports: [X] })` that\n // references such a class hits `_unresolved-${className}` as its\n // selector and the tag never matches at runtime.\n let compileRegistry: ComponentRegistry = registry;\n if (componentRegistries.some((external) => external.size > 0)) {\n compileRegistry = new Map(registry);\n for (const external of componentRegistries) {\n for (const [k, v] of external) compileRegistry.set(k, v);\n }\n }\n\n const result = compile(code, id, {\n registry: compileRegistry,\n resolvedInlineStyles,\n useDefineForClassFields,\n compilationMode: pluginOptions.fastCompileMode,\n oxcProgram,\n });\n\n // Track resource dependencies for HMR\n for (const dep of result.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Strip TypeScript-only syntax and compose the compiler map with the\n // final generated code so downstream breakpoints map back to the source.\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(\n result.code,\n id,\n {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n },\n result.map,\n )\n : await vite.transformWithEsbuild(\n result.code,\n id,\n { loader: 'ts', sourcemap: true },\n result.map,\n );\n let outputCode = stripped.code;\n\n // Append HMR code in dev mode\n if (watchMode && pluginOptions.liveReload) {\n const fileDeclarations = [...registry.values()].filter(\n (e) => e.fileName === id,\n );\n if (fileDeclarations.length > 0) {\n const localDepClassNames = fileDeclarations.map((e) => e.className);\n outputCode += generateHmrCode(fileDeclarations, localDepClassNames);\n }\n }\n\n return { code: outputCode, map: stripped.map };\n }\n\n function resolveTsConfigPath() {\n const { root, isProd, isLib } = tsConfigResolutionContext!;\n return getTsConfigPath(\n root,\n pluginOptions.tsconfigGetter(),\n isProd,\n pluginOptions.isTest,\n isLib,\n pluginOptions.workspaceRoot,\n );\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-fast-compile',\n api: { getTsConfigPath: resolveTsConfigPath },\n enforce: 'pre' as const,\n async config(config, { command }) {\n watchMode = command === 'serve';\n const isProd = isProdMode(config.mode);\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const depOptimizer = createDepOptimizerConfig({\n tsconfig: preliminaryTsConfigPath,\n isProd,\n jit: pluginOptions.jit,\n watchMode,\n isTest: pluginOptions.isTest,\n isAstroIntegration: pluginOptions.isAstroIntegration,\n });\n\n // No `resolve.conditions` extension here: the `style` condition is\n // scoped to `.css`-extension requests by\n // `cssExtensionStyleResolverPlugin`, registered once at the\n // `angular()` factory level (which is the only public entry point\n // that wires this plugin in).\n return {\n ...(vite.rolldownVersion ? { oxc: {} as any } : { esbuild: false }),\n ...depOptimizer,\n };\n },\n async configResolved(config) {\n resolvedConfig = config;\n const integrations = await discoverAnalogIntegrations(config);\n transformFilter = integrations.transformFilter;\n componentRegistries = integrations.componentRegistries;\n },\n configureServer(server) {\n // Watch for new .ts files and scan them into the registry. Use\n // the barrel-aware scanner so a newly added re-export entry\n // (`export * from './x'`) also expands its underlying directive\n // classes — otherwise the registry stays stale until restart.\n server.watcher.on('add', async (filePath) => {\n if (\n filePath.endsWith('.ts') &&\n !filePath.endsWith('.spec.ts') &&\n !filePath.endsWith('.d.ts')\n ) {\n await scanBarrelExports(filePath, new Set(), true);\n }\n });\n },\n async buildStart() {\n await initFastCompile();\n },\n closeBundle() {\n if (!watchMode) {\n releaseCssPreprocessorWorkers();\n }\n },\n async handleHotUpdate(ctx) {\n // Resource file changes → invalidate parent .ts module\n if (resourceToSource.has(ctx.file)) {\n const parentSource = resourceToSource.get(ctx.file)!;\n const parentModule = ctx.server.moduleGraph.getModuleById(parentSource);\n if (parentModule) {\n return [parentModule];\n }\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n // Remove old entries from this file\n const oldEntries = [...registry.entries()]\n .filter(([_, v]) => v.fileName === fileId)\n .map(([k]) => k);\n for (const key of oldEntries) {\n registry.delete(key);\n }\n\n // Rescan the changed file via the barrel-aware scanner so an\n // edited barrel re-export picks up newly-referenced files.\n // Pass overwrite=true so updated metadata replaces stale\n // entries from the previous scan.\n await scanBarrelExports(fileId, new Set(), true);\n }\n\n // Let Vite handle the rest — the transform hook will recompile\n return ctx.modules;\n },\n resolveId(id, importer) {\n if (id.startsWith(VIRTUAL_RAW_PREFIX)) {\n return `\\0${id}`;\n }\n\n if (pluginOptions.jit && id.startsWith('angular:jit:')) {\n const filePath = normalizePath(\n resolve(dirname(importer as string), id.split(';')[1]),\n );\n if (id.includes(':style')) {\n markStylePathSafe(resolvedConfig, filePath);\n return filePath + '?inline';\n }\n return toVirtualRawId(filePath);\n }\n\n const rawRewrite = rewriteHtmlRawImport(id, importer);\n if (rawRewrite) return rawRewrite;\n\n // User `.scss?inline` / `.css?inline` imports: resolve and mark\n // safe so Vite's native CSS pipeline handles them.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id) && importer) {\n const filePath = id.split('?')[0];\n const resolved = isAbsolute(filePath)\n ? normalizePath(filePath)\n : normalizePath(resolve(dirname(importer), filePath));\n markStylePathSafe(resolvedConfig, resolved);\n return resolved + '?inline';\n }\n\n return undefined;\n },\n async load(id) {\n const rawModule = await loadVirtualRawModule(this, id);\n if (rawModule !== undefined) return rawModule;\n\n // Vitest fallback: module-runner can skip resolveId, so the bare\n // ?inline query reaches load. Mark safe and let Vite handle it.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id)) {\n markStylePathSafe(resolvedConfig, id.split('?')[0]);\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n // `?raw` ids already carry Vite's native raw-loader output\n // (`export default \"<source>\"`). Recompiling them as Angular/TS\n // would strip that default export, so leave them to Vite (#2356).\n exclude: [\n /node_modules/,\n 'type=script',\n '@ng/component',\n /[?&]raw\\b/,\n ],\n },\n },\n async handler(code, id) {\n if (transformFilter && !transformFilter(code, id)) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n return handleFastCompileTransform(code, id);\n },\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fast-compile-plugin.js","names":[],"sources":["../../../src/lib/fast-compile-plugin.ts"],"sourcesContent":["import { promises as fsPromises } from 'node:fs';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport { parseSync } from 'oxc-parser';\nimport * as vite from 'vite';\n\nimport * as compilerCli from '@angular/compiler-cli';\nimport { normalizePath, Plugin, preprocessCSS, ResolvedConfig } from 'vite';\n\nimport {\n compile,\n scanFile,\n scanPackageDts,\n collectImportedPackages,\n collectRelativeReExports,\n collectAllImports,\n jitTransform,\n inlineResourceUrls,\n extractInlineStyles,\n generateHmrCode,\n debugCompile,\n debugRegistry,\n ANGULAR_DECORATOR_CALL_RE,\n type ComponentRegistry,\n} from './compiler/index.js';\n\nimport {\n TS_EXT_REGEX,\n getTsConfigPath,\n createDepOptimizerConfig,\n isProdMode,\n type TsConfigResolutionContext,\n} from './utils/plugin-config.js';\nimport { releaseCssPreprocessorWorkers } from './utils/css-preprocessor-workers.js';\nimport { VIRTUAL_RAW_PREFIX, toVirtualRawId } from './utils/virtual-ids.js';\nimport {\n loadVirtualRawModule,\n rewriteHtmlRawImport,\n} from './utils/virtual-resources.js';\nimport { markStylePathSafe } from './utils/safe-module-paths.js';\nimport {\n discoverAnalogIntegrations,\n type ComponentRegistryEntries,\n type TransformFilter,\n} from './analog-plugin-interop.js';\n\nexport interface FastCompilePluginOptions {\n tsconfigGetter: () => string;\n workspaceRoot: string;\n inlineStylesExtension: string;\n jit: boolean;\n liveReload: boolean;\n isTest: boolean;\n isAstroIntegration: boolean;\n fastCompileMode?: 'full' | 'partial';\n}\n\n/**\n * Directory that `compilerOptions.paths` targets resolve against. Mirrors\n * TypeScript: `baseUrl` when set, otherwise the directory of the config\n * that declares `paths` (`pathsBasePath`, since `baseUrl` is optional\n * from TS 4.1).\n */\nexport function getPathsBasePath(\n options: { baseUrl?: string; pathsBasePath?: string } | undefined,\n fallback: string,\n): string {\n return options?.baseUrl ?? options?.pathsBasePath ?? fallback;\n}\n\nexport function fastCompilePlugin(\n pluginOptions: FastCompilePluginOptions,\n): Plugin {\n let resolvedConfig: ResolvedConfig;\n let transformFilter: TransformFilter | undefined;\n let componentRegistries: ComponentRegistryEntries[] = [];\n let tsConfigResolutionContext: TsConfigResolutionContext | null = null;\n let watchMode = false;\n\n // fast-compile plugin state\n const registry: ComponentRegistry = new Map();\n const resourceToSource = new Map<string, string>();\n const scannedDtsPackages = new Set<string>();\n let projectRoot = '';\n let useDefineForClassFields = true;\n\n /**\n * Scan a file into the registry, then recursively walk its relative\n * `export *` / `export { … } from './x'` chain so any underlying\n * directive classes also land in the registry. Used both at\n * `buildStart` (for tsconfig path entries) and at dev time (file\n * `add` and `handleHotUpdate`) so newly added barrels stay in sync\n * without requiring a server restart.\n *\n * The `visited` set prevents infinite recursion within a single\n * top-level call. Each fresh scan should pass an empty set (so HMR\n * re-scans aren't blocked by buildStart's earlier visits).\n *\n * `fileContents`/`scanResults` are cold-start dedup caches scoped to a\n * single `initFastCompile` call. HMR/watcher callers must omit them so\n * an edited file is always re-read from disk.\n */\n async function scanBarrelExports(\n file: string,\n visited: Set<string> = new Set(),\n overwrite = false,\n fileContents?: Map<string, string>,\n scanResults?: Map<string, ReturnType<typeof scanFile>>,\n ): Promise<void> {\n if (visited.has(file)) return;\n visited.add(file);\n let code: string;\n try {\n code =\n fileContents?.get(file) ?? (await fsPromises.readFile(file, 'utf-8'));\n fileContents?.set(file, code);\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: failed to read %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return;\n }\n // Single parse shared by scanFile and collectRelativeReExports. On a\n // parse error each consumer re-parses on its own, preserving their\n // individual failure semantics (scanFile throws past its pre-filter;\n // collectRelativeReExports swallows and returns []).\n let program: ReturnType<typeof parseSync>['program'] | undefined;\n try {\n program = parseSync(file, code).program;\n } catch {\n program = undefined;\n }\n let entries = scanResults?.get(file);\n if (!entries) {\n entries = scanFile(code, file, program);\n scanResults?.set(file, entries);\n }\n for (const entry of entries) {\n // At buildStart we want stable registry entries (don't overwrite\n // an earlier scan with a barrel re-scan); HMR explicitly asks\n // for overwrite so updated metadata replaces stale entries.\n if (overwrite || !registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n // Collect every relative re-export specifier via OXC AST so\n // recursive scans can't trip over each other (a shared `/g` regex\n // would have its `lastIndex` reset by each recursive call and\n // silently skip half of an outer barrel's re-exports, which\n // previously left directives like `HlmRadioGroup` unregistered).\n const dir = dirname(file);\n for (const rel of collectRelativeReExports(code, file, program)) {\n // NodeNext-style libraries write `export * from './foo.js'`\n // even though the source is `./foo.ts`. Strip the ESM\n // extension before probing or the candidates would be\n // `foo.js.ts` / `foo.js/index.ts`, which never exist.\n const normalizedRel = rel.replace(/\\.(?:js|mjs)$/u, '');\n const reExportCandidates = [\n resolve(dir, normalizedRel + '.ts'),\n resolve(dir, normalizedRel, 'index.ts'),\n ];\n let resolved = false;\n for (const candidate of reExportCandidates) {\n try {\n await fsPromises.access(candidate);\n await scanBarrelExports(\n candidate,\n visited,\n overwrite,\n fileContents,\n scanResults,\n );\n resolved = true;\n break;\n } catch {\n // try next candidate\n }\n }\n if (!resolved && debugRegistry.enabled) {\n debugRegistry(\n 'scanBarrelExports: %s re-export %s did not resolve to %o',\n file,\n rel,\n reExportCandidates,\n );\n }\n }\n }\n\n async function initFastCompile() {\n if (pluginOptions.jit) return; // JIT: no registry scan needed\n\n // Scan all source files to build the registry\n registry.clear();\n scannedDtsPackages.clear();\n const resolvedTsConfigPath = resolveTsConfigPath();\n projectRoot = dirname(resolvedTsConfigPath);\n const config = compilerCli.readConfiguration(resolvedTsConfigPath);\n useDefineForClassFields = config.options?.useDefineForClassFields ?? true;\n\n // Collect candidate files: tsconfig rootNames PLUS the entry points\n // named in `compilerOptions.paths`. App tsconfigs typically only\n // include the app's own sources, so workspace library entry barrels\n // (e.g. `HlmSelectImports = [HlmSelect, HlmSelectContent, ...] as\n // const`) live outside `rootNames` and would otherwise miss the\n // initial scan. The compiler then can't see that `HlmSelectImports`\n // is a tuple barrel and emits the bare identifier into the parent\n // component's `dependencies()` list, where Angular's runtime\n // silently drops it because arrays don't have a directive def.\n const candidates = new Set<string>(config.rootNames);\n const tsPaths = config.options?.paths;\n const baseUrl = getPathsBasePath(config.options, projectRoot);\n // Cold-start dedup caches shared by the three scan phases below\n // (candidates scan, walkImports, scanBarrelExports). Scoped to this\n // init call only — HMR/watcher re-scans must hit disk fresh.\n const fileContents = new Map<string, string>();\n const scanResults = new Map<string, ReturnType<typeof scanFile>>();\n if (tsPaths) {\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n // Skip wildcard patterns — entry barrels are normally exact\n // file paths like \"libs/helm/select/src/index.ts\".\n if (target.includes('*')) continue;\n candidates.add(resolve(baseUrl, target));\n }\n }\n }\n const results = await Promise.all(\n Array.from(candidates).map(async (file) => {\n try {\n const code = await fsPromises.readFile(file, 'utf-8');\n fileContents.set(file, code);\n const entries = scanFile(code, file);\n scanResults.set(file, entries);\n return entries;\n } catch (e) {\n if (debugRegistry.enabled) {\n debugRegistry(\n 'initFastCompile: skipping unreadable %s: %s',\n file,\n (e as Error)?.message,\n );\n }\n return []; // Skip unreadable files\n }\n }),\n );\n\n for (const entries of results) {\n for (const entry of entries) {\n registry.set(entry.className, entry);\n }\n }\n\n // Walk the transitive import graph from the root files so the registry also\n // contains declarations that live in files not directly in tsconfig\n // `files`/`include` (transitively-imported app sources) and in workspace\n // libraries reached through wildcard `paths` (e.g. `@bitwarden/*`). Without\n // this, a non-standalone component's owning module can't classify its\n // declarations and `ɵɵsetComponentScope` is never emitted for it. Only\n // relative imports and `paths`-mapped (project/workspace) bare specifiers are\n // followed; true `node_modules` packages are left to the lazy `.d.ts` scanner.\n // Return *all* candidate base paths a bare specifier maps to. A `paths`\n // entry can list several fallback targets (e.g. a built `dist` path first\n // and the workspace `src` second); the caller probes them in order.\n const resolvePathSpecifier = (spec: string): string[] => {\n if (!tsPaths) return [];\n for (const [key, targets] of Object.entries(tsPaths)) {\n const list = targets as string[];\n if (key.endsWith('/*')) {\n const prefix = key.slice(0, -1);\n if (spec.startsWith(prefix)) {\n // `split('*').join(...)` substitutes the single tsconfig `*`\n // wildcard without `String.replace`'s first-match-only behavior or\n // `$`-pattern interpretation of the replacement.\n return list.map((t) =>\n resolve(baseUrl, t.split('*').join(spec.slice(prefix.length))),\n );\n }\n } else if (key === spec) {\n return list.map((t) => resolve(baseUrl, t));\n }\n }\n return [];\n };\n const probeToSource = async (base: string): Promise<string | null> => {\n const candidates = base.endsWith('.ts')\n ? [base]\n : [base + '.ts', resolve(base, 'index.ts')];\n for (const candidate of candidates) {\n try {\n await fsPromises.access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n };\n // Memoize fs probes per absolute base path. The cache stores the\n // Promise (not the settled value) so concurrent walks racing on the\n // same base collapse into a single probe.\n const baseResolveCache = new Map<string, Promise<string | null>>();\n const resolveToSource = (base: string): Promise<string | null> => {\n let probe = baseResolveCache.get(base);\n if (!probe) {\n probe = probeToSource(base);\n baseResolveCache.set(base, probe);\n }\n return probe;\n };\n // Probe each `paths` target in order; first one that resolves to source wins.\n const resolveFirstSource = async (\n bases: string[],\n ): Promise<string | null> => {\n for (const base of bases) {\n const resolved = await resolveToSource(base);\n if (resolved) return resolved;\n }\n return null;\n };\n const importWalkVisited = new Set<string>();\n // Paths-mapped resolution doesn't depend on the importer, so bare\n // specifiers can be memoized by their raw text. Relative specifiers\n // must NOT be — the same './foo' resolves differently per directory.\n const bareSpecResolveCache = new Map<string, Promise<string | null>>();\n const walkImports = async (file: string): Promise<void> => {\n if (importWalkVisited.has(file)) return;\n importWalkVisited.add(file);\n let code: string;\n try {\n code =\n fileContents.get(file) ?? (await fsPromises.readFile(file, 'utf-8'));\n fileContents.set(file, code);\n } catch {\n return;\n }\n // Single parse shared by scanFile, collectImportedPackages, and\n // collectAllImports. On a parse error each consumer re-parses on\n // its own, preserving their individual failure semantics.\n let program: ReturnType<typeof parseSync>['program'] | undefined;\n try {\n program = parseSync(file, code).program;\n } catch {\n program = undefined;\n }\n let entries = scanResults.get(file);\n if (!entries) {\n entries = scanFile(code, file, program);\n scanResults.set(file, entries);\n }\n for (const entry of entries) {\n if (!registry.has(entry.className))\n registry.set(entry.className, entry);\n }\n // Pre-scan the `.d.ts` of every external package this file imports (and,\n // transitively, packages those packages' NgModules re-export — e.g.\n // BrowserModule → CommonModule → NgIf). Doing this at buildStart means the\n // registry is complete before any component transforms, so non-standalone\n // component scope resolves regardless of file transform order.\n for (const pkg of collectImportedPackages(code, file, program)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n try {\n for (const entry of scanPackageDts(\n pkg,\n projectRoot,\n scannedDtsPackages,\n )) {\n if (!registry.has(entry.className))\n registry.set(entry.className, entry);\n }\n } catch {\n // Package may not have .d.ts or not be Angular\n }\n }\n const dir = dirname(file);\n const targets = await Promise.all(\n collectAllImports(code, file, program).map((spec) => {\n if (spec.startsWith('.')) {\n return resolveToSource(\n resolve(dir, spec.replace(/\\.(?:js|mjs)$/u, '')),\n );\n }\n let resolved = bareSpecResolveCache.get(spec);\n if (!resolved) {\n resolved = resolveFirstSource(resolvePathSpecifier(spec));\n bareSpecResolveCache.set(spec, resolved);\n }\n return resolved;\n }),\n );\n await Promise.all(\n targets.filter((t): t is string => !!t).map((t) => walkImports(t)),\n );\n };\n await Promise.all(config.rootNames.map((file) => walkImports(file)));\n\n // Library barrels typically `export * from './lib/...'` rather than\n // declaring directives directly, so the entry file alone gives us\n // the tuple consts but not the directive classes they reference.\n // Walk the relative `export *` chain so the underlying classes also\n // land in the registry. Use a SHARED visited set across all\n // barrels so recursive walks don't double-scan a file that's\n // re-exported from multiple entry points.\n const buildStartVisited = new Set<string>();\n if (tsPaths) {\n const barrelCandidates: string[] = [];\n for (const targets of Object.values(tsPaths)) {\n for (const target of targets as string[]) {\n if (target.includes('*')) continue;\n barrelCandidates.push(resolve(baseUrl, target));\n }\n }\n await Promise.all(\n barrelCandidates.map((c) =>\n scanBarrelExports(\n c,\n buildStartVisited,\n false,\n fileContents,\n scanResults,\n ),\n ),\n );\n }\n debugRegistry(\n 'initFastCompile done: %d entries from %d candidate files',\n registry.size,\n candidates.size,\n );\n }\n\n function ensureDtsRegistryForSource(\n code: string,\n id: string,\n program?: ReturnType<typeof parseSync>['program'],\n ) {\n for (const pkg of collectImportedPackages(code, id, program)) {\n if (scannedDtsPackages.has(pkg)) continue;\n scannedDtsPackages.add(pkg);\n\n try {\n const dtsEntries = scanPackageDts(pkg, projectRoot, scannedDtsPackages);\n for (const entry of dtsEntries) {\n if (!registry.has(entry.className)) {\n registry.set(entry.className, entry);\n }\n }\n } catch {\n // Package may not have .d.ts files or may not be Angular\n }\n }\n }\n\n async function handleFastCompileTransform(\n code: string,\n id: string,\n ): Promise<{ code: string; map: any } | undefined> {\n if (!ANGULAR_DECORATOR_CALL_RE.test(code)) {\n // Non-Angular file — strip TS-only syntax ourselves so barrels\n // like `export { Foo, type Bar } from './x'` and other TS-only\n // forms don't leak unstripped to Rolldown. In rolldown-vite the\n // built-in `vite:oxc` strip is registered as a Rust-side native\n // plugin (`viteTransformPlugin` from `rolldown/experimental`); if\n // its hook-filter treats files our `transform.filter.id.include`\n // claimed as already-handled, no JS-side fallback runs and raw\n // TS reaches the parser → `SyntaxError: Unexpected identifier`.\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(code, id, {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n })\n : await vite.transformWithEsbuild(code, id, {\n loader: 'ts',\n sourcemap: true,\n });\n return { code: stripped.code, map: stripped.map };\n }\n\n // JIT mode\n if (pluginOptions.jit) {\n const result = jitTransform(code, id);\n // Strip TypeScript-only syntax (e.g. `readonly`, parameter property\n // modifiers, type annotations on fields) so the output is valid JS\n // for Rolldown. `angularVitestSourcemapPlugin` normally runs this\n // strip downstream in tests, but it is intentionally skipped on\n // StackBlitz / WebContainer — and the production build pipeline\n // does not register it either — so the JIT path must self-strip\n // to stay safe across environments.\n //\n // Pass the jitTransform map as `inMap` so OXC/esbuild emit a map\n // composed with the original `.ts` source — without this, debug\n // stack traces and breakpoints land on the wrong lines once the\n // strip removes any TS-only token. `jitTransform` returns\n // `map: null` for files with no Angular class (no edits made);\n // passing that to OXC/esbuild as `inMap` throws, so coerce to\n // `undefined` in that case.\n const inMap = result.map ?? undefined;\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(\n result.code,\n id,\n {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n },\n inMap,\n )\n : await vite.transformWithEsbuild(\n result.code,\n id,\n { loader: 'ts', sourcemap: true },\n inMap,\n );\n return { code: stripped.code, map: stripped.map };\n }\n\n // Inline external templateUrl/styleUrl(s) into the source before compilation.\n // `styleExtensions` carries the source extension of each inlined external\n // style so it can be preprocessed by its own file type (e.g. an external\n // `.scss` styleUrl) regardless of the `inlineStylesExtension` option.\n const inlined = await inlineResourceUrls(code, id);\n code = inlined.code;\n const { styleExtensions } = inlined;\n\n // Track inlined resources for HMR. `compile()` only reports resources it\n // reads through its own fallback (a templateUrl/styleUrl the inliner did\n // NOT already inline), so files inlined here must be recorded here or a\n // later edit to them never invalidates the owning module.\n for (const dep of inlined.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Single OXC parse of the post-inline source, shared by every AST\n // consumer below. `inlineResourceUrls` parsed the PRE-inline string,\n // so its program can never be reused here.\n const { program: oxcProgram } = parseSync(id, code);\n\n // Pre-resolve inline styles that need preprocessing (SCSS/Sass/Less). Run\n // whenever a style needs a non-`css` preprocessor — either the configured\n // `inlineStylesExtension` for truly-inline styles, or an external styleUrl's\n // own extension.\n let resolvedInlineStyles: Map<number, string> | undefined;\n\n const inlineExt = pluginOptions.inlineStylesExtension;\n const styleNeedsPreprocess = (ext: string) => ext !== '' && ext !== 'css';\n\n if (styleNeedsPreprocess(inlineExt) || styleExtensions.size > 0) {\n const styleStrings = extractInlineStyles(code, id, oxcProgram);\n\n if (styleStrings.length > 0) {\n resolvedInlineStyles = new Map();\n for (let i = 0; i < styleStrings.length; i++) {\n // External styleUrls are preprocessed by their own extension; truly\n // inline `styles: [...]` fall back to `inlineStylesExtension`.\n const ext = styleExtensions.get(i) ?? inlineExt;\n if (!styleNeedsPreprocess(ext)) continue;\n try {\n const fakePath = id.replace(/\\.ts$/, `.inline-${i}.${ext}`);\n const processed = await preprocessCSS(\n styleStrings[i],\n fakePath,\n resolvedConfig,\n );\n resolvedInlineStyles.set(i, processed.code);\n } catch (e) {\n if (debugCompile.enabled) {\n debugCompile(\n 'inline style #%d preprocessing failed in %s: %s',\n i,\n id,\n (e as Error)?.message,\n );\n }\n // Skip styles that can't be preprocessed\n }\n }\n if (resolvedInlineStyles.size === 0) resolvedInlineStyles = undefined;\n }\n }\n\n ensureDtsRegistryForSource(code, id, oxcProgram);\n\n // Merge registries contributed through `analog.setup()` into this\n // compile's lookup view. Out-of-tree compilers register directive\n // metadata for classes fastCompile can't reach through its\n // tsconfig-driven scan (e.g. `.tsrx` files compiled by `@tsrx/analog`).\n // Without this merge, a TS `@Component({ imports: [X] })` that\n // references such a class hits `_unresolved-${className}` as its\n // selector and the tag never matches at runtime.\n let compileRegistry: ComponentRegistry = registry;\n if (componentRegistries.some((external) => external.size > 0)) {\n compileRegistry = new Map(registry);\n for (const external of componentRegistries) {\n for (const [k, v] of external) compileRegistry.set(k, v);\n }\n }\n\n const result = compile(code, id, {\n registry: compileRegistry,\n resolvedInlineStyles,\n useDefineForClassFields,\n compilationMode: pluginOptions.fastCompileMode,\n oxcProgram,\n });\n\n // Track resource dependencies for HMR\n for (const dep of result.resourceDependencies) {\n resourceToSource.set(dep, id);\n }\n\n // Strip TypeScript-only syntax and compose the compiler map with the\n // final generated code so downstream breakpoints map back to the source.\n const stripped = vite.transformWithOxc\n ? await vite.transformWithOxc(\n result.code,\n id,\n {\n lang: 'ts',\n sourcemap: true,\n decorator: { legacy: false, emitDecoratorMetadata: false },\n },\n result.map,\n )\n : await vite.transformWithEsbuild(\n result.code,\n id,\n { loader: 'ts', sourcemap: true },\n result.map,\n );\n let outputCode = stripped.code;\n\n // Append HMR code in dev mode\n if (watchMode && pluginOptions.liveReload) {\n const fileDeclarations = [...registry.values()].filter(\n (e) => e.fileName === id,\n );\n if (fileDeclarations.length > 0) {\n const localDepClassNames = fileDeclarations.map((e) => e.className);\n outputCode += generateHmrCode(fileDeclarations, localDepClassNames);\n }\n }\n\n return { code: outputCode, map: stripped.map };\n }\n\n function resolveTsConfigPath() {\n const { root, isProd, isLib } = tsConfigResolutionContext!;\n return getTsConfigPath(\n root,\n pluginOptions.tsconfigGetter(),\n isProd,\n pluginOptions.isTest,\n isLib,\n pluginOptions.workspaceRoot,\n );\n }\n\n return {\n name: '@analogjs/vite-plugin-angular-fast-compile',\n api: { getTsConfigPath: resolveTsConfigPath },\n enforce: 'pre' as const,\n async config(config, { command }) {\n watchMode = command === 'serve';\n const isProd = isProdMode(config.mode);\n\n tsConfigResolutionContext = {\n root: config.root || '.',\n isProd,\n isLib: !!config?.build?.lib,\n };\n\n const preliminaryTsConfigPath = resolveTsConfigPath();\n\n const depOptimizer = createDepOptimizerConfig({\n tsconfig: preliminaryTsConfigPath,\n isProd,\n jit: pluginOptions.jit,\n watchMode,\n isTest: pluginOptions.isTest,\n isAstroIntegration: pluginOptions.isAstroIntegration,\n });\n\n // No `resolve.conditions` extension here: the `style` condition is\n // scoped to `.css`-extension requests by\n // `cssExtensionStyleResolverPlugin`, registered once at the\n // `angular()` factory level (which is the only public entry point\n // that wires this plugin in).\n return {\n ...(vite.rolldownVersion ? { oxc: {} as any } : { esbuild: false }),\n ...depOptimizer,\n };\n },\n async configResolved(config) {\n resolvedConfig = config;\n const integrations = await discoverAnalogIntegrations(config);\n transformFilter = integrations.transformFilter;\n componentRegistries = integrations.componentRegistries;\n },\n configureServer(server) {\n // Watch for new .ts files and scan them into the registry. Use\n // the barrel-aware scanner so a newly added re-export entry\n // (`export * from './x'`) also expands its underlying directive\n // classes — otherwise the registry stays stale until restart.\n server.watcher.on('add', async (filePath) => {\n if (\n filePath.endsWith('.ts') &&\n !filePath.endsWith('.spec.ts') &&\n !filePath.endsWith('.d.ts')\n ) {\n await scanBarrelExports(filePath, new Set(), true);\n }\n });\n },\n async buildStart() {\n await initFastCompile();\n },\n closeBundle() {\n if (!watchMode) {\n releaseCssPreprocessorWorkers();\n }\n },\n async handleHotUpdate(ctx) {\n // Resource file changes → invalidate parent .ts module\n if (resourceToSource.has(ctx.file)) {\n const parentSource = resourceToSource.get(ctx.file)!;\n const parentModule = ctx.server.moduleGraph.getModuleById(parentSource);\n if (parentModule) {\n return [parentModule];\n }\n }\n\n if (TS_EXT_REGEX.test(ctx.file)) {\n const [fileId] = ctx.file.split('?');\n\n // Remove old entries from this file\n const oldEntries = [...registry.entries()]\n .filter(([_, v]) => v.fileName === fileId)\n .map(([k]) => k);\n for (const key of oldEntries) {\n registry.delete(key);\n }\n\n // Rescan the changed file via the barrel-aware scanner so an\n // edited barrel re-export picks up newly-referenced files.\n // Pass overwrite=true so updated metadata replaces stale\n // entries from the previous scan.\n await scanBarrelExports(fileId, new Set(), true);\n }\n\n // Let Vite handle the rest — the transform hook will recompile\n return ctx.modules;\n },\n resolveId(id, importer) {\n if (id.startsWith(VIRTUAL_RAW_PREFIX)) {\n return `\\0${id}`;\n }\n\n if (pluginOptions.jit && id.startsWith('angular:jit:')) {\n const filePath = normalizePath(\n resolve(dirname(importer as string), id.split(';')[1]),\n );\n if (id.includes(':style')) {\n markStylePathSafe(resolvedConfig, filePath);\n return filePath + '?inline';\n }\n return toVirtualRawId(filePath);\n }\n\n const rawRewrite = rewriteHtmlRawImport(id, importer);\n if (rawRewrite) return rawRewrite;\n\n // User `.scss?inline` / `.css?inline` imports: resolve and mark\n // safe so Vite's native CSS pipeline handles them.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id) && importer) {\n const filePath = id.split('?')[0];\n const resolved = isAbsolute(filePath)\n ? normalizePath(filePath)\n : normalizePath(resolve(dirname(importer), filePath));\n markStylePathSafe(resolvedConfig, resolved);\n return resolved + '?inline';\n }\n\n return undefined;\n },\n async load(id) {\n const rawModule = await loadVirtualRawModule(this, id);\n if (rawModule !== undefined) return rawModule;\n\n // Vitest fallback: module-runner can skip resolveId, so the bare\n // ?inline query reaches load. Mark safe and let Vite handle it.\n if (/\\.(css|scss|sass|less)\\?inline$/.test(id)) {\n markStylePathSafe(resolvedConfig, id.split('?')[0]);\n }\n\n return;\n },\n transform: {\n filter: {\n id: {\n include: [TS_EXT_REGEX],\n // `?raw` ids already carry Vite's native raw-loader output\n // (`export default \"<source>\"`). Recompiling them as Angular/TS\n // would strip that default export, so leave them to Vite (#2356).\n exclude: [\n /node_modules/,\n 'type=script',\n '@ng/component',\n /[?&]raw\\b/,\n ],\n },\n },\n async handler(code, id) {\n if (transformFilter && !transformFilter(code, id)) {\n return;\n }\n\n if (id.includes('.ts?')) {\n id = id.replace(/\\?(.*)/, '');\n }\n return handleFastCompileTransform(code, id);\n },\n },\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","names":[],"sources":["../../../src/lib/host.ts"],"sourcesContent":["import type { CompilerHost } from '@angular/compiler-cli';\nimport { normalizePath } from 'vite';\n\nimport * as ts from 'typescript';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport {\n normalizeStylesheetDependencies,\n type StylePreprocessor,\n} from './style-preprocessor.js';\nimport {\n AnalogStylesheetRegistry,\n preprocessStylesheetResult,\n registerStylesheetContent,\n} from './stylesheet-registry.js';\nimport { debugStyles } from './utils/debug.js';\nimport type { SourceFileCache } from './utils/source-file-cache.js';\nimport { EXCLUDED_TS_EXT_REGEX, TS_EXT_REGEX } from './utils/plugin-config.js';\n\nexport function augmentHostWithModuleResolution(\n host: ts.CompilerHost,\n options: ts.CompilerOptions,\n): void {\n const resolutionCache = ts.createModuleResolutionCache(\n host.getCurrentDirectory(),\n host.getCanonicalFileName.bind(host),\n options,\n );\n host.getModuleResolutionCache = () => resolutionCache;\n host.resolveModuleNameLiterals = (\n literals,\n containingFile,\n redirectedReference,\n compilerOptions,\n containingSourceFile,\n ) =>\n literals.map((literal) => {\n const resolution: ts.ResolvedModuleWithFailedLookupLocations =\n ts.resolveModuleName(\n literal.text,\n containingFile,\n compilerOptions,\n host,\n resolutionCache,\n redirectedReference,\n ts.getModeForUsageLocation(\n containingSourceFile,\n literal,\n compilerOptions,\n ),\n );\n const resolvedModule = resolution.resolvedModule;\n if (\n resolvedModule?.isExternalLibraryImport &&\n TS_EXT_REGEX.test(resolvedModule.resolvedFileName) &&\n !EXCLUDED_TS_EXT_REGEX.test(resolvedModule.resolvedFileName) &&\n !normalizePath(resolvedModule.resolvedFileName).includes(\n '/node_modules/',\n )\n ) {\n // A workspace symlink resolves to source outside node_modules.\n // Classify it before program creation so TypeScript emits it.\n return {\n ...resolution,\n resolvedModule: {\n ...resolvedModule,\n isExternalLibraryImport: false,\n },\n };\n }\n return resolution;\n });\n}\n\nexport function augmentHostWithResources(\n host: ts.CompilerHost,\n transform: (\n code: string,\n id: string,\n options?: { ssr?: boolean },\n ) => ReturnType<any> | null,\n options: {\n inlineStylesExtension: string;\n isProd?: boolean;\n stylesheetRegistry?: AnalogStylesheetRegistry;\n sourceFileCache?: SourceFileCache;\n stylePreprocessor?: StylePreprocessor;\n },\n): void {\n const resourceHost = host as CompilerHost;\n\n resourceHost.readResource = async function (fileName: string) {\n const filePath = normalizePath(fileName);\n\n const content = (this as any).readFile(filePath);\n\n if (content === undefined) {\n throw new Error('Unable to locate component resource: ' + fileName);\n }\n\n return content;\n };\n\n resourceHost.getModifiedResourceFiles = function () {\n return options?.sourceFileCache?.modifiedFiles;\n };\n\n resourceHost.transformResource = async function (data, context) {\n // Only style resources are supported currently\n if (context.type !== 'style') {\n return null;\n }\n\n const filename =\n context.resourceFile ??\n context.containingFile.replace(\n '.ts',\n `.${options?.inlineStylesExtension}`,\n );\n const preprocessed = preprocessStylesheetResult(\n data,\n filename,\n options.stylePreprocessor,\n {\n filename,\n containingFile: context.containingFile,\n resourceFile: context.resourceFile ?? undefined,\n className: context.className,\n order: context.order,\n inline: !context.resourceFile,\n },\n );\n\n // Externalized path: store preprocessed CSS for Vite's serve-time pipeline.\n // CSS must NOT be transformed here — the load hook returns it into\n // Vite's transform pipeline where PostCSS / Tailwind process it once.\n if (options.stylesheetRegistry) {\n const stylesheetId = registerStylesheetContent(\n options.stylesheetRegistry,\n {\n code: preprocessed.code,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n containingFile: context.containingFile,\n className: context.className,\n order: context.order,\n inlineStylesExtension: options.inlineStylesExtension,\n resourceFile: context.resourceFile ?? undefined,\n },\n );\n debugStyles('NgtscProgram: stylesheet deferred to Vite pipeline', {\n stylesheetId,\n resourceFile: context.resourceFile ?? '(inline)',\n dependencies: preprocessed.dependencies,\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n });\n return { content: stylesheetId };\n }\n\n // Non-externalized: CSS is returned directly to the Angular compiler\n // and never re-enters Vite's pipeline, so transform eagerly.\n debugStyles('NgtscProgram: stylesheet processed inline via transform', {\n filename,\n resourceFile: context.resourceFile ?? '(inline)',\n dataLength: preprocessed.code.length,\n });\n let stylesheetResult;\n\n try {\n stylesheetResult = await transform(\n preprocessed.code,\n `${filename}?direct`,\n );\n } catch (e) {\n debugStyles('NgtscProgram: stylesheet transform error', {\n filename,\n resourceFile: context.resourceFile ?? '(inline)',\n error: String(e),\n });\n }\n\n if (!stylesheetResult?.code) {\n return null;\n }\n\n return { content: stylesheetResult.code };\n };\n\n resourceHost.resourceNameToFileName = function (\n resourceName,\n containingFile,\n fallbackResolve,\n ) {\n // Angular's fallbackResolve callback expects (resourceUrl, containingFile),\n // NOT (directory, resourceName). Use it correctly or fall back to\n // path.join for simple relative paths.\n let resolved: string | null = null;\n if (fallbackResolve) {\n resolved = fallbackResolve(path.dirname(containingFile), resourceName);\n }\n const resolvedPath = normalizePath(\n resolved ?? path.join(path.dirname(containingFile), resourceName),\n );\n\n // All resource names that have template file extensions are assumed to be templates\n if (!options.stylesheetRegistry || !hasStyleExtension(resolvedPath)) {\n return resolvedPath;\n }\n\n // Register the hash-based external mapping so the resolveId hook can\n // resolve Angular's compiled stylesheet references back to the source.\n const externalId = createHash('sha256').update(resolvedPath).digest('hex');\n const filename = externalId + path.extname(resolvedPath);\n\n options.stylesheetRegistry.registerExternalRequest(filename, resolvedPath);\n debugStyles('NgtscProgram: external stylesheet ID mapped for resolveId', {\n resourceName,\n resolvedPath,\n filename,\n });\n\n // Return the real path so Angular can read the file during analysis.\n // Previously, returning the hash-based filename caused \"Could not find\n // stylesheet file\" errors because the hash doesn't exist on disk,\n // preventing AOT compilation for any component with styleUrls. (#2293)\n return resolvedPath;\n };\n}\n\nexport function augmentProgramWithVersioning(program: ts.Program): void {\n const baseGetSourceFiles = program.getSourceFiles;\n program.getSourceFiles = function (...parameters) {\n const files: readonly (ts.SourceFile & { version?: string })[] =\n baseGetSourceFiles(...parameters);\n\n for (const file of files) {\n file.version ??= createHash('sha256').update(file.text).digest('hex');\n }\n\n return files;\n };\n}\n\nexport function augmentHostWithCaching(\n host: ts.CompilerHost,\n cache: Map<string, ts.SourceFile>,\n): void {\n const baseGetSourceFile = host.getSourceFile;\n host.getSourceFile = function (\n fileName,\n languageVersion,\n onError,\n shouldCreateNewSourceFile,\n ...parameters\n ) {\n if (!shouldCreateNewSourceFile && cache.has(fileName)) {\n return cache.get(fileName);\n }\n\n const file = baseGetSourceFile.call(\n host,\n fileName,\n languageVersion,\n onError,\n true,\n ...parameters,\n );\n\n if (file) {\n cache.set(fileName, file);\n }\n\n return file;\n };\n}\n\nexport function mergeTransformers(\n first: ts.CustomTransformers,\n second: ts.CustomTransformers,\n): ts.CustomTransformers {\n const result: ts.CustomTransformers = {};\n\n if (first.before || second.before) {\n result.before = [...(first.before || []), ...(second.before || [])];\n }\n\n if (first.after || second.after) {\n result.after = [...(first.after || []), ...(second.after || [])];\n }\n\n if (first.afterDeclarations || second.afterDeclarations) {\n result.afterDeclarations = [\n ...(first.afterDeclarations || []),\n ...(second.afterDeclarations || []),\n ];\n }\n\n return result;\n}\n\nfunction hasStyleExtension(file: string): boolean {\n const extension = path.extname(file).toLowerCase();\n\n switch (extension) {\n case '.css':\n case '.scss':\n return true;\n default:\n return false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"host.js","names":[],"sources":["../../../src/lib/host.ts"],"sourcesContent":["import type { CompilerHost } from '@angular/compiler-cli';\nimport { normalizePath } from 'vite';\n\nimport * as ts from 'typescript';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport {\n normalizeStylesheetDependencies,\n type StylePreprocessor,\n} from './style-preprocessor.js';\nimport {\n AnalogStylesheetRegistry,\n preprocessStylesheetResult,\n registerStylesheetContent,\n} from './stylesheet-registry.js';\nimport { debugStyles } from './utils/debug.js';\nimport type { SourceFileCache } from './utils/source-file-cache.js';\nimport { EXCLUDED_TS_EXT_REGEX, TS_EXT_REGEX } from './utils/plugin-config.js';\n\nexport function augmentHostWithModuleResolution(\n host: ts.CompilerHost,\n options: ts.CompilerOptions,\n): void {\n const resolutionCache = ts.createModuleResolutionCache(\n host.getCurrentDirectory(),\n host.getCanonicalFileName.bind(host),\n options,\n );\n host.getModuleResolutionCache = () => resolutionCache;\n host.resolveModuleNameLiterals = (\n literals,\n containingFile,\n redirectedReference,\n compilerOptions,\n containingSourceFile,\n ) =>\n literals.map((literal) => {\n const resolution: ts.ResolvedModuleWithFailedLookupLocations =\n ts.resolveModuleName(\n literal.text,\n containingFile,\n compilerOptions,\n host,\n resolutionCache,\n redirectedReference,\n ts.getModeForUsageLocation(\n containingSourceFile,\n literal,\n compilerOptions,\n ),\n );\n const resolvedModule = resolution.resolvedModule;\n if (\n resolvedModule?.isExternalLibraryImport &&\n TS_EXT_REGEX.test(resolvedModule.resolvedFileName) &&\n !EXCLUDED_TS_EXT_REGEX.test(resolvedModule.resolvedFileName) &&\n !normalizePath(resolvedModule.resolvedFileName).includes(\n '/node_modules/',\n )\n ) {\n // A workspace symlink resolves to source outside node_modules.\n // Classify it before program creation so TypeScript emits it.\n return {\n ...resolution,\n resolvedModule: {\n ...resolvedModule,\n isExternalLibraryImport: false,\n },\n };\n }\n return resolution;\n });\n}\n\nexport function augmentHostWithResources(\n host: ts.CompilerHost,\n transform: (\n code: string,\n id: string,\n options?: { ssr?: boolean },\n ) => ReturnType<any> | null,\n options: {\n inlineStylesExtension: string;\n isProd?: boolean;\n stylesheetRegistry?: AnalogStylesheetRegistry;\n sourceFileCache?: SourceFileCache;\n stylePreprocessor?: StylePreprocessor;\n },\n): void {\n const resourceHost = host as CompilerHost;\n\n resourceHost.readResource = async function (fileName: string) {\n const filePath = normalizePath(fileName);\n\n const content = (this as any).readFile(filePath);\n\n if (content === undefined) {\n throw new Error('Unable to locate component resource: ' + fileName);\n }\n\n return content;\n };\n\n resourceHost.getModifiedResourceFiles = function () {\n return options?.sourceFileCache?.modifiedFiles;\n };\n\n resourceHost.transformResource = async function (data, context) {\n // Only style resources are supported currently\n if (context.type !== 'style') {\n return null;\n }\n\n const filename =\n context.resourceFile ??\n context.containingFile.replace(\n '.ts',\n `.${options?.inlineStylesExtension}`,\n );\n const preprocessed = preprocessStylesheetResult(\n data,\n filename,\n options.stylePreprocessor,\n {\n filename,\n containingFile: context.containingFile,\n resourceFile: context.resourceFile ?? undefined,\n className: context.className,\n order: context.order,\n inline: !context.resourceFile,\n },\n );\n\n // Externalized path: store preprocessed CSS for Vite's serve-time pipeline.\n // CSS must NOT be transformed here — the load hook returns it into\n // Vite's transform pipeline where PostCSS / Tailwind process it once.\n if (options.stylesheetRegistry) {\n const stylesheetId = registerStylesheetContent(\n options.stylesheetRegistry,\n {\n code: preprocessed.code,\n dependencies: normalizeStylesheetDependencies(\n preprocessed.dependencies,\n ),\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n containingFile: context.containingFile,\n className: context.className,\n order: context.order,\n inlineStylesExtension: options.inlineStylesExtension,\n resourceFile: context.resourceFile ?? undefined,\n },\n );\n debugStyles('NgtscProgram: stylesheet deferred to Vite pipeline', {\n stylesheetId,\n resourceFile: context.resourceFile ?? '(inline)',\n dependencies: preprocessed.dependencies,\n diagnostics: preprocessed.diagnostics,\n tags: preprocessed.tags,\n });\n return { content: stylesheetId };\n }\n\n // Non-externalized: CSS is returned directly to the Angular compiler\n // and never re-enters Vite's pipeline, so transform eagerly.\n debugStyles('NgtscProgram: stylesheet processed inline via transform', {\n filename,\n resourceFile: context.resourceFile ?? '(inline)',\n dataLength: preprocessed.code.length,\n });\n let stylesheetResult;\n\n try {\n stylesheetResult = await transform(\n preprocessed.code,\n `${filename}?direct`,\n );\n } catch (e) {\n debugStyles('NgtscProgram: stylesheet transform error', {\n filename,\n resourceFile: context.resourceFile ?? '(inline)',\n error: String(e),\n });\n }\n\n if (!stylesheetResult?.code) {\n return null;\n }\n\n return { content: stylesheetResult.code };\n };\n\n resourceHost.resourceNameToFileName = function (\n resourceName,\n containingFile,\n fallbackResolve,\n ) {\n // Angular's fallbackResolve callback expects (resourceUrl, containingFile),\n // NOT (directory, resourceName). Use it correctly or fall back to\n // path.join for simple relative paths.\n let resolved: string | null = null;\n if (fallbackResolve) {\n resolved = fallbackResolve(path.dirname(containingFile), resourceName);\n }\n const resolvedPath = normalizePath(\n resolved ?? path.join(path.dirname(containingFile), resourceName),\n );\n\n // All resource names that have template file extensions are assumed to be templates\n if (!options.stylesheetRegistry || !hasStyleExtension(resolvedPath)) {\n return resolvedPath;\n }\n\n // Register the hash-based external mapping so the resolveId hook can\n // resolve Angular's compiled stylesheet references back to the source.\n const externalId = createHash('sha256').update(resolvedPath).digest('hex');\n const filename = externalId + path.extname(resolvedPath);\n\n options.stylesheetRegistry.registerExternalRequest(filename, resolvedPath);\n debugStyles('NgtscProgram: external stylesheet ID mapped for resolveId', {\n resourceName,\n resolvedPath,\n filename,\n });\n\n // Return the real path so Angular can read the file during analysis.\n // Previously, returning the hash-based filename caused \"Could not find\n // stylesheet file\" errors because the hash doesn't exist on disk,\n // preventing AOT compilation for any component with styleUrls. (#2293)\n return resolvedPath;\n };\n}\n\nexport function augmentProgramWithVersioning(program: ts.Program): void {\n const baseGetSourceFiles = program.getSourceFiles;\n program.getSourceFiles = function (...parameters) {\n const files: readonly (ts.SourceFile & { version?: string })[] =\n baseGetSourceFiles(...parameters);\n\n for (const file of files) {\n file.version ??= createHash('sha256').update(file.text).digest('hex');\n }\n\n return files;\n };\n}\n\nexport function augmentHostWithCaching(\n host: ts.CompilerHost,\n cache: Map<string, ts.SourceFile>,\n): void {\n const baseGetSourceFile = host.getSourceFile;\n host.getSourceFile = function (\n fileName,\n languageVersion,\n onError,\n shouldCreateNewSourceFile,\n ...parameters\n ) {\n if (!shouldCreateNewSourceFile && cache.has(fileName)) {\n return cache.get(fileName);\n }\n\n const file = baseGetSourceFile.call(\n host,\n fileName,\n languageVersion,\n onError,\n true,\n ...parameters,\n );\n\n if (file) {\n cache.set(fileName, file);\n }\n\n return file;\n };\n}\n\nexport function mergeTransformers(\n first: ts.CustomTransformers,\n second: ts.CustomTransformers,\n): ts.CustomTransformers {\n const result: ts.CustomTransformers = {};\n\n if (first.before || second.before) {\n result.before = [...(first.before || []), ...(second.before || [])];\n }\n\n if (first.after || second.after) {\n result.after = [...(first.after || []), ...(second.after || [])];\n }\n\n if (first.afterDeclarations || second.afterDeclarations) {\n result.afterDeclarations = [\n ...(first.afterDeclarations || []),\n ...(second.afterDeclarations || []),\n ];\n }\n\n return result;\n}\n\nfunction hasStyleExtension(file: string): boolean {\n const extension = path.extname(file).toLowerCase();\n\n switch (extension) {\n case '.css':\n case '.scss':\n return true;\n default:\n return false;\n }\n}\n"],"mappings":"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"}
@@ -136,7 +136,7 @@ function createHotUpdateNotifications(hasPendingCompilations) {
136
136
  queueFlush,
137
137
  configureServer(server) {
138
138
  closed = false;
139
- const channels = new Set([server.ws, server.environments?.client.hot]);
139
+ const channels = /* @__PURE__ */ new Set([server.ws, server.environments?.client.hot]);
140
140
  for (const channel of channels) {
141
141
  if (!channel) continue;
142
142
  const original = channel.send;
@@ -1 +1 @@
1
- {"version":3,"file":"hot-update-batch.js","names":[],"sources":["../../../src/lib/hot-update-batch.ts"],"sourcesContent":["import {\n normalizePath,\n type HMRPayload,\n type Update,\n type ViteDevServer,\n} from 'vite';\n\nconst HOT_UPDATE_DEBOUNCE_MS = 100;\n\ntype Batch = {\n ids: Set<string>;\n promise: Promise<void>;\n resolve: () => void;\n reject: (error: unknown) => void;\n};\n\ntype Notification = {\n payload: HMRPayload;\n send: (payload: HMRPayload) => void;\n};\n\nexport function createHotUpdateBatcher(\n compile: (ids: string[]) => Promise<void>,\n) {\n let scheduledBatch: Batch | undefined;\n let compileTimer: ReturnType<typeof setTimeout> | undefined;\n const pendingCompilations = new Set<Promise<void>>();\n const notifications = createHotUpdateNotifications(\n () => pendingCompilations.size > 0,\n );\n\n async function run(batch: Batch) {\n scheduledBatch = undefined;\n compileTimer = undefined;\n try {\n await compile([...batch.ids]);\n batch.resolve();\n } catch (error) {\n batch.reject(error);\n } finally {\n pendingCompilations.delete(batch.promise);\n notifications.queueFlush();\n }\n }\n\n return {\n schedule(file: string, ids: string[]) {\n notifications.track(file);\n if (!scheduledBatch) {\n let resolve!: () => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n scheduledBatch = { ids: new Set(), promise, resolve, reject };\n pendingCompilations.add(promise);\n }\n const batch = scheduledBatch;\n for (const id of ids) batch.ids.add(id);\n clearTimeout(compileTimer);\n compileTimer = setTimeout(() => run(batch), HOT_UPDATE_DEBOUNCE_MS);\n return batch.promise;\n },\n async wait() {\n while (pendingCompilations.size) await Promise.all(pendingCompilations);\n },\n configureServer: notifications.configureServer,\n close() {\n clearTimeout(compileTimer);\n compileTimer = undefined;\n if (scheduledBatch) {\n pendingCompilations.delete(scheduledBatch.promise);\n scheduledBatch.reject(\n new Error('Angular hot update cancelled: server closed'),\n );\n scheduledBatch = undefined;\n }\n notifications.close();\n },\n };\n}\n\nfunction createHotUpdateNotifications(hasPendingCompilations: () => boolean) {\n const changedFiles = new Set<string>();\n const reloads = new Map<string, Notification>();\n const components = new Map<string, Notification>();\n const updates = new Map<string, Update>();\n const restoreChannels: (() => void)[] = [];\n let sendUpdates: Notification['send'] | undefined;\n let notificationTimer: ReturnType<typeof setTimeout> | undefined;\n let sending = false;\n let closed = false;\n\n function clear() {\n reloads.clear();\n components.clear();\n updates.clear();\n sendUpdates = undefined;\n }\n\n function buffer(payload: HMRPayload, send: Notification['send']) {\n switch (payload.type) {\n case 'full-reload':\n if (\n !payload.triggeredBy ||\n !changedFiles.has(normalizePath(payload.triggeredBy))\n ) {\n return false;\n }\n reloads.set(payload.path ?? '*', { payload, send });\n return true;\n case 'update':\n sendUpdates = send;\n for (const update of payload.updates) {\n const key = `${update.type}:${update.path}:${update.acceptedPath}`;\n const previous = updates.get(key);\n if (!previous || update.timestamp >= previous.timestamp) {\n updates.set(key, update);\n }\n }\n return true;\n case 'custom':\n if (payload.event !== 'angular:component-update') return false;\n components.set(payload.data.id, { payload, send });\n return true;\n default:\n return false;\n }\n }\n\n function flush() {\n notificationTimer = undefined;\n if (hasPendingCompilations()) return;\n changedFiles.clear();\n\n // A client channel can forward through server.ws; don't capture our flush again.\n sending = true;\n try {\n const reload = reloads.get('*');\n if (reload) {\n reload.send(reload.payload);\n return;\n }\n for (const { payload, send } of reloads.values()) send(payload);\n for (const { payload, send } of components.values()) send(payload);\n if (sendUpdates && updates.size) {\n sendUpdates({ type: 'update', updates: [...updates.values()] });\n }\n } finally {\n sending = false;\n clear();\n }\n }\n\n function queueFlush() {\n if (closed) return;\n clearTimeout(notificationTimer);\n // Vite propagates updates after the hot-update promises settle.\n notificationTimer = setTimeout(flush, 0);\n }\n\n return {\n track(file: string) {\n changedFiles.add(normalizePath(file));\n },\n queueFlush,\n configureServer(server: ViteDevServer) {\n closed = false;\n // Vite 6 can use a separate client channel; newer Vite shares server.ws.\n const channels = new Set([server.ws, server.environments?.client.hot]);\n for (const channel of channels) {\n if (!channel) continue;\n const original = channel.send;\n const send = original.bind(channel);\n const wrapped: typeof original = (\n payload: HMRPayload | string,\n data?: unknown,\n ) => {\n const message: HMRPayload =\n typeof payload === 'string'\n ? { type: 'custom', event: payload, data }\n : payload;\n if (!sending && changedFiles.size > 0 && buffer(message, send)) {\n queueFlush();\n return;\n }\n if (message.type === 'error') clear();\n send(message);\n };\n channel.send = wrapped;\n restoreChannels.push(() => {\n if (channel.send === wrapped) channel.send = original;\n });\n }\n },\n close() {\n closed = true;\n clearTimeout(notificationTimer);\n notificationTimer = undefined;\n changedFiles.clear();\n clear();\n for (const restore of restoreChannels.splice(0)) restore();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"hot-update-batch.js","names":[],"sources":["../../../src/lib/hot-update-batch.ts"],"sourcesContent":["import {\n normalizePath,\n type HMRPayload,\n type Update,\n type ViteDevServer,\n} from 'vite';\n\nconst HOT_UPDATE_DEBOUNCE_MS = 100;\n\ntype Batch = {\n ids: Set<string>;\n promise: Promise<void>;\n resolve: () => void;\n reject: (error: unknown) => void;\n};\n\ntype Notification = {\n payload: HMRPayload;\n send: (payload: HMRPayload) => void;\n};\n\nexport function createHotUpdateBatcher(\n compile: (ids: string[]) => Promise<void>,\n) {\n let scheduledBatch: Batch | undefined;\n let compileTimer: ReturnType<typeof setTimeout> | undefined;\n const pendingCompilations = new Set<Promise<void>>();\n const notifications = createHotUpdateNotifications(\n () => pendingCompilations.size > 0,\n );\n\n async function run(batch: Batch) {\n scheduledBatch = undefined;\n compileTimer = undefined;\n try {\n await compile([...batch.ids]);\n batch.resolve();\n } catch (error) {\n batch.reject(error);\n } finally {\n pendingCompilations.delete(batch.promise);\n notifications.queueFlush();\n }\n }\n\n return {\n schedule(file: string, ids: string[]) {\n notifications.track(file);\n if (!scheduledBatch) {\n let resolve!: () => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n scheduledBatch = { ids: new Set(), promise, resolve, reject };\n pendingCompilations.add(promise);\n }\n const batch = scheduledBatch;\n for (const id of ids) batch.ids.add(id);\n clearTimeout(compileTimer);\n compileTimer = setTimeout(() => run(batch), HOT_UPDATE_DEBOUNCE_MS);\n return batch.promise;\n },\n async wait() {\n while (pendingCompilations.size) await Promise.all(pendingCompilations);\n },\n configureServer: notifications.configureServer,\n close() {\n clearTimeout(compileTimer);\n compileTimer = undefined;\n if (scheduledBatch) {\n pendingCompilations.delete(scheduledBatch.promise);\n scheduledBatch.reject(\n new Error('Angular hot update cancelled: server closed'),\n );\n scheduledBatch = undefined;\n }\n notifications.close();\n },\n };\n}\n\nfunction createHotUpdateNotifications(hasPendingCompilations: () => boolean) {\n const changedFiles = new Set<string>();\n const reloads = new Map<string, Notification>();\n const components = new Map<string, Notification>();\n const updates = new Map<string, Update>();\n const restoreChannels: (() => void)[] = [];\n let sendUpdates: Notification['send'] | undefined;\n let notificationTimer: ReturnType<typeof setTimeout> | undefined;\n let sending = false;\n let closed = false;\n\n function clear() {\n reloads.clear();\n components.clear();\n updates.clear();\n sendUpdates = undefined;\n }\n\n function buffer(payload: HMRPayload, send: Notification['send']) {\n switch (payload.type) {\n case 'full-reload':\n if (\n !payload.triggeredBy ||\n !changedFiles.has(normalizePath(payload.triggeredBy))\n ) {\n return false;\n }\n reloads.set(payload.path ?? '*', { payload, send });\n return true;\n case 'update':\n sendUpdates = send;\n for (const update of payload.updates) {\n const key = `${update.type}:${update.path}:${update.acceptedPath}`;\n const previous = updates.get(key);\n if (!previous || update.timestamp >= previous.timestamp) {\n updates.set(key, update);\n }\n }\n return true;\n case 'custom':\n if (payload.event !== 'angular:component-update') return false;\n components.set(payload.data.id, { payload, send });\n return true;\n default:\n return false;\n }\n }\n\n function flush() {\n notificationTimer = undefined;\n if (hasPendingCompilations()) return;\n changedFiles.clear();\n\n // A client channel can forward through server.ws; don't capture our flush again.\n sending = true;\n try {\n const reload = reloads.get('*');\n if (reload) {\n reload.send(reload.payload);\n return;\n }\n for (const { payload, send } of reloads.values()) send(payload);\n for (const { payload, send } of components.values()) send(payload);\n if (sendUpdates && updates.size) {\n sendUpdates({ type: 'update', updates: [...updates.values()] });\n }\n } finally {\n sending = false;\n clear();\n }\n }\n\n function queueFlush() {\n if (closed) return;\n clearTimeout(notificationTimer);\n // Vite propagates updates after the hot-update promises settle.\n notificationTimer = setTimeout(flush, 0);\n }\n\n return {\n track(file: string) {\n changedFiles.add(normalizePath(file));\n },\n queueFlush,\n configureServer(server: ViteDevServer) {\n closed = false;\n // Vite 6 can use a separate client channel; newer Vite shares server.ws.\n const channels = new Set([server.ws, server.environments?.client.hot]);\n for (const channel of channels) {\n if (!channel) continue;\n const original = channel.send;\n const send = original.bind(channel);\n const wrapped: typeof original = (\n payload: HMRPayload | string,\n data?: unknown,\n ) => {\n const message: HMRPayload =\n typeof payload === 'string'\n ? { type: 'custom', event: payload, data }\n : payload;\n if (!sending && changedFiles.size > 0 && buffer(message, send)) {\n queueFlush();\n return;\n }\n if (message.type === 'error') clear();\n send(message);\n };\n channel.send = wrapped;\n restoreChannels.push(() => {\n if (channel.send === wrapped) channel.send = original;\n });\n }\n },\n close() {\n closed = true;\n clearTimeout(notificationTimer);\n notificationTimer = undefined;\n changedFiles.clear();\n clear();\n for (const restore of restoreChannels.splice(0)) restore();\n },\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"live-reload-plugin.js","names":[],"sources":["../../../src/lib/live-reload-plugin.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { ServerResponse } from 'node:http';\nimport { Connect, normalizePath, Plugin, ViteDevServer } from 'vite';\n\nimport { EmitFileResult } from './models.js';\nimport { debugHmr } from './utils/debug.js';\n\nconst ANGULAR_COMPONENT_PREFIX = '/@ng/component';\nconst FILE_PREFIX = 'file:';\n\nexport function liveReloadPlugin({\n classNames,\n fileEmitter,\n}: {\n classNames: Map<string, string>;\n fileEmitter: (file: string) => EmitFileResult | undefined;\n}): Plugin {\n return {\n name: 'analogjs-live-reload-plugin',\n apply: 'serve',\n configureServer(server: ViteDevServer) {\n if (server.config.server.hmr === false) {\n debugHmr('middleware disabled: vite server.hmr is false');\n return;\n }\n\n const angularComponentMiddleware: Connect.HandleFunction = async (\n req: Connect.IncomingMessage,\n res: ServerResponse<Connect.IncomingMessage>,\n next: Connect.NextFunction,\n ) => {\n if (req.url === undefined || res.writableEnded) {\n return;\n }\n\n if (!req.url.includes(ANGULAR_COMPONENT_PREFIX)) {\n next();\n\n return;\n }\n\n const requestUrl = new URL(req.url, 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n res.statusCode = 400;\n res.end();\n\n return;\n }\n\n const [fileId] = decodeURIComponent(componentId).split('@');\n const resolvedId = normalizePath(resolve(process.cwd(), fileId));\n const invalidated =\n !!server.moduleGraph.getModuleById(resolvedId)\n ?.lastInvalidationTimestamp && classNames.get(resolvedId);\n\n // don't send an HMR update until the file has been invalidated\n if (!invalidated) {\n debugHmr('middleware: skipped (not invalidated)', { resolvedId });\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end('');\n return;\n }\n\n const result = fileEmitter(resolvedId);\n debugHmr('middleware: served component update', {\n resolvedId,\n hasCode: !!result?.hmrUpdateCode,\n });\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(`${result?.hmrUpdateCode || ''}`);\n };\n\n server.middlewares.use(angularComponentMiddleware);\n },\n resolveId(id, _importer, options) {\n if (\n options?.ssr &&\n id.startsWith(FILE_PREFIX) &&\n id.includes(ANGULAR_COMPONENT_PREFIX)\n ) {\n return `\\0${id}`;\n }\n\n return undefined;\n },\n load(id, options) {\n if (options?.ssr && id.includes(ANGULAR_COMPONENT_PREFIX)) {\n const requestUrl = new URL(id.slice(1), 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n return;\n }\n\n const result = fileEmitter(\n normalizePath(\n resolve(\n process.cwd(),\n decodeURIComponent(componentId).split('@')[0],\n ),\n ),\n );\n\n return result?.hmrUpdateCode || '';\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;;AAOA,IAAM,2BAA2B;AACjC,IAAM,cAAc;AAEpB,SAAgB,iBAAiB,EAC/B,YACA,eAIS;AACT,QAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,QAAuB;AACrC,OAAI,OAAO,OAAO,OAAO,QAAQ,OAAO;AACtC,aAAS,gDAAgD;AACzD;;GAGF,MAAM,6BAAqD,OACzD,KACA,KACA,SACG;AACH,QAAI,IAAI,QAAQ,KAAA,KAAa,IAAI,cAC/B;AAGF,QAAI,CAAC,IAAI,IAAI,SAAS,yBAAyB,EAAE;AAC/C,WAAM;AAEN;;IAIF,MAAM,cADa,IAAI,IAAI,IAAI,KAAK,mBAAmB,CACxB,aAAa,IAAI,IAAI;AAEpD,QAAI,CAAC,aAAa;AAChB,SAAI,aAAa;AACjB,SAAI,KAAK;AAET;;IAGF,MAAM,CAAC,UAAU,mBAAmB,YAAY,CAAC,MAAM,IAAI;IAC3D,MAAM,aAAa,cAAc,QAAQ,QAAQ,KAAK,EAAE,OAAO,CAAC;AAMhE,QAAI,EAJF,CAAC,CAAC,OAAO,YAAY,cAAc,WAAW,EAC1C,6BAA6B,WAAW,IAAI,WAAW,GAG3C;AAChB,cAAS,yCAAyC,EAAE,YAAY,CAAC;AACjE,SAAI,UAAU,gBAAgB,kBAAkB;AAChD,SAAI,UAAU,iBAAiB,WAAW;AAC1C,SAAI,IAAI,GAAG;AACX;;IAGF,MAAM,SAAS,YAAY,WAAW;AACtC,aAAS,uCAAuC;KAC9C;KACA,SAAS,CAAC,CAAC,QAAQ;KACpB,CAAC;AACF,QAAI,UAAU,gBAAgB,kBAAkB;AAChD,QAAI,UAAU,iBAAiB,WAAW;AAC1C,QAAI,IAAI,GAAG,QAAQ,iBAAiB,KAAK;;AAG3C,UAAO,YAAY,IAAI,2BAA2B;;EAEpD,UAAU,IAAI,WAAW,SAAS;AAChC,OACE,SAAS,OACT,GAAG,WAAW,YAAY,IAC1B,GAAG,SAAS,yBAAyB,CAErC,QAAO,KAAK;;EAKhB,KAAK,IAAI,SAAS;AAChB,OAAI,SAAS,OAAO,GAAG,SAAS,yBAAyB,EAAE;IAEzD,MAAM,cADa,IAAI,IAAI,GAAG,MAAM,EAAE,EAAE,mBAAmB,CAC5B,aAAa,IAAI,IAAI;AAEpD,QAAI,CAAC,YACH;AAYF,WATe,YACb,cACE,QACE,QAAQ,KAAK,EACb,mBAAmB,YAAY,CAAC,MAAM,IAAI,CAAC,GAC5C,CACF,CACF,EAEc,iBAAiB;;;EAKrC"}
1
+ {"version":3,"file":"live-reload-plugin.js","names":[],"sources":["../../../src/lib/live-reload-plugin.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { ServerResponse } from 'node:http';\nimport { Connect, normalizePath, Plugin, ViteDevServer } from 'vite';\n\nimport { EmitFileResult } from './models.js';\nimport { debugHmr } from './utils/debug.js';\n\nconst ANGULAR_COMPONENT_PREFIX = '/@ng/component';\nconst FILE_PREFIX = 'file:';\n\nexport function liveReloadPlugin({\n classNames,\n fileEmitter,\n}: {\n classNames: Map<string, string>;\n fileEmitter: (file: string) => EmitFileResult | undefined;\n}): Plugin {\n return {\n name: 'analogjs-live-reload-plugin',\n apply: 'serve',\n configureServer(server: ViteDevServer) {\n if (server.config.server.hmr === false) {\n debugHmr('middleware disabled: vite server.hmr is false');\n return;\n }\n\n const angularComponentMiddleware: Connect.HandleFunction = async (\n req: Connect.IncomingMessage,\n res: ServerResponse<Connect.IncomingMessage>,\n next: Connect.NextFunction,\n ) => {\n if (req.url === undefined || res.writableEnded) {\n return;\n }\n\n if (!req.url.includes(ANGULAR_COMPONENT_PREFIX)) {\n next();\n\n return;\n }\n\n const requestUrl = new URL(req.url, 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n res.statusCode = 400;\n res.end();\n\n return;\n }\n\n const [fileId] = decodeURIComponent(componentId).split('@');\n const resolvedId = normalizePath(resolve(process.cwd(), fileId));\n const invalidated =\n !!server.moduleGraph.getModuleById(resolvedId)\n ?.lastInvalidationTimestamp && classNames.get(resolvedId);\n\n // don't send an HMR update until the file has been invalidated\n if (!invalidated) {\n debugHmr('middleware: skipped (not invalidated)', { resolvedId });\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end('');\n return;\n }\n\n const result = fileEmitter(resolvedId);\n debugHmr('middleware: served component update', {\n resolvedId,\n hasCode: !!result?.hmrUpdateCode,\n });\n res.setHeader('Content-Type', 'text/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(`${result?.hmrUpdateCode || ''}`);\n };\n\n server.middlewares.use(angularComponentMiddleware);\n },\n resolveId(id, _importer, options) {\n if (\n options?.ssr &&\n id.startsWith(FILE_PREFIX) &&\n id.includes(ANGULAR_COMPONENT_PREFIX)\n ) {\n return `\\0${id}`;\n }\n\n return undefined;\n },\n load(id, options) {\n if (options?.ssr && id.includes(ANGULAR_COMPONENT_PREFIX)) {\n const requestUrl = new URL(id.slice(1), 'http://localhost');\n const componentId = requestUrl.searchParams.get('c');\n\n if (!componentId) {\n return;\n }\n\n const result = fileEmitter(\n normalizePath(\n resolve(\n process.cwd(),\n decodeURIComponent(componentId).split('@')[0],\n ),\n ),\n );\n\n return result?.hmrUpdateCode || '';\n }\n\n return;\n },\n };\n}\n"],"mappings":";;;;AAOA,IAAM,2BAA2B;AACjC,IAAM,cAAc;AAEpB,SAAgB,iBAAiB,EAC/B,YACA,eAIS;CACT,OAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,QAAuB;GACrC,IAAI,OAAO,OAAO,OAAO,QAAQ,OAAO;IACtC,SAAS,+CAA+C;IACxD;GACF;GAEA,MAAM,6BAAqD,OACzD,KACA,KACA,SACG;IACH,IAAI,IAAI,QAAQ,KAAA,KAAa,IAAI,eAC/B;IAGF,IAAI,CAAC,IAAI,IAAI,SAAS,wBAAwB,GAAG;KAC/C,KAAK;KAEL;IACF;IAGA,MAAM,cAAc,IADG,IAAI,IAAI,KAAK,kBAChB,CAAA,CAAW,aAAa,IAAI,GAAG;IAEnD,IAAI,CAAC,aAAa;KAChB,IAAI,aAAa;KACjB,IAAI,IAAI;KAER;IACF;IAEA,MAAM,CAAC,UAAU,mBAAmB,WAAW,CAAC,CAAC,MAAM,GAAG;IAC1D,MAAM,aAAa,cAAc,QAAQ,QAAQ,IAAI,GAAG,MAAM,CAAC;IAM/D,IAAI,EAJF,CAAC,CAAC,OAAO,YAAY,cAAc,UAAU,CAAC,EAC1C,6BAA6B,WAAW,IAAI,UAAU,IAG1C;KAChB,SAAS,yCAAyC,EAAE,WAAW,CAAC;KAChE,IAAI,UAAU,gBAAgB,iBAAiB;KAC/C,IAAI,UAAU,iBAAiB,UAAU;KACzC,IAAI,IAAI,EAAE;KACV;IACF;IAEA,MAAM,SAAS,YAAY,UAAU;IACrC,SAAS,uCAAuC;KAC9C;KACA,SAAS,CAAC,CAAC,QAAQ;IACrB,CAAC;IACD,IAAI,UAAU,gBAAgB,iBAAiB;IAC/C,IAAI,UAAU,iBAAiB,UAAU;IACzC,IAAI,IAAI,GAAG,QAAQ,iBAAiB,IAAI;GAC1C;GAEA,OAAO,YAAY,IAAI,0BAA0B;EACnD;EACA,UAAU,IAAI,WAAW,SAAS;GAChC,IACE,SAAS,OACT,GAAG,WAAW,WAAW,KACzB,GAAG,SAAS,wBAAwB,GAEpC,OAAO,KAAK;EAIhB;EACA,KAAK,IAAI,SAAS;GAChB,IAAI,SAAS,OAAO,GAAG,SAAS,wBAAwB,GAAG;IAEzD,MAAM,cAAc,IADG,IAAI,GAAG,MAAM,CAAC,GAAG,kBACpB,CAAA,CAAW,aAAa,IAAI,GAAG;IAEnD,IAAI,CAAC,aACH;IAYF,OATe,YACb,cACE,QACE,QAAQ,IAAI,GACZ,mBAAmB,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAC7C,CACF,CAGK,CAAA,EAAQ,iBAAiB;GAClC;EAGF;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"nx-folder-plugin.js","names":[],"sources":["../../../src/lib/nx-folder-plugin.ts"],"sourcesContent":["import { normalizePath, Plugin } from 'vite';\n\n/**\n * Ignores anything in the .nx folder from triggering HMR\n *\n * @returns\n */\nexport function nxFolderPlugin(): Plugin {\n return {\n name: 'analogjs-nx-folder-plugin',\n apply: 'serve',\n handleHotUpdate(ctx) {\n if (ctx.file.includes(normalizePath('/.nx/'))) {\n return [];\n }\n\n return ctx.modules;\n },\n };\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,iBAAyB;AACvC,QAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,KAAK;AACnB,OAAI,IAAI,KAAK,SAAS,cAAc,QAAQ,CAAC,CAC3C,QAAO,EAAE;AAGX,UAAO,IAAI;;EAEd"}
1
+ {"version":3,"file":"nx-folder-plugin.js","names":[],"sources":["../../../src/lib/nx-folder-plugin.ts"],"sourcesContent":["import { normalizePath, Plugin } from 'vite';\n\n/**\n * Ignores anything in the .nx folder from triggering HMR\n *\n * @returns\n */\nexport function nxFolderPlugin(): Plugin {\n return {\n name: 'analogjs-nx-folder-plugin',\n apply: 'serve',\n handleHotUpdate(ctx) {\n if (ctx.file.includes(normalizePath('/.nx/'))) {\n return [];\n }\n\n return ctx.modules;\n },\n };\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,iBAAyB;CACvC,OAAO;EACL,MAAM;EACN,OAAO;EACP,gBAAgB,KAAK;GACnB,IAAI,IAAI,KAAK,SAAS,cAAc,OAAO,CAAC,GAC1C,OAAO,CAAC;GAGV,OAAO,IAAI;EACb;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-replacements.plugin.js","names":[],"sources":["../../../../src/lib/plugins/file-replacements.plugin.ts"],"sourcesContent":["// source: https://github.com/Myrmod/vitejs-theming/blob/master/build-plugins/rollup/replace-files.js\nimport { isAbsolute, resolve } from 'node:path';\nimport { Plugin } from 'vite';\nimport { debugCompiler } from '../utils/debug.js';\n\nexport function replaceFiles(\n replacements: FileReplacement[],\n workspaceRoot: string,\n): Plugin | false {\n if (!replacements?.length) {\n return false;\n }\n\n return {\n name: 'rollup-plugin-replace-files',\n enforce: 'pre',\n async resolveId(source, importer, options) {\n const resolved = await this.resolve(source, importer, {\n ...options,\n skipSelf: true,\n });\n /**\n * The reason we're using endsWith here is because the resolved id\n * will be the absolute path to the file. We want to check if the\n * file ends with the file we're trying to replace, which will be essentially\n * the path from the root of our workspace.\n */\n const mappedReplacements = replacements.map((fr: FileReplacement) => {\n const frSSR = fr as FileReplacementSSR;\n const frWith = fr as FileReplacementWith;\n\n return {\n ...fr,\n ssr: frSSR.ssr\n ? isAbsolute(frSSR.ssr)\n ? frSSR.ssr\n : resolve(workspaceRoot, frSSR.ssr)\n : '',\n with: frWith.with\n ? isAbsolute(frWith.with)\n ? frWith.with\n : resolve(workspaceRoot, frWith.with)\n : '',\n };\n });\n const foundReplace = mappedReplacements.find((replacement) =>\n resolved?.id?.endsWith(replacement.replace),\n );\n if (foundReplace) {\n try {\n if (this.environment.name === 'ssr' && foundReplace.ssr) {\n // return new file id for ssr\n return {\n id: foundReplace.ssr,\n };\n } else if (foundReplace.ssr) {\n return null;\n }\n\n // return new file id\n return {\n id: foundReplace.with,\n };\n } catch (err) {\n debugCompiler('file replacement error', {\n error: String(err),\n source,\n importer,\n });\n return null;\n }\n }\n return null;\n },\n };\n}\n\nexport type FileReplacement = FileReplacementWith | FileReplacementSSR;\n\nexport interface FileReplacementBase {\n replace: string;\n}\nexport interface FileReplacementWith extends FileReplacementBase {\n with: string;\n}\n\nexport interface FileReplacementSSR extends FileReplacementBase {\n ssr: string;\n}\n"],"mappings":";;;AAKA,SAAgB,aACd,cACA,eACgB;AAChB,KAAI,CAAC,cAAc,OACjB,QAAO;AAGT,QAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM,UAAU,QAAQ,UAAU,SAAS;GACzC,MAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,UAAU;IACpD,GAAG;IACH,UAAU;IACX,CAAC;GAyBF,MAAM,eAlBqB,aAAa,KAAK,OAAwB;IACnE,MAAM,QAAQ;IACd,MAAM,SAAS;AAEf,WAAO;KACL,GAAG;KACH,KAAK,MAAM,MACP,WAAW,MAAM,IAAI,GACnB,MAAM,MACN,QAAQ,eAAe,MAAM,IAAI,GACnC;KACJ,MAAM,OAAO,OACT,WAAW,OAAO,KAAK,GACrB,OAAO,OACP,QAAQ,eAAe,OAAO,KAAK,GACrC;KACL;KACD,CACsC,MAAM,gBAC5C,UAAU,IAAI,SAAS,YAAY,QAAQ,CAC5C;AACD,OAAI,aACF,KAAI;AACF,QAAI,KAAK,YAAY,SAAS,SAAS,aAAa,IAElD,QAAO,EACL,IAAI,aAAa,KAClB;aACQ,aAAa,IACtB,QAAO;AAIT,WAAO,EACL,IAAI,aAAa,MAClB;YACM,KAAK;AACZ,kBAAc,0BAA0B;KACtC,OAAO,OAAO,IAAI;KAClB;KACA;KACD,CAAC;AACF,WAAO;;AAGX,UAAO;;EAEV"}
1
+ {"version":3,"file":"file-replacements.plugin.js","names":[],"sources":["../../../../src/lib/plugins/file-replacements.plugin.ts"],"sourcesContent":["// source: https://github.com/Myrmod/vitejs-theming/blob/master/build-plugins/rollup/replace-files.js\nimport { isAbsolute, resolve } from 'node:path';\nimport { Plugin } from 'vite';\nimport { debugCompiler } from '../utils/debug.js';\n\nexport function replaceFiles(\n replacements: FileReplacement[],\n workspaceRoot: string,\n): Plugin | false {\n if (!replacements?.length) {\n return false;\n }\n\n return {\n name: 'rollup-plugin-replace-files',\n enforce: 'pre',\n async resolveId(source, importer, options) {\n const resolved = await this.resolve(source, importer, {\n ...options,\n skipSelf: true,\n });\n /**\n * The reason we're using endsWith here is because the resolved id\n * will be the absolute path to the file. We want to check if the\n * file ends with the file we're trying to replace, which will be essentially\n * the path from the root of our workspace.\n */\n const mappedReplacements = replacements.map((fr: FileReplacement) => {\n const frSSR = fr as FileReplacementSSR;\n const frWith = fr as FileReplacementWith;\n\n return {\n ...fr,\n ssr: frSSR.ssr\n ? isAbsolute(frSSR.ssr)\n ? frSSR.ssr\n : resolve(workspaceRoot, frSSR.ssr)\n : '',\n with: frWith.with\n ? isAbsolute(frWith.with)\n ? frWith.with\n : resolve(workspaceRoot, frWith.with)\n : '',\n };\n });\n const foundReplace = mappedReplacements.find((replacement) =>\n resolved?.id?.endsWith(replacement.replace),\n );\n if (foundReplace) {\n try {\n if (this.environment.name === 'ssr' && foundReplace.ssr) {\n // return new file id for ssr\n return {\n id: foundReplace.ssr,\n };\n } else if (foundReplace.ssr) {\n return null;\n }\n\n // return new file id\n return {\n id: foundReplace.with,\n };\n } catch (err) {\n debugCompiler('file replacement error', {\n error: String(err),\n source,\n importer,\n });\n return null;\n }\n }\n return null;\n },\n };\n}\n\nexport type FileReplacement = FileReplacementWith | FileReplacementSSR;\n\nexport interface FileReplacementBase {\n replace: string;\n}\nexport interface FileReplacementWith extends FileReplacementBase {\n with: string;\n}\n\nexport interface FileReplacementSSR extends FileReplacementBase {\n ssr: string;\n}\n"],"mappings":";;;AAKA,SAAgB,aACd,cACA,eACgB;CAChB,IAAI,CAAC,cAAc,QACjB,OAAO;CAGT,OAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM,UAAU,QAAQ,UAAU,SAAS;GACzC,MAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,UAAU;IACpD,GAAG;IACH,UAAU;GACZ,CAAC;GAyBD,MAAM,eAlBqB,aAAa,KAAK,OAAwB;IACnE,MAAM,QAAQ;IACd,MAAM,SAAS;IAEf,OAAO;KACL,GAAG;KACH,KAAK,MAAM,MACP,WAAW,MAAM,GAAG,IAClB,MAAM,MACN,QAAQ,eAAe,MAAM,GAAG,IAClC;KACJ,MAAM,OAAO,OACT,WAAW,OAAO,IAAI,IACpB,OAAO,OACP,QAAQ,eAAe,OAAO,IAAI,IACpC;IACN;GACF,CACqB,CAAA,CAAmB,MAAM,gBAC5C,UAAU,IAAI,SAAS,YAAY,OAAO,CAC5C;GACA,IAAI,cACF,IAAI;IACF,IAAI,KAAK,YAAY,SAAS,SAAS,aAAa,KAElD,OAAO,EACL,IAAI,aAAa,IACnB;SACK,IAAI,aAAa,KACtB,OAAO;IAIT,OAAO,EACL,IAAI,aAAa,KACnB;GACF,SAAS,KAAK;IACZ,cAAc,0BAA0B;KACtC,OAAO,OAAO,GAAG;KACjB;KACA;IACF,CAAC;IACD,OAAO;GACT;GAEF,OAAO;EACT;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"router-plugin.js","names":[],"sources":["../../../src/lib/router-plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\nimport {\n createPersistentTransformCache,\n resolveTransformCacheDir,\n withMemoryLayer,\n type TransformCacheStore,\n} from './utils/transform-cache.js';\n\nexport function routerPlugin(): Plugin {\n const memoryCache = new Map<string, Uint8Array>();\n const memoryOnly: TransformCacheStore = {\n get: (key: string) => memoryCache.get(key),\n put: (key: string, value: Uint8Array) => {\n memoryCache.set(key, value);\n },\n };\n const persistentDir = resolveTransformCacheDir(process.cwd());\n let javascriptTransformer: InstanceType<typeof JavaScriptTransformer>;\n function getTransformer() {\n return (javascriptTransformer ??= new JavaScriptTransformer(\n { jit: true },\n 1,\n persistentDir\n ? withMemoryLayer(createPersistentTransformCache(persistentDir))\n : memoryOnly,\n ));\n }\n\n /**\n * Transforms Angular packages the didn't get picked up by Vite's pre-optimization.\n */\n return {\n name: 'analogjs-router-optimization',\n enforce: 'pre',\n apply: 'serve',\n buildEnd() {\n return javascriptTransformer?.close();\n },\n transform: {\n filter: {\n id: /fesm(.*?)\\.mjs/,\n },\n async handler(_code: string, id: string) {\n const path = id.split('?')[0];\n const contents = await getTransformer().transformFile(path);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n };\n },\n },\n };\n}\n"],"mappings":";;;AASA,SAAgB,eAAuB;CACrC,MAAM,8BAAc,IAAI,KAAyB;CACjD,MAAM,aAAkC;EACtC,MAAM,QAAgB,YAAY,IAAI,IAAI;EAC1C,MAAM,KAAa,UAAsB;AACvC,eAAY,IAAI,KAAK,MAAM;;EAE9B;CACD,MAAM,gBAAgB,yBAAyB,QAAQ,KAAK,CAAC;CAC7D,IAAI;CACJ,SAAS,iBAAiB;AACxB,SAAQ,0BAA0B,IAAI,sBACpC,EAAE,KAAK,MAAM,EACb,GACA,gBACI,gBAAgB,+BAA+B,cAAc,CAAC,GAC9D,WACL;;;;;AAMH,QAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO;EACP,WAAW;AACT,UAAO,uBAAuB,OAAO;;EAEvC,WAAW;GACT,QAAQ,EACN,IAAI,kBACL;GACD,MAAM,QAAQ,OAAe,IAAY;IACvC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC;IAC3B,MAAM,WAAW,MAAM,gBAAgB,CAAC,cAAc,KAAK;AAE3D,WAAO,EACL,MAAM,OAAO,KAAK,SAAS,CAAC,SAAS,QAAQ,EAC9C;;GAEJ;EACF"}
1
+ {"version":3,"file":"router-plugin.js","names":[],"sources":["../../../src/lib/router-plugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport { JavaScriptTransformer } from './utils/devkit.js';\nimport {\n createPersistentTransformCache,\n resolveTransformCacheDir,\n withMemoryLayer,\n type TransformCacheStore,\n} from './utils/transform-cache.js';\n\nexport function routerPlugin(): Plugin {\n const memoryCache = new Map<string, Uint8Array>();\n const memoryOnly: TransformCacheStore = {\n get: (key: string) => memoryCache.get(key),\n put: (key: string, value: Uint8Array) => {\n memoryCache.set(key, value);\n },\n };\n const persistentDir = resolveTransformCacheDir(process.cwd());\n let javascriptTransformer: InstanceType<typeof JavaScriptTransformer>;\n function getTransformer() {\n return (javascriptTransformer ??= new JavaScriptTransformer(\n { jit: true },\n 1,\n persistentDir\n ? withMemoryLayer(createPersistentTransformCache(persistentDir))\n : memoryOnly,\n ));\n }\n\n /**\n * Transforms Angular packages the didn't get picked up by Vite's pre-optimization.\n */\n return {\n name: 'analogjs-router-optimization',\n enforce: 'pre',\n apply: 'serve',\n buildEnd() {\n return javascriptTransformer?.close();\n },\n transform: {\n filter: {\n id: /fesm(.*?)\\.mjs/,\n },\n async handler(_code: string, id: string) {\n const path = id.split('?')[0];\n const contents = await getTransformer().transformFile(path);\n\n return {\n code: Buffer.from(contents).toString('utf-8'),\n };\n },\n },\n };\n}\n"],"mappings":";;;AASA,SAAgB,eAAuB;CACrC,MAAM,8BAAc,IAAI,IAAwB;CAChD,MAAM,aAAkC;EACtC,MAAM,QAAgB,YAAY,IAAI,GAAG;EACzC,MAAM,KAAa,UAAsB;GACvC,YAAY,IAAI,KAAK,KAAK;EAC5B;CACF;CACA,MAAM,gBAAgB,yBAAyB,QAAQ,IAAI,CAAC;CAC5D,IAAI;CACJ,SAAS,iBAAiB;EACxB,OAAQ,0BAA0B,IAAI,sBACpC,EAAE,KAAK,KAAK,GACZ,GACA,gBACI,gBAAgB,+BAA+B,aAAa,CAAC,IAC7D,UACN;CACF;;;;CAKA,OAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO;EACP,WAAW;GACT,OAAO,uBAAuB,MAAM;EACtC;EACA,WAAW;GACT,QAAQ,EACN,IAAI,iBACN;GACA,MAAM,QAAQ,OAAe,IAAY;IACvC,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC;IAC3B,MAAM,WAAW,MAAM,eAAe,CAAC,CAAC,cAAc,IAAI;IAE1D,OAAO,EACL,MAAM,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,OAAO,EAC9C;GACF;EACF;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"style-preprocessor.js","names":[],"sources":["../../../src/lib/style-preprocessor.ts"],"sourcesContent":["export interface StylesheetTransformContext {\n filename: string;\n containingFile?: string;\n resourceFile?: string;\n className?: string;\n order?: number;\n inline: boolean;\n}\n\nexport interface StylesheetDependency {\n id: string;\n kind?: 'file' | 'virtual' | 'token' | 'bridge' | 'manifest' | 'runtime';\n owner?: string;\n}\n\nexport interface StylesheetDiagnostic {\n severity: 'warning' | 'error';\n code: string;\n message: string;\n}\n\nexport interface StylesheetTransformResult {\n code: string;\n dependencies?: Array<string | StylesheetDependency>;\n diagnostics?: StylesheetDiagnostic[];\n tags?: string[];\n}\n\nexport interface StylesheetRegistryReader {\n getPublicIdsForSource(sourcePath: string): string[];\n getRequestIdsForSource(sourcePath: string): string[];\n getDependenciesForSource(sourcePath: string): StylesheetDependency[];\n getDiagnosticsForSource(sourcePath: string): StylesheetDiagnostic[];\n getTagsForSource(sourcePath: string): string[];\n}\n\nexport type StylePreprocessor = (\n code: string,\n filename: string,\n context?: StylesheetTransformContext,\n) => string | StylesheetTransformResult;\n\nexport function normalizeStylesheetTransformResult(\n value: string | StylesheetTransformResult | undefined,\n fallbackCode: string,\n): StylesheetTransformResult {\n if (value == null) {\n return { code: fallbackCode };\n }\n\n if (typeof value === 'string') {\n return { code: value };\n }\n\n return {\n code: value.code ?? fallbackCode,\n dependencies: normalizeStylesheetDependencies(value.dependencies),\n diagnostics: value.diagnostics ?? [],\n tags: value.tags ?? [],\n };\n}\n\nexport function normalizeStylesheetDependencies(\n dependencies: Array<string | StylesheetDependency> | undefined,\n): StylesheetDependency[] {\n return (dependencies ?? []).map((dependency) =>\n typeof dependency === 'string' ? { id: dependency } : dependency,\n );\n}\n\nexport function composeStylePreprocessors(\n preprocessors: Array<StylePreprocessor | false | null | undefined>,\n): StylePreprocessor | undefined {\n const active = preprocessors.filter(\n (preprocessor): preprocessor is StylePreprocessor => !!preprocessor,\n );\n\n if (!active.length) {\n return undefined;\n }\n\n return (code, filename, context) => {\n let current = normalizeStylesheetTransformResult(undefined, code);\n\n for (const preprocessor of active) {\n const next = normalizeStylesheetTransformResult(\n preprocessor(current.code, filename, context),\n current.code,\n );\n current = {\n code: next.code,\n dependencies: [\n ...(current.dependencies ?? []),\n ...(next.dependencies ?? []),\n ],\n diagnostics: [\n ...(current.diagnostics ?? []),\n ...(next.diagnostics ?? []),\n ],\n tags: [...(current.tags ?? []), ...(next.tags ?? [])],\n };\n }\n\n return current;\n };\n}\n"],"mappings":";AA0CA,SAAgB,mCACd,OACA,cAC2B;AAC3B,KAAI,SAAS,KACX,QAAO,EAAE,MAAM,cAAc;AAG/B,KAAI,OAAO,UAAU,SACnB,QAAO,EAAE,MAAM,OAAO;AAGxB,QAAO;EACL,MAAM,MAAM,QAAQ;EACpB,cAAc,gCAAgC,MAAM,aAAa;EACjE,aAAa,MAAM,eAAe,EAAE;EACpC,MAAM,MAAM,QAAQ,EAAE;EACvB;;AAGH,SAAgB,gCACd,cACwB;AACxB,SAAQ,gBAAgB,EAAE,EAAE,KAAK,eAC/B,OAAO,eAAe,WAAW,EAAE,IAAI,YAAY,GAAG,WACvD;;AAGH,SAAgB,0BACd,eAC+B;CAC/B,MAAM,SAAS,cAAc,QAC1B,iBAAoD,CAAC,CAAC,aACxD;AAED,KAAI,CAAC,OAAO,OACV;AAGF,SAAQ,MAAM,UAAU,YAAY;EAClC,IAAI,UAAU,mCAAmC,KAAA,GAAW,KAAK;AAEjE,OAAK,MAAM,gBAAgB,QAAQ;GACjC,MAAM,OAAO,mCACX,aAAa,QAAQ,MAAM,UAAU,QAAQ,EAC7C,QAAQ,KACT;AACD,aAAU;IACR,MAAM,KAAK;IACX,cAAc,CACZ,GAAI,QAAQ,gBAAgB,EAAE,EAC9B,GAAI,KAAK,gBAAgB,EAAE,CAC5B;IACD,aAAa,CACX,GAAI,QAAQ,eAAe,EAAE,EAC7B,GAAI,KAAK,eAAe,EAAE,CAC3B;IACD,MAAM,CAAC,GAAI,QAAQ,QAAQ,EAAE,EAAG,GAAI,KAAK,QAAQ,EAAE,CAAE;IACtD;;AAGH,SAAO"}
1
+ {"version":3,"file":"style-preprocessor.js","names":[],"sources":["../../../src/lib/style-preprocessor.ts"],"sourcesContent":["export interface StylesheetTransformContext {\n filename: string;\n containingFile?: string;\n resourceFile?: string;\n className?: string;\n order?: number;\n inline: boolean;\n}\n\nexport interface StylesheetDependency {\n id: string;\n kind?: 'file' | 'virtual' | 'token' | 'bridge' | 'manifest' | 'runtime';\n owner?: string;\n}\n\nexport interface StylesheetDiagnostic {\n severity: 'warning' | 'error';\n code: string;\n message: string;\n}\n\nexport interface StylesheetTransformResult {\n code: string;\n dependencies?: Array<string | StylesheetDependency>;\n diagnostics?: StylesheetDiagnostic[];\n tags?: string[];\n}\n\nexport interface StylesheetRegistryReader {\n getPublicIdsForSource(sourcePath: string): string[];\n getRequestIdsForSource(sourcePath: string): string[];\n getDependenciesForSource(sourcePath: string): StylesheetDependency[];\n getDiagnosticsForSource(sourcePath: string): StylesheetDiagnostic[];\n getTagsForSource(sourcePath: string): string[];\n}\n\nexport type StylePreprocessor = (\n code: string,\n filename: string,\n context?: StylesheetTransformContext,\n) => string | StylesheetTransformResult;\n\nexport function normalizeStylesheetTransformResult(\n value: string | StylesheetTransformResult | undefined,\n fallbackCode: string,\n): StylesheetTransformResult {\n if (value == null) {\n return { code: fallbackCode };\n }\n\n if (typeof value === 'string') {\n return { code: value };\n }\n\n return {\n code: value.code ?? fallbackCode,\n dependencies: normalizeStylesheetDependencies(value.dependencies),\n diagnostics: value.diagnostics ?? [],\n tags: value.tags ?? [],\n };\n}\n\nexport function normalizeStylesheetDependencies(\n dependencies: Array<string | StylesheetDependency> | undefined,\n): StylesheetDependency[] {\n return (dependencies ?? []).map((dependency) =>\n typeof dependency === 'string' ? { id: dependency } : dependency,\n );\n}\n\nexport function composeStylePreprocessors(\n preprocessors: Array<StylePreprocessor | false | null | undefined>,\n): StylePreprocessor | undefined {\n const active = preprocessors.filter(\n (preprocessor): preprocessor is StylePreprocessor => !!preprocessor,\n );\n\n if (!active.length) {\n return undefined;\n }\n\n return (code, filename, context) => {\n let current = normalizeStylesheetTransformResult(undefined, code);\n\n for (const preprocessor of active) {\n const next = normalizeStylesheetTransformResult(\n preprocessor(current.code, filename, context),\n current.code,\n );\n current = {\n code: next.code,\n dependencies: [\n ...(current.dependencies ?? []),\n ...(next.dependencies ?? []),\n ],\n diagnostics: [\n ...(current.diagnostics ?? []),\n ...(next.diagnostics ?? []),\n ],\n tags: [...(current.tags ?? []), ...(next.tags ?? [])],\n };\n }\n\n return current;\n };\n}\n"],"mappings":";AA0CA,SAAgB,mCACd,OACA,cAC2B;CAC3B,IAAI,SAAS,MACX,OAAO,EAAE,MAAM,aAAa;CAG9B,IAAI,OAAO,UAAU,UACnB,OAAO,EAAE,MAAM,MAAM;CAGvB,OAAO;EACL,MAAM,MAAM,QAAQ;EACpB,cAAc,gCAAgC,MAAM,YAAY;EAChE,aAAa,MAAM,eAAe,CAAC;EACnC,MAAM,MAAM,QAAQ,CAAC;CACvB;AACF;AAEA,SAAgB,gCACd,cACwB;CACxB,QAAQ,gBAAgB,CAAC,EAAA,CAAG,KAAK,eAC/B,OAAO,eAAe,WAAW,EAAE,IAAI,WAAW,IAAI,UACxD;AACF;AAEA,SAAgB,0BACd,eAC+B;CAC/B,MAAM,SAAS,cAAc,QAC1B,iBAAoD,CAAC,CAAC,YACzD;CAEA,IAAI,CAAC,OAAO,QACV;CAGF,QAAQ,MAAM,UAAU,YAAY;EAClC,IAAI,UAAU,mCAAmC,KAAA,GAAW,IAAI;EAEhE,KAAK,MAAM,gBAAgB,QAAQ;GACjC,MAAM,OAAO,mCACX,aAAa,QAAQ,MAAM,UAAU,OAAO,GAC5C,QAAQ,IACV;GACA,UAAU;IACR,MAAM,KAAK;IACX,cAAc,CACZ,GAAI,QAAQ,gBAAgB,CAAC,GAC7B,GAAI,KAAK,gBAAgB,CAAC,CAC5B;IACA,aAAa,CACX,GAAI,QAAQ,eAAe,CAAC,GAC5B,GAAI,KAAK,eAAe,CAAC,CAC3B;IACA,MAAM,CAAC,GAAI,QAAQ,QAAQ,CAAC,GAAI,GAAI,KAAK,QAAQ,CAAC,CAAE;GACtD;EACF;EAEA,OAAO;CACT;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"stylesheet-registry.js","names":[],"sources":["../../../src/lib/stylesheet-registry.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { dirname, normalize, resolve } from 'node:path';\nimport { normalizePath } from 'vite';\nimport type {\n StylePreprocessor,\n StylesheetDependency,\n StylesheetDiagnostic,\n StylesheetTransformResult,\n StylesheetTransformContext,\n} from './style-preprocessor.js';\nimport { normalizeStylesheetTransformResult as normalizeTransformResult } from './style-preprocessor.js';\n\nexport interface AnalogStylesheetRecord {\n publicId: string;\n sourcePath?: string;\n originalCode?: string;\n normalizedCode: string;\n dependencies?: StylesheetDependency[];\n diagnostics?: StylesheetDiagnostic[];\n tags?: string[];\n}\n\nexport class AnalogStylesheetRegistry {\n private servedById = new Map<string, AnalogStylesheetRecord>();\n private servedAliasToId = new Map<string, string>();\n private externalRequestToSource = new Map<string, string>();\n /**\n * Maps a real source stylesheet path back to the generated public stylesheet\n * ids Analog serves for Angular. This is stable across requests and lets HMR\n * reason about \"which virtual stylesheet came from this source file?\"\n */\n private sourceToPublicIds = new Map<string, Set<string>>();\n /**\n * Tracks the live request ids Vite/Angular have actually served for a source\n * stylesheet, including both `?direct&ngcomp=...` CSS modules and\n * `?ngcomp=...` JS wrapper modules. HMR must use these live request ids\n * because Angular component styles are no longer addressed by their original\n * file paths once externalized.\n */\n private sourceToRequestIds = new Map<string, Set<string>>();\n private sourceToDependencies = new Map<string, StylesheetDependency[]>();\n private sourceToDiagnostics = new Map<string, StylesheetDiagnostic[]>();\n private sourceToTags = new Map<string, string[]>();\n\n /**\n * Canonicalizes browser-facing stylesheet request ids so Vite timestamp\n * variants (`?t=...`) and path-shape variants (`abc.css?...` vs\n * `/abc.css?...`) all collapse onto one logical module identity.\n *\n * This is critical for Angular component stylesheet HMR because the browser\n * can keep both timestamped and non-timestamped requests alive for the same\n * externalized stylesheet. If Analog tracks them as distinct resources, HMR\n * can update one module while the browser continues rendering another stale\n * module for the same public stylesheet id.\n */\n private normalizeRequestId(requestId: string): string {\n const [rawPathname, rawSearch = ''] = requestId.split('?');\n const normalizedPathname = rawPathname.replace(/^\\//, '');\n\n if (!rawSearch) {\n return normalizedPathname;\n }\n\n // Preserve bare query flags like `?direct&ngcomp=...` exactly. Using\n // URLSearchParams reserializes `direct` as `direct=`, which changes the\n // module identity and breaks Vite module-graph lookups for Angular's\n // externalized component stylesheet requests.\n const normalizedSearch = rawSearch\n .split('&')\n .filter((segment) => segment.length > 0)\n .filter((segment) => {\n const [key] = segment.split('=');\n return key !== 't';\n })\n .join('&');\n\n return normalizedSearch\n ? `${normalizedPathname}?${normalizedSearch}`\n : normalizedPathname;\n }\n\n get servedCount(): number {\n return this.servedById.size;\n }\n\n get externalCount(): number {\n return this.externalRequestToSource.size;\n }\n\n hasServed(requestId: string): boolean {\n return this.resolveServedRecord(requestId) !== undefined;\n }\n\n getServedContent(requestId: string): string | undefined {\n return this.resolveServedRecord(requestId)?.normalizedCode;\n }\n\n getServedSourcePath(requestId: string): string | undefined {\n return this.resolveServedRecord(requestId)?.sourcePath;\n }\n\n resolveExternalSource(requestId: string): string | undefined {\n const normalizedRequestId = this.normalizeRequestId(requestId);\n return this.externalRequestToSource.get(normalizedRequestId);\n }\n\n getPublicIdsForSource(sourcePath: string): string[] {\n return [...(this.sourceToPublicIds.get(sourcePath) ?? [])];\n }\n\n getRequestIdsForSource(sourcePath: string): string[] {\n return [...(this.sourceToRequestIds.get(sourcePath) ?? [])];\n }\n\n getDependenciesForSource(sourcePath: string): StylesheetDependency[] {\n return [...(this.sourceToDependencies.get(sourcePath) ?? [])];\n }\n\n getDiagnosticsForSource(sourcePath: string): StylesheetDiagnostic[] {\n return [...(this.sourceToDiagnostics.get(sourcePath) ?? [])];\n }\n\n getTagsForSource(sourcePath: string): string[] {\n return [...(this.sourceToTags.get(sourcePath) ?? [])];\n }\n\n registerExternalRequest(requestId: string, sourcePath: string): void {\n this.externalRequestToSource.set(\n this.normalizeRequestId(requestId),\n sourcePath,\n );\n }\n\n registerActiveRequest(requestId: string): void {\n // Requests arrive in multiple shapes depending on who asked for the\n // stylesheet (`abc123.css?...` vs `/abc123.css?...`). Normalize both back to\n // the source file so later HMR events for `/src/...component.css` can find\n // the currently active virtual requests.\n const normalizedRequestId = this.normalizeRequestId(requestId);\n const requestPath = normalizedRequestId.split('?')[0];\n const sourcePath =\n this.resolveExternalSource(requestPath) ??\n this.resolveExternalSource(requestPath.replace(/^\\//, '')) ??\n this.getServedSourcePath(requestPath) ??\n this.getServedSourcePath(requestPath.replace(/^\\//, ''));\n if (!sourcePath) {\n return;\n }\n\n const requestIds = this.sourceToRequestIds.get(sourcePath) ?? new Set();\n requestIds.add(normalizedRequestId);\n // Angular component styles are served through both a direct CSS request\n // (`?direct&ngcomp=...`) and a JS wrapper request (`?ngcomp=...`). The\n // browser can already have the wrapper loaded even when Vite's live module\n // graph only surfaces the direct request during a CSS-only edit. Track the\n // derived wrapper id eagerly so HMR can reason about the browser-visible\n // stylesheet identity without waiting for that wrapper request to be\n // observed later in the session.\n if (normalizedRequestId.includes('?direct&ngcomp=')) {\n requestIds.add(\n normalizedRequestId.replace('?direct&ngcomp=', '?ngcomp='),\n );\n }\n this.sourceToRequestIds.set(sourcePath, requestIds);\n }\n\n registerServedStylesheet(\n record: AnalogStylesheetRecord,\n aliases: string[] = [],\n ): void {\n const publicId = this.normalizeRequestId(record.publicId);\n this.servedById.set(publicId, { ...record, publicId });\n this.servedAliasToId.set(publicId, publicId);\n\n for (const alias of aliases) {\n this.servedAliasToId.set(this.normalizeRequestId(alias), publicId);\n }\n\n if (record.sourcePath) {\n const publicIds =\n this.sourceToPublicIds.get(record.sourcePath) ?? new Set();\n publicIds.add(publicId);\n this.sourceToPublicIds.set(record.sourcePath, publicIds);\n this.recomputeSourceMetadata(record.sourcePath);\n }\n }\n\n private recomputeSourceMetadata(sourcePath: string): void {\n const dependencies = new Map<string, StylesheetDependency>();\n const diagnostics = new Map<string, StylesheetDiagnostic>();\n const tags = new Set<string>();\n\n for (const publicId of this.sourceToPublicIds.get(sourcePath) ?? []) {\n const record = this.servedById.get(publicId);\n if (!record) {\n continue;\n }\n\n for (const dependency of record.dependencies ?? []) {\n const key = `${dependency.kind ?? 'unknown'}:${dependency.id}:${dependency.owner ?? ''}`;\n dependencies.set(key, dependency);\n }\n\n for (const diagnostic of record.diagnostics ?? []) {\n const key = `${diagnostic.severity}:${diagnostic.code}:${diagnostic.message}`;\n diagnostics.set(key, diagnostic);\n }\n\n for (const tag of record.tags ?? []) {\n tags.add(tag);\n }\n }\n\n this.sourceToDependencies.set(sourcePath, [...dependencies.values()]);\n this.sourceToDiagnostics.set(sourcePath, [...diagnostics.values()]);\n this.sourceToTags.set(sourcePath, [...tags]);\n }\n\n private resolveServedRecord(\n requestId: string,\n ): AnalogStylesheetRecord | undefined {\n const normalizedRequestId = this.normalizeRequestId(requestId);\n const publicId =\n this.servedAliasToId.get(normalizedRequestId) ??\n this.servedAliasToId.get(normalizedRequestId.split('?')[0]) ??\n normalizedRequestId.split('?')[0];\n return this.servedById.get(publicId);\n }\n}\n\nexport function preprocessStylesheet(\n code: string,\n filename: string,\n stylePreprocessor?: StylePreprocessor,\n context?: StylesheetTransformContext,\n): string {\n return preprocessStylesheetResult(code, filename, stylePreprocessor, context)\n .code;\n}\n\nexport function preprocessStylesheetResult(\n code: string,\n filename: string,\n stylePreprocessor?: StylePreprocessor,\n context?: StylesheetTransformContext,\n): StylesheetTransformResult {\n return normalizeTransformResult(\n stylePreprocessor?.(code, filename, context),\n code,\n );\n}\n\nexport function rewriteRelativeCssImports(\n code: string,\n filename: string,\n): string {\n const cssDir = dirname(filename);\n return code.replace(\n /@import\\s+(?:url\\(\\s*([\"']?)(\\.[^'\")\\s;]+)\\1\\s*\\)|([\"'])(\\.[^'\"]+)\\3)/g,\n (_match, urlQuote, urlPath, stringQuote, stringPath) => {\n const relPath = urlPath ?? stringPath;\n const absPath = resolve(cssDir, relPath);\n\n if (typeof urlPath === 'string') {\n return `@import url(${urlQuote}${absPath}${urlQuote})`;\n }\n\n return `@import ${stringQuote}${absPath}${stringQuote}`;\n },\n );\n}\n\nexport function registerStylesheetContent(\n registry: AnalogStylesheetRegistry,\n {\n code,\n dependencies,\n diagnostics,\n tags,\n containingFile,\n className,\n order,\n inlineStylesExtension,\n resourceFile,\n }: {\n code: string;\n dependencies?: StylesheetDependency[];\n diagnostics?: StylesheetDiagnostic[];\n tags?: string[];\n containingFile: string;\n className?: string;\n order?: number;\n inlineStylesExtension: string;\n resourceFile?: string;\n },\n): string {\n const id = createHash('sha256')\n .update(containingFile)\n .update(className ?? '')\n .update(String(order ?? 0))\n .update(code)\n .digest('hex');\n const stylesheetId = `${id}.${inlineStylesExtension}`;\n const sourcePath =\n resourceFile ?? containingFile.replace('.ts', `.${inlineStylesExtension}`);\n const normalizedSourcePath = normalizePath(normalize(sourcePath));\n\n // Avoid basename-only aliases here: shared filenames like `index.css`\n // can collide across components and break HMR lookups.\n const aliases = [\n sourcePath,\n normalizedSourcePath,\n sourcePath.replace(/^\\//, ''),\n normalizedSourcePath.replace(/^\\//, ''),\n ];\n\n registry.registerServedStylesheet(\n {\n publicId: stylesheetId,\n sourcePath: normalizedSourcePath,\n normalizedCode: code,\n dependencies,\n diagnostics,\n tags,\n },\n aliases,\n );\n\n return stylesheetId;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stylesheet-registry.js","names":[],"sources":["../../../src/lib/stylesheet-registry.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { dirname, normalize, resolve } from 'node:path';\nimport { normalizePath } from 'vite';\nimport type {\n StylePreprocessor,\n StylesheetDependency,\n StylesheetDiagnostic,\n StylesheetTransformResult,\n StylesheetTransformContext,\n} from './style-preprocessor.js';\nimport { normalizeStylesheetTransformResult as normalizeTransformResult } from './style-preprocessor.js';\n\nexport interface AnalogStylesheetRecord {\n publicId: string;\n sourcePath?: string;\n originalCode?: string;\n normalizedCode: string;\n dependencies?: StylesheetDependency[];\n diagnostics?: StylesheetDiagnostic[];\n tags?: string[];\n}\n\nexport class AnalogStylesheetRegistry {\n private servedById = new Map<string, AnalogStylesheetRecord>();\n private servedAliasToId = new Map<string, string>();\n private externalRequestToSource = new Map<string, string>();\n /**\n * Maps a real source stylesheet path back to the generated public stylesheet\n * ids Analog serves for Angular. This is stable across requests and lets HMR\n * reason about \"which virtual stylesheet came from this source file?\"\n */\n private sourceToPublicIds = new Map<string, Set<string>>();\n /**\n * Tracks the live request ids Vite/Angular have actually served for a source\n * stylesheet, including both `?direct&ngcomp=...` CSS modules and\n * `?ngcomp=...` JS wrapper modules. HMR must use these live request ids\n * because Angular component styles are no longer addressed by their original\n * file paths once externalized.\n */\n private sourceToRequestIds = new Map<string, Set<string>>();\n private sourceToDependencies = new Map<string, StylesheetDependency[]>();\n private sourceToDiagnostics = new Map<string, StylesheetDiagnostic[]>();\n private sourceToTags = new Map<string, string[]>();\n\n /**\n * Canonicalizes browser-facing stylesheet request ids so Vite timestamp\n * variants (`?t=...`) and path-shape variants (`abc.css?...` vs\n * `/abc.css?...`) all collapse onto one logical module identity.\n *\n * This is critical for Angular component stylesheet HMR because the browser\n * can keep both timestamped and non-timestamped requests alive for the same\n * externalized stylesheet. If Analog tracks them as distinct resources, HMR\n * can update one module while the browser continues rendering another stale\n * module for the same public stylesheet id.\n */\n private normalizeRequestId(requestId: string): string {\n const [rawPathname, rawSearch = ''] = requestId.split('?');\n const normalizedPathname = rawPathname.replace(/^\\//, '');\n\n if (!rawSearch) {\n return normalizedPathname;\n }\n\n // Preserve bare query flags like `?direct&ngcomp=...` exactly. Using\n // URLSearchParams reserializes `direct` as `direct=`, which changes the\n // module identity and breaks Vite module-graph lookups for Angular's\n // externalized component stylesheet requests.\n const normalizedSearch = rawSearch\n .split('&')\n .filter((segment) => segment.length > 0)\n .filter((segment) => {\n const [key] = segment.split('=');\n return key !== 't';\n })\n .join('&');\n\n return normalizedSearch\n ? `${normalizedPathname}?${normalizedSearch}`\n : normalizedPathname;\n }\n\n get servedCount(): number {\n return this.servedById.size;\n }\n\n get externalCount(): number {\n return this.externalRequestToSource.size;\n }\n\n hasServed(requestId: string): boolean {\n return this.resolveServedRecord(requestId) !== undefined;\n }\n\n getServedContent(requestId: string): string | undefined {\n return this.resolveServedRecord(requestId)?.normalizedCode;\n }\n\n getServedSourcePath(requestId: string): string | undefined {\n return this.resolveServedRecord(requestId)?.sourcePath;\n }\n\n resolveExternalSource(requestId: string): string | undefined {\n const normalizedRequestId = this.normalizeRequestId(requestId);\n return this.externalRequestToSource.get(normalizedRequestId);\n }\n\n getPublicIdsForSource(sourcePath: string): string[] {\n return [...(this.sourceToPublicIds.get(sourcePath) ?? [])];\n }\n\n getRequestIdsForSource(sourcePath: string): string[] {\n return [...(this.sourceToRequestIds.get(sourcePath) ?? [])];\n }\n\n getDependenciesForSource(sourcePath: string): StylesheetDependency[] {\n return [...(this.sourceToDependencies.get(sourcePath) ?? [])];\n }\n\n getDiagnosticsForSource(sourcePath: string): StylesheetDiagnostic[] {\n return [...(this.sourceToDiagnostics.get(sourcePath) ?? [])];\n }\n\n getTagsForSource(sourcePath: string): string[] {\n return [...(this.sourceToTags.get(sourcePath) ?? [])];\n }\n\n registerExternalRequest(requestId: string, sourcePath: string): void {\n this.externalRequestToSource.set(\n this.normalizeRequestId(requestId),\n sourcePath,\n );\n }\n\n registerActiveRequest(requestId: string): void {\n // Requests arrive in multiple shapes depending on who asked for the\n // stylesheet (`abc123.css?...` vs `/abc123.css?...`). Normalize both back to\n // the source file so later HMR events for `/src/...component.css` can find\n // the currently active virtual requests.\n const normalizedRequestId = this.normalizeRequestId(requestId);\n const requestPath = normalizedRequestId.split('?')[0];\n const sourcePath =\n this.resolveExternalSource(requestPath) ??\n this.resolveExternalSource(requestPath.replace(/^\\//, '')) ??\n this.getServedSourcePath(requestPath) ??\n this.getServedSourcePath(requestPath.replace(/^\\//, ''));\n if (!sourcePath) {\n return;\n }\n\n const requestIds = this.sourceToRequestIds.get(sourcePath) ?? new Set();\n requestIds.add(normalizedRequestId);\n // Angular component styles are served through both a direct CSS request\n // (`?direct&ngcomp=...`) and a JS wrapper request (`?ngcomp=...`). The\n // browser can already have the wrapper loaded even when Vite's live module\n // graph only surfaces the direct request during a CSS-only edit. Track the\n // derived wrapper id eagerly so HMR can reason about the browser-visible\n // stylesheet identity without waiting for that wrapper request to be\n // observed later in the session.\n if (normalizedRequestId.includes('?direct&ngcomp=')) {\n requestIds.add(\n normalizedRequestId.replace('?direct&ngcomp=', '?ngcomp='),\n );\n }\n this.sourceToRequestIds.set(sourcePath, requestIds);\n }\n\n registerServedStylesheet(\n record: AnalogStylesheetRecord,\n aliases: string[] = [],\n ): void {\n const publicId = this.normalizeRequestId(record.publicId);\n this.servedById.set(publicId, { ...record, publicId });\n this.servedAliasToId.set(publicId, publicId);\n\n for (const alias of aliases) {\n this.servedAliasToId.set(this.normalizeRequestId(alias), publicId);\n }\n\n if (record.sourcePath) {\n const publicIds =\n this.sourceToPublicIds.get(record.sourcePath) ?? new Set();\n publicIds.add(publicId);\n this.sourceToPublicIds.set(record.sourcePath, publicIds);\n this.recomputeSourceMetadata(record.sourcePath);\n }\n }\n\n private recomputeSourceMetadata(sourcePath: string): void {\n const dependencies = new Map<string, StylesheetDependency>();\n const diagnostics = new Map<string, StylesheetDiagnostic>();\n const tags = new Set<string>();\n\n for (const publicId of this.sourceToPublicIds.get(sourcePath) ?? []) {\n const record = this.servedById.get(publicId);\n if (!record) {\n continue;\n }\n\n for (const dependency of record.dependencies ?? []) {\n const key = `${dependency.kind ?? 'unknown'}:${dependency.id}:${dependency.owner ?? ''}`;\n dependencies.set(key, dependency);\n }\n\n for (const diagnostic of record.diagnostics ?? []) {\n const key = `${diagnostic.severity}:${diagnostic.code}:${diagnostic.message}`;\n diagnostics.set(key, diagnostic);\n }\n\n for (const tag of record.tags ?? []) {\n tags.add(tag);\n }\n }\n\n this.sourceToDependencies.set(sourcePath, [...dependencies.values()]);\n this.sourceToDiagnostics.set(sourcePath, [...diagnostics.values()]);\n this.sourceToTags.set(sourcePath, [...tags]);\n }\n\n private resolveServedRecord(\n requestId: string,\n ): AnalogStylesheetRecord | undefined {\n const normalizedRequestId = this.normalizeRequestId(requestId);\n const publicId =\n this.servedAliasToId.get(normalizedRequestId) ??\n this.servedAliasToId.get(normalizedRequestId.split('?')[0]) ??\n normalizedRequestId.split('?')[0];\n return this.servedById.get(publicId);\n }\n}\n\nexport function preprocessStylesheet(\n code: string,\n filename: string,\n stylePreprocessor?: StylePreprocessor,\n context?: StylesheetTransformContext,\n): string {\n return preprocessStylesheetResult(code, filename, stylePreprocessor, context)\n .code;\n}\n\nexport function preprocessStylesheetResult(\n code: string,\n filename: string,\n stylePreprocessor?: StylePreprocessor,\n context?: StylesheetTransformContext,\n): StylesheetTransformResult {\n return normalizeTransformResult(\n stylePreprocessor?.(code, filename, context),\n code,\n );\n}\n\nexport function rewriteRelativeCssImports(\n code: string,\n filename: string,\n): string {\n const cssDir = dirname(filename);\n return code.replace(\n /@import\\s+(?:url\\(\\s*([\"']?)(\\.[^'\")\\s;]+)\\1\\s*\\)|([\"'])(\\.[^'\"]+)\\3)/g,\n (_match, urlQuote, urlPath, stringQuote, stringPath) => {\n const relPath = urlPath ?? stringPath;\n const absPath = resolve(cssDir, relPath);\n\n if (typeof urlPath === 'string') {\n return `@import url(${urlQuote}${absPath}${urlQuote})`;\n }\n\n return `@import ${stringQuote}${absPath}${stringQuote}`;\n },\n );\n}\n\nexport function registerStylesheetContent(\n registry: AnalogStylesheetRegistry,\n {\n code,\n dependencies,\n diagnostics,\n tags,\n containingFile,\n className,\n order,\n inlineStylesExtension,\n resourceFile,\n }: {\n code: string;\n dependencies?: StylesheetDependency[];\n diagnostics?: StylesheetDiagnostic[];\n tags?: string[];\n containingFile: string;\n className?: string;\n order?: number;\n inlineStylesExtension: string;\n resourceFile?: string;\n },\n): string {\n const id = createHash('sha256')\n .update(containingFile)\n .update(className ?? '')\n .update(String(order ?? 0))\n .update(code)\n .digest('hex');\n const stylesheetId = `${id}.${inlineStylesExtension}`;\n const sourcePath =\n resourceFile ?? containingFile.replace('.ts', `.${inlineStylesExtension}`);\n const normalizedSourcePath = normalizePath(normalize(sourcePath));\n\n // Avoid basename-only aliases here: shared filenames like `index.css`\n // can collide across components and break HMR lookups.\n const aliases = [\n sourcePath,\n normalizedSourcePath,\n sourcePath.replace(/^\\//, ''),\n normalizedSourcePath.replace(/^\\//, ''),\n ];\n\n registry.registerServedStylesheet(\n {\n publicId: stylesheetId,\n sourcePath: normalizedSourcePath,\n normalizedCode: code,\n dependencies,\n diagnostics,\n tags,\n },\n aliases,\n );\n\n return stylesheetId;\n}\n"],"mappings":"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"}
@@ -6,7 +6,8 @@ async function viteBuilder(options, context) {
6
6
  const projectConfig = await context.getProjectMetadata(context.target);
7
7
  const projectName = context.target.project;
8
8
  const configuration = context.target.configuration || "production";
9
- const buildTarget = (0, _angular_devkit_architect.targetFromTargetString)(`::${configuration}`, projectName, "build");
9
+ const buildTargetSpecifier = `::${configuration}`;
10
+ const buildTarget = (0, _angular_devkit_architect.targetFromTargetString)(buildTargetSpecifier, projectName, "build");
10
11
  const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);
11
12
  const rawBuildOptions = await context.getTargetOptions(buildTarget);
12
13
  const buildOptions = await context.validateOptions(rawBuildOptions, browserBuilderName);
@@ -1 +1 @@
1
- {"version":3,"file":"vite-build.impl.js","names":[],"sources":["../../../../../../../../vite-plugin-angular-tools/src/builders/vite/vite-build.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n targetFromTargetString,\n} from '@angular-devkit/architect';\nimport type { InlineConfig } from 'vite';\nimport { ViteBuildSchema } from './schema';\n\nasync function viteBuilder(\n options: ViteBuildSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n const { createBuilder } = await Function('return import(\"vite\")')();\n if (!context.target) {\n throw new Error('Builder must be executed with a target');\n }\n const projectConfig = await context.getProjectMetadata(context.target);\n const projectName = context.target.project;\n const configuration = context.target.configuration || 'production';\n const buildTargetSpecifier = `::${configuration}`;\n const buildTarget = targetFromTargetString(\n buildTargetSpecifier,\n projectName,\n 'build',\n );\n\n const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);\n const rawBuildOptions = await context.getTargetOptions(buildTarget);\n const buildOptions = await context.validateOptions(\n rawBuildOptions,\n browserBuilderName,\n );\n\n // Explicit build options and the requested configuration win over an\n // ambient NODE_ENV, so `build:production` cannot silently produce a\n // development build when NODE_ENV happens to be set. See #2458.\n const mode = (buildOptions.mode ?? configuration) as string;\n\n if (process.env.NODE_ENV && process.env.NODE_ENV !== mode) {\n context.logger.warn(\n `NODE_ENV is set to \"${process.env.NODE_ENV}\" but is ignored because the build resolved mode \"${mode}\" from the build options and configuration.`,\n );\n }\n\n const buildConfig: InlineConfig = {\n configFile: options.configFile,\n root: projectConfig.root as string,\n mode,\n build: {\n outDir: options.outputPath,\n sourcemap: !!buildOptions.sourcemap,\n },\n };\n\n try {\n const builder = await createBuilder(buildConfig, false);\n await builder.buildApp();\n\n return {\n success: true,\n };\n } catch (e) {\n console.error(e);\n return {\n success: false,\n };\n }\n}\n\nexport default createBuilder(viteBuilder) as any;\n"],"mappings":";;AASA,eAAe,YACb,SACA,SACwB;CACxB,MAAM,EAAE,kBAAkB,MAAM,SAAS,0BAAwB,EAAE;AACnE,KAAI,CAAC,QAAQ,OACX,OAAM,IAAI,MAAM,yCAAyC;CAE3D,MAAM,gBAAgB,MAAM,QAAQ,mBAAmB,QAAQ,OAAO;CACtE,MAAM,cAAc,QAAQ,OAAO;CACnC,MAAM,gBAAgB,QAAQ,OAAO,iBAAiB;CAEtD,MAAM,eAAA,GAAA,0BAAA,wBADuB,KAAK,iBAGhC,aACA,QACD;CAED,MAAM,qBAAqB,MAAM,QAAQ,wBAAwB,YAAY;CAC7E,MAAM,kBAAkB,MAAM,QAAQ,iBAAiB,YAAY;CACnE,MAAM,eAAe,MAAM,QAAQ,gBACjC,iBACA,mBACD;CAKD,MAAM,OAAQ,aAAa,QAAQ;AAEnC,KAAA,QAAA,IAAA,YAAA,QAAA,IAAA,aAAqD,KACnD,SAAQ,OAAO,KACb,uBAAA,QAAA,IAAA,SAA4C,oDAAoD,KAAK,6CACtG;CAGH,MAAM,cAA4B;EAChC,YAAY,QAAQ;EACpB,MAAM,cAAc;EACpB;EACA,OAAO;GACL,QAAQ,QAAQ;GAChB,WAAW,CAAC,CAAC,aAAa;GAC3B;EACF;AAED,KAAI;AAEF,SADgB,MAAM,cAAc,aAAa,MAAM,EACzC,UAAU;AAExB,SAAO,EACL,SAAS,MACV;UACM,GAAG;AACV,UAAQ,MAAM,EAAE;AAChB,SAAO,EACL,SAAS,OACV;;;AAIL,IAAA,2BAAA,GAAA,0BAAA,eAA6B,YAAY"}
1
+ {"version":3,"file":"vite-build.impl.js","names":[],"sources":["../../../../../../../../vite-plugin-angular-tools/src/builders/vite/vite-build.impl.ts"],"sourcesContent":["import {\n BuilderContext,\n BuilderOutput,\n createBuilder,\n targetFromTargetString,\n} from '@angular-devkit/architect';\nimport type { InlineConfig } from 'vite';\nimport { ViteBuildSchema } from './schema';\n\nasync function viteBuilder(\n options: ViteBuildSchema,\n context: BuilderContext,\n): Promise<BuilderOutput> {\n const { createBuilder } = await Function('return import(\"vite\")')();\n if (!context.target) {\n throw new Error('Builder must be executed with a target');\n }\n const projectConfig = await context.getProjectMetadata(context.target);\n const projectName = context.target.project;\n const configuration = context.target.configuration || 'production';\n const buildTargetSpecifier = `::${configuration}`;\n const buildTarget = targetFromTargetString(\n buildTargetSpecifier,\n projectName,\n 'build',\n );\n\n const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);\n const rawBuildOptions = await context.getTargetOptions(buildTarget);\n const buildOptions = await context.validateOptions(\n rawBuildOptions,\n browserBuilderName,\n );\n\n // Explicit build options and the requested configuration win over an\n // ambient NODE_ENV, so `build:production` cannot silently produce a\n // development build when NODE_ENV happens to be set. See #2458.\n const mode = (buildOptions.mode ?? configuration) as string;\n\n if (process.env.NODE_ENV && process.env.NODE_ENV !== mode) {\n context.logger.warn(\n `NODE_ENV is set to \"${process.env.NODE_ENV}\" but is ignored because the build resolved mode \"${mode}\" from the build options and configuration.`,\n );\n }\n\n const buildConfig: InlineConfig = {\n configFile: options.configFile,\n root: projectConfig.root as string,\n mode,\n build: {\n outDir: options.outputPath,\n sourcemap: !!buildOptions.sourcemap,\n },\n };\n\n try {\n const builder = await createBuilder(buildConfig, false);\n await builder.buildApp();\n\n return {\n success: true,\n };\n } catch (e) {\n console.error(e);\n return {\n success: false,\n };\n }\n}\n\nexport default createBuilder(viteBuilder) as any;\n"],"mappings":";;AASA,eAAe,YACb,SACA,SACwB;CACxB,MAAM,EAAE,kBAAkB,MAAM,SAAS,yBAAuB,CAAC,CAAC;CAClE,IAAI,CAAC,QAAQ,QACX,MAAM,IAAI,MAAM,wCAAwC;CAE1D,MAAM,gBAAgB,MAAM,QAAQ,mBAAmB,QAAQ,MAAM;CACrE,MAAM,cAAc,QAAQ,OAAO;CACnC,MAAM,gBAAgB,QAAQ,OAAO,iBAAiB;CACtD,MAAM,uBAAuB,KAAK;CAClC,MAAM,eAAA,GAAc,0BAAA,uBAAA,CAClB,sBACA,aACA,OACF;CAEA,MAAM,qBAAqB,MAAM,QAAQ,wBAAwB,WAAW;CAC5E,MAAM,kBAAkB,MAAM,QAAQ,iBAAiB,WAAW;CAClE,MAAM,eAAe,MAAM,QAAQ,gBACjC,iBACA,kBACF;CAKA,MAAM,OAAQ,aAAa,QAAQ;CAEnC,IAAA,QAAA,IAAA,YAAA,QAAA,IAAA,aAAqD,MACnD,QAAQ,OAAO,KACb,uBAAA,QAAA,IAAA,SAA4C,oDAAoD,KAAK,4CACvG;CAGF,MAAM,cAA4B;EAChC,YAAY,QAAQ;EACpB,MAAM,cAAc;EACpB;EACA,OAAO;GACL,QAAQ,QAAQ;GAChB,WAAW,CAAC,CAAC,aAAa;EAC5B;CACF;CAEA,IAAI;EAEF,OAAM,MADgB,cAAc,aAAa,KAAK,EAAA,CACxC,SAAS;EAEvB,OAAO,EACL,SAAS,KACX;CACF,SAAS,GAAG;EACV,QAAQ,MAAM,CAAC;EACf,OAAO,EACL,SAAS,MACX;CACF;AACF;AAEA,IAAA,2BAAA,GAAe,0BAAA,cAAA,CAAc,WAAW"}
@@ -5,7 +5,8 @@ async function viteDevServerBuilder(options, context) {
5
5
  if (!context.target) throw new Error("Builder must be executed with a target");
6
6
  const projectConfig = await context.getProjectMetadata(context.target);
7
7
  const projectName = context.target.project;
8
- const buildTarget = (0, _angular_devkit_architect.targetFromTargetString)(options.buildTarget ?? `::development`, projectName, "build");
8
+ const buildTargetSpecifier = options.buildTarget ?? `::development`;
9
+ const buildTarget = (0, _angular_devkit_architect.targetFromTargetString)(buildTargetSpecifier, projectName, "build");
9
10
  const browserBuilderName = await context.getBuilderNameForTarget(buildTarget);
10
11
  const rawBuildOptions = await context.getTargetOptions(buildTarget);
11
12
  const buildOptions = await context.validateOptions(rawBuildOptions, browserBuilderName);