@ttsc/unplugin 0.32.0 → 0.32.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 (93) hide show
  1. package/lib/core/options/ResolvedTtscUnpluginOptions.d.cts +2 -0
  2. package/lib/core/options/ResolvedTtscUnpluginOptions.d.mts +2 -0
  3. package/lib/core/options/ResolvedTtscUnpluginOptions.d.ts +2 -0
  4. package/lib/core/options/TtscUnpluginOptions.d.cts +12 -2
  5. package/lib/core/options/TtscUnpluginOptions.d.mts +12 -2
  6. package/lib/core/options/TtscUnpluginOptions.d.ts +12 -2
  7. package/lib/core/options/resolveOptions.d.cts +4 -3
  8. package/lib/core/options/resolveOptions.d.mts +4 -3
  9. package/lib/core/options/resolveOptions.d.ts +4 -3
  10. package/lib/core/options/resolveOptions.js +5 -3
  11. package/lib/core/options/resolveOptions.js.map +1 -1
  12. package/lib/core/options/resolveOptions.mjs +5 -3
  13. package/lib/core/options/resolveOptions.mjs.map +1 -1
  14. package/lib/core/transform/TtscPrecompilation.d.cts +52 -0
  15. package/lib/core/transform/TtscPrecompilation.d.mts +52 -0
  16. package/lib/core/transform/TtscPrecompilation.d.ts +52 -0
  17. package/lib/core/transform/TtscPrecompilation.js +101 -0
  18. package/lib/core/transform/TtscPrecompilation.js.map +1 -0
  19. package/lib/core/transform/TtscPrecompilation.mjs +101 -0
  20. package/lib/core/transform/TtscPrecompilation.mjs.map +1 -0
  21. package/lib/core/transform/cache/selectCachedGenerationAction.d.cts +2 -0
  22. package/lib/core/transform/cache/selectCachedGenerationAction.d.mts +2 -0
  23. package/lib/core/transform/cache/selectCachedGenerationAction.d.ts +2 -0
  24. package/lib/core/transform/cache/selectCachedGenerationAction.js +1 -1
  25. package/lib/core/transform/cache/selectCachedGenerationAction.js.map +1 -1
  26. package/lib/core/transform/cache/selectCachedGenerationAction.mjs +1 -1
  27. package/lib/core/transform/cache/selectCachedGenerationAction.mjs.map +1 -1
  28. package/lib/core/transform/cache/withdrawTtscTransformGenerations.js +2 -0
  29. package/lib/core/transform/cache/withdrawTtscTransformGenerations.js.map +1 -1
  30. package/lib/core/transform/cache/withdrawTtscTransformGenerations.mjs +2 -0
  31. package/lib/core/transform/cache/withdrawTtscTransformGenerations.mjs.map +1 -1
  32. package/lib/core/transform/generation/captureTransformGeneration.d.cts +2 -0
  33. package/lib/core/transform/generation/captureTransformGeneration.d.mts +2 -0
  34. package/lib/core/transform/generation/captureTransformGeneration.d.ts +2 -0
  35. package/lib/core/transform/generation/captureTransformGeneration.js +7 -2
  36. package/lib/core/transform/generation/captureTransformGeneration.js.map +1 -1
  37. package/lib/core/transform/generation/captureTransformGeneration.mjs +7 -2
  38. package/lib/core/transform/generation/captureTransformGeneration.mjs.map +1 -1
  39. package/lib/core/transform/generation/transformProject.d.cts +2 -0
  40. package/lib/core/transform/generation/transformProject.d.mts +2 -0
  41. package/lib/core/transform/generation/transformProject.d.ts +2 -0
  42. package/lib/core/transform/generation/transformProject.js.map +1 -1
  43. package/lib/core/transform/generation/transformProject.mjs.map +1 -1
  44. package/lib/core/transform/transformTtsc.d.cts +8 -24
  45. package/lib/core/transform/transformTtsc.d.mts +8 -24
  46. package/lib/core/transform/transformTtsc.d.ts +8 -24
  47. package/lib/core/transform/transformTtsc.js +51 -31
  48. package/lib/core/transform/transformTtsc.js.map +1 -1
  49. package/lib/core/transform/transformTtsc.mjs +51 -31
  50. package/lib/core/transform/transformTtsc.mjs.map +1 -1
  51. package/lib/core/transform/validation/captureUniversalHostInputValidation.d.cts +1 -1
  52. package/lib/core/transform/validation/captureUniversalHostInputValidation.d.mts +1 -1
  53. package/lib/core/transform/validation/captureUniversalHostInputValidation.d.ts +1 -1
  54. package/lib/core/transform/validation/captureUniversalHostInputValidation.js +12 -4
  55. package/lib/core/transform/validation/captureUniversalHostInputValidation.js.map +1 -1
  56. package/lib/core/transform/validation/captureUniversalHostInputValidation.mjs +12 -4
  57. package/lib/core/transform/validation/captureUniversalHostInputValidation.mjs.map +1 -1
  58. package/lib/core/transform/validation/matchesCachedSource.d.cts +9 -2
  59. package/lib/core/transform/validation/matchesCachedSource.d.mts +9 -2
  60. package/lib/core/transform/validation/matchesCachedSource.d.ts +9 -2
  61. package/lib/core/transform/validation/matchesCachedSource.js +11 -3
  62. package/lib/core/transform/validation/matchesCachedSource.js.map +1 -1
  63. package/lib/core/transform/validation/matchesCachedSource.mjs +11 -3
  64. package/lib/core/transform/validation/matchesCachedSource.mjs.map +1 -1
  65. package/lib/core/transform/watch/TtscTransformHooks.d.cts +9 -0
  66. package/lib/core/transform/watch/TtscTransformHooks.d.mts +9 -0
  67. package/lib/core/transform/watch/TtscTransformHooks.d.ts +9 -0
  68. package/lib/core/unplugin.js +14 -0
  69. package/lib/core/unplugin.js.map +1 -1
  70. package/lib/core/unplugin.mjs +14 -0
  71. package/lib/core/unplugin.mjs.map +1 -1
  72. package/lib/core/vite/installViteDependencyScanPlugins.d.cts +46 -0
  73. package/lib/core/vite/installViteDependencyScanPlugins.d.mts +46 -0
  74. package/lib/core/vite/installViteDependencyScanPlugins.d.ts +46 -0
  75. package/lib/core/vite/installViteDependencyScanPlugins.js +186 -0
  76. package/lib/core/vite/installViteDependencyScanPlugins.js.map +1 -0
  77. package/lib/core/vite/installViteDependencyScanPlugins.mjs +184 -0
  78. package/lib/core/vite/installViteDependencyScanPlugins.mjs.map +1 -0
  79. package/package.json +5 -4
  80. package/src/core/options/ResolvedTtscUnpluginOptions.ts +3 -0
  81. package/src/core/options/TtscUnpluginOptions.ts +13 -2
  82. package/src/core/options/resolveOptions.ts +6 -3
  83. package/src/core/transform/TtscPrecompilation.ts +103 -0
  84. package/src/core/transform/cache/selectCachedGenerationAction.ts +3 -0
  85. package/src/core/transform/cache/withdrawTtscTransformGenerations.ts +2 -0
  86. package/src/core/transform/generation/captureTransformGeneration.ts +12 -2
  87. package/src/core/transform/generation/transformProject.ts +3 -0
  88. package/src/core/transform/transformTtsc.ts +81 -36
  89. package/src/core/transform/validation/captureUniversalHostInputValidation.ts +12 -4
  90. package/src/core/transform/validation/matchesCachedSource.ts +9 -2
  91. package/src/core/transform/watch/TtscTransformHooks.ts +10 -0
  92. package/src/core/unplugin.ts +32 -0
  93. package/src/core/vite/installViteDependencyScanPlugins.ts +219 -0
@@ -0,0 +1,46 @@
1
+ import type { BuildOptions } from "esbuild";
2
+ import type { TtscTransformResult } from "../transform/TtscTransformResult.mjs";
3
+ /**
4
+ * Exposes imports introduced by ttsc plugins to Vite's dependency scanner.
5
+ *
6
+ * Vite scans files without its normal transform hooks. Its optimizer plugins
7
+ * are the supported connection: Rolldown transforms the scanner's loaded text,
8
+ * while esbuild scans transformed modules in a separate namespace and also
9
+ * imports each original through Vite's loader. That original graph preserves
10
+ * glob, JSX and user loaders; the transformed graph adds complete relative
11
+ * import chains without a second parser or artificial exports.
12
+ *
13
+ * Vite's esbuild scanner supplies stdin; dependency bundling supplies entry
14
+ * points. Only the scanner gets the extra original graph, because publishing
15
+ * that graph would execute untransformed code alongside transformed code.
16
+ * Bundling applies ordinary transforms after user loaders instead. Supplying
17
+ * both stdin and entryPoints is not a supported Vite optimizer configuration.
18
+ *
19
+ * The caller owns compilation, aliases, validation and cache lifetime. Each
20
+ * environment keeps its own optimizer settings and existing plugins. Disabled
21
+ * discovery is left alone, and repeated installation on one settings object
22
+ * within this call is suppressed.
23
+ *
24
+ * @evidence contracts/common.md#principled-implementation Official optimizer hooks and the host's Rolldown capability select the real backend. Esbuild's stdin scan parses transformed namespaces plus actual-loader originals, while entry-point dependency bundles receive ordinary transforms without duplicate runtime source.
25
+ * @evidence contracts/common.md#clear-and-simple-design One installer selects the host's resolved optimizer backend and delegates compilation to the adapter's existing transform owner.
26
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Uses published setup, input options, namespaces, load, resolve and transform APIs. Synthetic original-import edges belong only to the unpublished dependency scan, and no host method, global, package name or expected dependency is replaced or special-cased.
27
+ * @evidence contracts/common.md#meaningful-documentation Prose explains the missing transform phase, original-loader ownership, scan versus bundle behavior, caller-owned generation validity and environment-specific option preservation.
28
+ * @evidence contracts/portability.md#os-neutral-implementation Node reads native paths and derives their resolve directories; Vite's resolver retains workspace, alias and filesystem identity policy. No OS-name or case assumption is introduced.
29
+ * @evidence contracts/performance.md#efficient-algorithms Esbuild scans at most a transformed and an original graph node per reached TypeScript source, sharing host cycle detection and parsing. Each interception delegates native resolution once. Active equal requests yield to the next resolver while the initiating interception retains the transformed graph edge; compilation and validation retain their own costs.
30
+ * @evidence contracts/performance.md#reuse-equivalent-work Scanner deliveries use the caller's transform cache and proof rules. Existing optimizer plugin objects remain shared by identity. Each distinct backend settings object receives one Rolldown transform or one prepended esbuild scanner and one appended bundle transform per installation.
31
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Settings retain plugin closures for their Vite configuration lifetime. Active resolution keys are removed in finally; module graph state belongs to the host's scanner context. No child build, module history or separate compiler cache is retained, and the caller releases generations at its existing Vite boundaries.
32
+ */
33
+ export declare function installViteDependencyScanPlugins(config: {
34
+ command: string;
35
+ optimizeDeps: {
36
+ disabled?: boolean | "build" | "dev";
37
+ noDiscovery?: boolean;
38
+ esbuildOptions?: BuildOptions;
39
+ rolldownOptions?: {
40
+ plugins?: unknown;
41
+ };
42
+ };
43
+ environments?: Record<string, {
44
+ optimizeDeps?: typeof config.optimizeDeps;
45
+ }>;
46
+ }, includes: (file: string) => boolean, transform: (source: string, file: string) => Promise<TtscTransformResult | undefined>, backend: "esbuild" | "rolldown"): void;
@@ -0,0 +1,46 @@
1
+ import type { BuildOptions } from "esbuild";
2
+ import type { TtscTransformResult } from "../transform/TtscTransformResult";
3
+ /**
4
+ * Exposes imports introduced by ttsc plugins to Vite's dependency scanner.
5
+ *
6
+ * Vite scans files without its normal transform hooks. Its optimizer plugins
7
+ * are the supported connection: Rolldown transforms the scanner's loaded text,
8
+ * while esbuild scans transformed modules in a separate namespace and also
9
+ * imports each original through Vite's loader. That original graph preserves
10
+ * glob, JSX and user loaders; the transformed graph adds complete relative
11
+ * import chains without a second parser or artificial exports.
12
+ *
13
+ * Vite's esbuild scanner supplies stdin; dependency bundling supplies entry
14
+ * points. Only the scanner gets the extra original graph, because publishing
15
+ * that graph would execute untransformed code alongside transformed code.
16
+ * Bundling applies ordinary transforms after user loaders instead. Supplying
17
+ * both stdin and entryPoints is not a supported Vite optimizer configuration.
18
+ *
19
+ * The caller owns compilation, aliases, validation and cache lifetime. Each
20
+ * environment keeps its own optimizer settings and existing plugins. Disabled
21
+ * discovery is left alone, and repeated installation on one settings object
22
+ * within this call is suppressed.
23
+ *
24
+ * @evidence contracts/common.md#principled-implementation Official optimizer hooks and the host's Rolldown capability select the real backend. Esbuild's stdin scan parses transformed namespaces plus actual-loader originals, while entry-point dependency bundles receive ordinary transforms without duplicate runtime source.
25
+ * @evidence contracts/common.md#clear-and-simple-design One installer selects the host's resolved optimizer backend and delegates compilation to the adapter's existing transform owner.
26
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Uses published setup, input options, namespaces, load, resolve and transform APIs. Synthetic original-import edges belong only to the unpublished dependency scan, and no host method, global, package name or expected dependency is replaced or special-cased.
27
+ * @evidence contracts/common.md#meaningful-documentation Prose explains the missing transform phase, original-loader ownership, scan versus bundle behavior, caller-owned generation validity and environment-specific option preservation.
28
+ * @evidence contracts/portability.md#os-neutral-implementation Node reads native paths and derives their resolve directories; Vite's resolver retains workspace, alias and filesystem identity policy. No OS-name or case assumption is introduced.
29
+ * @evidence contracts/performance.md#efficient-algorithms Esbuild scans at most a transformed and an original graph node per reached TypeScript source, sharing host cycle detection and parsing. Each interception delegates native resolution once. Active equal requests yield to the next resolver while the initiating interception retains the transformed graph edge; compilation and validation retain their own costs.
30
+ * @evidence contracts/performance.md#reuse-equivalent-work Scanner deliveries use the caller's transform cache and proof rules. Existing optimizer plugin objects remain shared by identity. Each distinct backend settings object receives one Rolldown transform or one prepended esbuild scanner and one appended bundle transform per installation.
31
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Settings retain plugin closures for their Vite configuration lifetime. Active resolution keys are removed in finally; module graph state belongs to the host's scanner context. No child build, module history or separate compiler cache is retained, and the caller releases generations at its existing Vite boundaries.
32
+ */
33
+ export declare function installViteDependencyScanPlugins(config: {
34
+ command: string;
35
+ optimizeDeps: {
36
+ disabled?: boolean | "build" | "dev";
37
+ noDiscovery?: boolean;
38
+ esbuildOptions?: BuildOptions;
39
+ rolldownOptions?: {
40
+ plugins?: unknown;
41
+ };
42
+ };
43
+ environments?: Record<string, {
44
+ optimizeDeps?: typeof config.optimizeDeps;
45
+ }>;
46
+ }, includes: (file: string) => boolean, transform: (source: string, file: string) => Promise<TtscTransformResult | undefined>, backend: "esbuild" | "rolldown"): void;
@@ -0,0 +1,186 @@
1
+ 'use strict';
2
+
3
+ var fs = require('node:fs');
4
+ var path = require('node:path');
5
+ var typescriptTransformSourcePattern = require('../source/typescriptTransformSourcePattern.js');
6
+ var inlineSourceMap = require('../transform/utils/inlineSourceMap.js');
7
+ var isHostWrapperQuery = require('../transform/utils/isHostWrapperQuery.js');
8
+ var stripQuery = require('../transform/utils/stripQuery.js');
9
+
10
+ /**
11
+ * Exposes imports introduced by ttsc plugins to Vite's dependency scanner.
12
+ *
13
+ * Vite scans files without its normal transform hooks. Its optimizer plugins
14
+ * are the supported connection: Rolldown transforms the scanner's loaded text,
15
+ * while esbuild scans transformed modules in a separate namespace and also
16
+ * imports each original through Vite's loader. That original graph preserves
17
+ * glob, JSX and user loaders; the transformed graph adds complete relative
18
+ * import chains without a second parser or artificial exports.
19
+ *
20
+ * Vite's esbuild scanner supplies stdin; dependency bundling supplies entry
21
+ * points. Only the scanner gets the extra original graph, because publishing
22
+ * that graph would execute untransformed code alongside transformed code.
23
+ * Bundling applies ordinary transforms after user loaders instead. Supplying
24
+ * both stdin and entryPoints is not a supported Vite optimizer configuration.
25
+ *
26
+ * The caller owns compilation, aliases, validation and cache lifetime. Each
27
+ * environment keeps its own optimizer settings and existing plugins. Disabled
28
+ * discovery is left alone, and repeated installation on one settings object
29
+ * within this call is suppressed.
30
+ *
31
+ * @evidence contracts/common.md#principled-implementation Official optimizer hooks and the host's Rolldown capability select the real backend. Esbuild's stdin scan parses transformed namespaces plus actual-loader originals, while entry-point dependency bundles receive ordinary transforms without duplicate runtime source.
32
+ * @evidence contracts/common.md#clear-and-simple-design One installer selects the host's resolved optimizer backend and delegates compilation to the adapter's existing transform owner.
33
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Uses published setup, input options, namespaces, load, resolve and transform APIs. Synthetic original-import edges belong only to the unpublished dependency scan, and no host method, global, package name or expected dependency is replaced or special-cased.
34
+ * @evidence contracts/common.md#meaningful-documentation Prose explains the missing transform phase, original-loader ownership, scan versus bundle behavior, caller-owned generation validity and environment-specific option preservation.
35
+ * @evidence contracts/portability.md#os-neutral-implementation Node reads native paths and derives their resolve directories; Vite's resolver retains workspace, alias and filesystem identity policy. No OS-name or case assumption is introduced.
36
+ * @evidence contracts/performance.md#efficient-algorithms Esbuild scans at most a transformed and an original graph node per reached TypeScript source, sharing host cycle detection and parsing. Each interception delegates native resolution once. Active equal requests yield to the next resolver while the initiating interception retains the transformed graph edge; compilation and validation retain their own costs.
37
+ * @evidence contracts/performance.md#reuse-equivalent-work Scanner deliveries use the caller's transform cache and proof rules. Existing optimizer plugin objects remain shared by identity. Each distinct backend settings object receives one Rolldown transform or one prepended esbuild scanner and one appended bundle transform per installation.
38
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Settings retain plugin closures for their Vite configuration lifetime. Active resolution keys are removed in finally; module graph state belongs to the host's scanner context. No child build, module history or separate compiler cache is retained, and the caller releases generations at its existing Vite boundaries.
39
+ */
40
+ function installViteDependencyScanPlugins(config, includes, transform, backend) {
41
+ if (config.command !== "serve")
42
+ return;
43
+ const installed = new Set();
44
+ const backends = new Set();
45
+ for (const options of [
46
+ config.optimizeDeps,
47
+ ...Object.values(config.environments ?? {}).map((environment) => environment.optimizeDeps),
48
+ ]) {
49
+ if (options === undefined ||
50
+ installed.has(options) ||
51
+ options.noDiscovery === true ||
52
+ options.disabled === true ||
53
+ options.disabled === "dev")
54
+ continue;
55
+ installed.add(options);
56
+ if (backend === "rolldown") {
57
+ options.rolldownOptions ??= {};
58
+ if (backends.has(options.rolldownOptions))
59
+ continue;
60
+ backends.add(options.rolldownOptions);
61
+ const existing = options.rolldownOptions.plugins;
62
+ options.rolldownOptions.plugins = [
63
+ ...(existing === undefined ? [] : [existing]),
64
+ {
65
+ name: "ttsc-dependency-scan",
66
+ async transform(source, file) {
67
+ if (isHostWrapperQuery.isHostWrapperQuery(file) || !includes(stripQuery.stripQuery(file)))
68
+ return;
69
+ return transform(source, stripQuery.stripQuery(file));
70
+ },
71
+ },
72
+ ];
73
+ continue;
74
+ }
75
+ options.esbuildOptions ??= {};
76
+ if (backends.has(options.esbuildOptions))
77
+ continue;
78
+ backends.add(options.esbuildOptions);
79
+ const plugin = {
80
+ name: "ttsc-dependency-scan",
81
+ setup(build) {
82
+ if (build.initialOptions.stdin === undefined)
83
+ return;
84
+ const namespace = "ttsc-dependency-scan";
85
+ const originalPrefix = "ttsc-dependency-original:";
86
+ const resolving = new Set();
87
+ build.onResolve({ filter: /^ttsc-dependency-original:/, namespace }, (imported) => ({
88
+ path: imported.path.slice(originalPrefix.length),
89
+ namespace: "file",
90
+ pluginData: imported.pluginData,
91
+ }));
92
+ build.onResolve({ filter: /.*/ }, async (imported) => {
93
+ if (imported.namespace !== "file" &&
94
+ imported.namespace !== namespace &&
95
+ imported.namespace !== "")
96
+ return;
97
+ const key = JSON.stringify([
98
+ imported.namespace === namespace
99
+ ? "file"
100
+ : imported.namespace || "file",
101
+ imported.path,
102
+ imported.importer,
103
+ imported.resolveDir,
104
+ imported.kind,
105
+ imported.with,
106
+ ]);
107
+ // Equal active requests include both self recursion and concurrent
108
+ // duplicates. Their raw edges cannot remove the first request's
109
+ // transformed node, which still exposes the added dependency closure.
110
+ if (resolving.has(key))
111
+ return;
112
+ resolving.add(key);
113
+ let resolved;
114
+ try {
115
+ resolved = await build.resolve(imported.path, {
116
+ importer: imported.importer,
117
+ resolveDir: imported.resolveDir,
118
+ namespace: "file",
119
+ kind: imported.kind,
120
+ pluginData: imported.pluginData,
121
+ with: imported.with,
122
+ });
123
+ }
124
+ finally {
125
+ resolving.delete(key);
126
+ }
127
+ if (resolved.errors.length !== 0 ||
128
+ resolved.external ||
129
+ resolved.namespace !== "file" ||
130
+ !includes(resolved.path) ||
131
+ isHostWrapperQuery.isHostWrapperQuery(resolved.suffix))
132
+ return resolved;
133
+ const loader = build.initialOptions.loader?.[path.extname(resolved.path)];
134
+ if (loader !== undefined &&
135
+ !["js", "jsx", "ts", "tsx"].includes(loader))
136
+ return resolved;
137
+ return { ...resolved, namespace, pluginData: resolved };
138
+ });
139
+ build.onLoad({ filter: typescriptTransformSourcePattern.typescriptTransformSourcePattern, namespace }, async ({ path: file, pluginData }) => {
140
+ const resolved = pluginData;
141
+ const source = await fs.promises.readFile(file, "utf8");
142
+ const transformed = await transform(source, file);
143
+ return {
144
+ contents: `${transformed?.code ?? source}\nimport ${JSON.stringify(originalPrefix + file)};\n`,
145
+ loader: build.initialOptions.loader?.[path.extname(file)] ??
146
+ (file.endsWith(".tsx") ? "tsx" : "ts"),
147
+ resolveDir: path.dirname(file),
148
+ pluginData: resolved.pluginData,
149
+ };
150
+ });
151
+ },
152
+ };
153
+ const bundle = {
154
+ name: "ttsc-dependency-transform",
155
+ setup(build) {
156
+ if (build.initialOptions.stdin !== undefined)
157
+ return;
158
+ build.onLoad({ filter: typescriptTransformSourcePattern.typescriptTransformSourcePattern, namespace: "file" }, async ({ path: file }) => {
159
+ if (!includes(file))
160
+ return;
161
+ const loader = build.initialOptions.loader?.[path.extname(file)] ??
162
+ (file.endsWith(".tsx") ? "tsx" : "ts");
163
+ if (!["js", "jsx", "ts", "tsx"].includes(loader))
164
+ return;
165
+ const source = await fs.promises.readFile(file, "utf8");
166
+ const result = await transform(source, file);
167
+ if (result === undefined)
168
+ return;
169
+ return {
170
+ contents: inlineSourceMap.inlineSourceMap(result),
171
+ loader,
172
+ resolveDir: path.dirname(file),
173
+ };
174
+ });
175
+ },
176
+ };
177
+ options.esbuildOptions.plugins = [
178
+ plugin,
179
+ ...(options.esbuildOptions.plugins ?? []),
180
+ bundle,
181
+ ];
182
+ }
183
+ }
184
+
185
+ exports.installViteDependencyScanPlugins = installViteDependencyScanPlugins;
186
+ //# sourceMappingURL=installViteDependencyScanPlugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installViteDependencyScanPlugins.js","sources":["../../../src/core/vite/installViteDependencyScanPlugins.ts"],"sourcesContent":[null],"names":["isHostWrapperQuery","stripQuery","typescriptTransformSourcePattern","inlineSourceMap"],"mappings":"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"}
@@ -0,0 +1,184 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { typescriptTransformSourcePattern } from '../source/typescriptTransformSourcePattern.mjs';
4
+ import { inlineSourceMap } from '../transform/utils/inlineSourceMap.mjs';
5
+ import { isHostWrapperQuery } from '../transform/utils/isHostWrapperQuery.mjs';
6
+ import { stripQuery } from '../transform/utils/stripQuery.mjs';
7
+
8
+ /**
9
+ * Exposes imports introduced by ttsc plugins to Vite's dependency scanner.
10
+ *
11
+ * Vite scans files without its normal transform hooks. Its optimizer plugins
12
+ * are the supported connection: Rolldown transforms the scanner's loaded text,
13
+ * while esbuild scans transformed modules in a separate namespace and also
14
+ * imports each original through Vite's loader. That original graph preserves
15
+ * glob, JSX and user loaders; the transformed graph adds complete relative
16
+ * import chains without a second parser or artificial exports.
17
+ *
18
+ * Vite's esbuild scanner supplies stdin; dependency bundling supplies entry
19
+ * points. Only the scanner gets the extra original graph, because publishing
20
+ * that graph would execute untransformed code alongside transformed code.
21
+ * Bundling applies ordinary transforms after user loaders instead. Supplying
22
+ * both stdin and entryPoints is not a supported Vite optimizer configuration.
23
+ *
24
+ * The caller owns compilation, aliases, validation and cache lifetime. Each
25
+ * environment keeps its own optimizer settings and existing plugins. Disabled
26
+ * discovery is left alone, and repeated installation on one settings object
27
+ * within this call is suppressed.
28
+ *
29
+ * @evidence contracts/common.md#principled-implementation Official optimizer hooks and the host's Rolldown capability select the real backend. Esbuild's stdin scan parses transformed namespaces plus actual-loader originals, while entry-point dependency bundles receive ordinary transforms without duplicate runtime source.
30
+ * @evidence contracts/common.md#clear-and-simple-design One installer selects the host's resolved optimizer backend and delegates compilation to the adapter's existing transform owner.
31
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Uses published setup, input options, namespaces, load, resolve and transform APIs. Synthetic original-import edges belong only to the unpublished dependency scan, and no host method, global, package name or expected dependency is replaced or special-cased.
32
+ * @evidence contracts/common.md#meaningful-documentation Prose explains the missing transform phase, original-loader ownership, scan versus bundle behavior, caller-owned generation validity and environment-specific option preservation.
33
+ * @evidence contracts/portability.md#os-neutral-implementation Node reads native paths and derives their resolve directories; Vite's resolver retains workspace, alias and filesystem identity policy. No OS-name or case assumption is introduced.
34
+ * @evidence contracts/performance.md#efficient-algorithms Esbuild scans at most a transformed and an original graph node per reached TypeScript source, sharing host cycle detection and parsing. Each interception delegates native resolution once. Active equal requests yield to the next resolver while the initiating interception retains the transformed graph edge; compilation and validation retain their own costs.
35
+ * @evidence contracts/performance.md#reuse-equivalent-work Scanner deliveries use the caller's transform cache and proof rules. Existing optimizer plugin objects remain shared by identity. Each distinct backend settings object receives one Rolldown transform or one prepended esbuild scanner and one appended bundle transform per installation.
36
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Settings retain plugin closures for their Vite configuration lifetime. Active resolution keys are removed in finally; module graph state belongs to the host's scanner context. No child build, module history or separate compiler cache is retained, and the caller releases generations at its existing Vite boundaries.
37
+ */
38
+ function installViteDependencyScanPlugins(config, includes, transform, backend) {
39
+ if (config.command !== "serve")
40
+ return;
41
+ const installed = new Set();
42
+ const backends = new Set();
43
+ for (const options of [
44
+ config.optimizeDeps,
45
+ ...Object.values(config.environments ?? {}).map((environment) => environment.optimizeDeps),
46
+ ]) {
47
+ if (options === undefined ||
48
+ installed.has(options) ||
49
+ options.noDiscovery === true ||
50
+ options.disabled === true ||
51
+ options.disabled === "dev")
52
+ continue;
53
+ installed.add(options);
54
+ if (backend === "rolldown") {
55
+ options.rolldownOptions ??= {};
56
+ if (backends.has(options.rolldownOptions))
57
+ continue;
58
+ backends.add(options.rolldownOptions);
59
+ const existing = options.rolldownOptions.plugins;
60
+ options.rolldownOptions.plugins = [
61
+ ...(existing === undefined ? [] : [existing]),
62
+ {
63
+ name: "ttsc-dependency-scan",
64
+ async transform(source, file) {
65
+ if (isHostWrapperQuery(file) || !includes(stripQuery(file)))
66
+ return;
67
+ return transform(source, stripQuery(file));
68
+ },
69
+ },
70
+ ];
71
+ continue;
72
+ }
73
+ options.esbuildOptions ??= {};
74
+ if (backends.has(options.esbuildOptions))
75
+ continue;
76
+ backends.add(options.esbuildOptions);
77
+ const plugin = {
78
+ name: "ttsc-dependency-scan",
79
+ setup(build) {
80
+ if (build.initialOptions.stdin === undefined)
81
+ return;
82
+ const namespace = "ttsc-dependency-scan";
83
+ const originalPrefix = "ttsc-dependency-original:";
84
+ const resolving = new Set();
85
+ build.onResolve({ filter: /^ttsc-dependency-original:/, namespace }, (imported) => ({
86
+ path: imported.path.slice(originalPrefix.length),
87
+ namespace: "file",
88
+ pluginData: imported.pluginData,
89
+ }));
90
+ build.onResolve({ filter: /.*/ }, async (imported) => {
91
+ if (imported.namespace !== "file" &&
92
+ imported.namespace !== namespace &&
93
+ imported.namespace !== "")
94
+ return;
95
+ const key = JSON.stringify([
96
+ imported.namespace === namespace
97
+ ? "file"
98
+ : imported.namespace || "file",
99
+ imported.path,
100
+ imported.importer,
101
+ imported.resolveDir,
102
+ imported.kind,
103
+ imported.with,
104
+ ]);
105
+ // Equal active requests include both self recursion and concurrent
106
+ // duplicates. Their raw edges cannot remove the first request's
107
+ // transformed node, which still exposes the added dependency closure.
108
+ if (resolving.has(key))
109
+ return;
110
+ resolving.add(key);
111
+ let resolved;
112
+ try {
113
+ resolved = await build.resolve(imported.path, {
114
+ importer: imported.importer,
115
+ resolveDir: imported.resolveDir,
116
+ namespace: "file",
117
+ kind: imported.kind,
118
+ pluginData: imported.pluginData,
119
+ with: imported.with,
120
+ });
121
+ }
122
+ finally {
123
+ resolving.delete(key);
124
+ }
125
+ if (resolved.errors.length !== 0 ||
126
+ resolved.external ||
127
+ resolved.namespace !== "file" ||
128
+ !includes(resolved.path) ||
129
+ isHostWrapperQuery(resolved.suffix))
130
+ return resolved;
131
+ const loader = build.initialOptions.loader?.[path.extname(resolved.path)];
132
+ if (loader !== undefined &&
133
+ !["js", "jsx", "ts", "tsx"].includes(loader))
134
+ return resolved;
135
+ return { ...resolved, namespace, pluginData: resolved };
136
+ });
137
+ build.onLoad({ filter: typescriptTransformSourcePattern, namespace }, async ({ path: file, pluginData }) => {
138
+ const resolved = pluginData;
139
+ const source = await fs.promises.readFile(file, "utf8");
140
+ const transformed = await transform(source, file);
141
+ return {
142
+ contents: `${transformed?.code ?? source}\nimport ${JSON.stringify(originalPrefix + file)};\n`,
143
+ loader: build.initialOptions.loader?.[path.extname(file)] ??
144
+ (file.endsWith(".tsx") ? "tsx" : "ts"),
145
+ resolveDir: path.dirname(file),
146
+ pluginData: resolved.pluginData,
147
+ };
148
+ });
149
+ },
150
+ };
151
+ const bundle = {
152
+ name: "ttsc-dependency-transform",
153
+ setup(build) {
154
+ if (build.initialOptions.stdin !== undefined)
155
+ return;
156
+ build.onLoad({ filter: typescriptTransformSourcePattern, namespace: "file" }, async ({ path: file }) => {
157
+ if (!includes(file))
158
+ return;
159
+ const loader = build.initialOptions.loader?.[path.extname(file)] ??
160
+ (file.endsWith(".tsx") ? "tsx" : "ts");
161
+ if (!["js", "jsx", "ts", "tsx"].includes(loader))
162
+ return;
163
+ const source = await fs.promises.readFile(file, "utf8");
164
+ const result = await transform(source, file);
165
+ if (result === undefined)
166
+ return;
167
+ return {
168
+ contents: inlineSourceMap(result),
169
+ loader,
170
+ resolveDir: path.dirname(file),
171
+ };
172
+ });
173
+ },
174
+ };
175
+ options.esbuildOptions.plugins = [
176
+ plugin,
177
+ ...(options.esbuildOptions.plugins ?? []),
178
+ bundle,
179
+ ];
180
+ }
181
+ }
182
+
183
+ export { installViteDependencyScanPlugins };
184
+ //# sourceMappingURL=installViteDependencyScanPlugins.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installViteDependencyScanPlugins.mjs","sources":["../../../src/core/vite/installViteDependencyScanPlugins.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttsc/unplugin",
3
- "version": "0.32.0",
3
+ "version": "0.32.1",
4
4
  "description": "Bundler adapters for ttsc plugins.",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
@@ -202,10 +202,10 @@
202
202
  "fsevents": "^2.3.3"
203
203
  },
204
204
  "peerDependencies": {
205
- "ttsc": "^0.32.0"
205
+ "ttsc": "^0.32.1"
206
206
  },
207
207
  "devDependencies": {
208
- "@wrtnlabs/evidence": "^0.5.0",
208
+ "@wrtnlabs/evidence": "^0.5.1",
209
209
  "@rollup/plugin-commonjs": "^29.0.2",
210
210
  "@rollup/plugin-node-resolve": "^16.0.3",
211
211
  "@types/node": "^25.3.0",
@@ -217,7 +217,8 @@
217
217
  "tslib": "^2.8.1",
218
218
  "typescript": "^7.0.2",
219
219
  "vite": "^7.3.5",
220
- "ttsc": "0.32.0"
220
+ "vite8": "npm:vite@^8.3.4",
221
+ "ttsc": "0.32.1"
221
222
  },
222
223
  "repository": {
223
224
  "type": "git",
@@ -37,6 +37,9 @@ import type { TtscUnpluginCompilerOptionsJson } from "./TtscUnpluginCompilerOpti
37
37
  * retained state at runtime.
38
38
  */
39
39
  export interface ResolvedTtscUnpluginOptions {
40
+ /** Explicit source entries prepared concurrently before their first import. */
41
+ precompile?: readonly string[];
42
+
40
43
  /** Compiler-options overlay applied on top of the discovered tsconfig. */
41
44
  compilerOptions: TtscUnpluginCompilerOptionsJson;
42
45
 
@@ -6,7 +6,7 @@ import type { TtscUnpluginCompilerOptionsJson } from "./TtscUnpluginCompilerOpti
6
6
  * Options accepted by the `@ttsc/unplugin` bundler adapter.
7
7
  *
8
8
  * @evidence contracts/common.md#principled-implementation
9
- * Optional project selection, a JSON compiler overlay and the distinct
9
+ * Explicit startup entries, optional project selection, a JSON compiler overlay and the distinct
10
10
  * undefined/false/array plugin states express the supported caller choices.
11
11
  * @evidence contracts/common.md#clear-and-simple-design
12
12
  * Config selection and common source root stay separate from compiler settings and
@@ -18,7 +18,7 @@ import type { TtscUnpluginCompilerOptionsJson } from "./TtscUnpluginCompilerOpti
18
18
  * Member JSDoc explains relative-path resolution and override precedence.
19
19
  * Separate member paragraphs and spacing follow the documentation guidance.
20
20
  * @evidence contracts/portability.md#os-neutral-implementation
21
- * Project and projectRoot carry native paths: relative spelling is
21
+ * Precompile entries, project and projectRoot carry native paths: relative spelling is
22
22
  * resolved against process.cwd at delivery. An omitted project requests
23
23
  * discovery; an omitted root uses the config directory. Compiler settings retain their compiler-owned path semantics;
24
24
  * this type imposes no separator or filesystem case policy.
@@ -33,6 +33,17 @@ import type { TtscUnpluginCompilerOptionsJson } from "./TtscUnpluginCompilerOpti
33
33
  * state at runtime.
34
34
  */
35
35
  export interface TtscUnpluginOptions {
36
+ /**
37
+ * Source entries whose projects start compiling together on the first load.
38
+ *
39
+ * Paths resolve from `process.cwd()` and use the same project selection,
40
+ * compiler options and plugins as delivered modules. Each project retains its
41
+ * normal input proofs. Listing an entry opts its project into compilation
42
+ * even if the host never imports it. Omission keeps compilation
43
+ * demand-driven.
44
+ */
45
+ precompile?: readonly string[];
46
+
36
47
  /**
37
48
  * Project config used by the bundler adapter.
38
49
  *
@@ -18,10 +18,11 @@ const defaultOptions: ResolvedTtscUnpluginOptions = {
18
18
  * @evidence contracts/common.md#principled-implementation
19
19
  * Nullish defaults normalize the overlay and project; a presence check
20
20
  * preserves explicit false and undefined plugin overrides. Object spread
21
- * detaches top-level compiler keys while nested values retain caller identity.
21
+ * detaches top-level compiler keys and the entry array while nested option
22
+ * values retain caller identity.
22
23
  * @evidence contracts/common.md#clear-and-simple-design
23
24
  * One returned record owns option normalization; transform code receives
24
- * the same four choices without a second defaults layer. The optional root
25
+ * the same choices without a second defaults layer. The optional root
25
26
  * retains its spelling until delivery resolves it against process.cwd.
26
27
  * @evidence contracts/common.md#prohibited-implementation-shortcuts
27
28
  * Empty defaults implement omission semantics, and the false branch implements
@@ -32,7 +33,7 @@ const defaultOptions: ResolvedTtscUnpluginOptions = {
32
33
  * @evidenceExclude contracts/portability.md#os-neutral-implementation
33
34
  * Performs no filesystem, path or process operation of its own.
34
35
  * @evidence contracts/performance.md#efficient-algorithms
35
- * One shallow object spread copies the supplied compiler-option keys in
36
+ * Shallow copies detach compiler-option keys and precompile entries in
36
37
  * linear time and space. Nested option values are not traversed; this copy
37
38
  * detaches the returned top-level overlay from later caller assignments.
38
39
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work
@@ -44,6 +45,8 @@ export function resolveOptions(
44
45
  options: TtscUnpluginOptions = {},
45
46
  ): ResolvedTtscUnpluginOptions {
46
47
  return {
48
+ precompile:
49
+ options.precompile === undefined ? undefined : [...options.precompile],
47
50
  compilerOptions: { ...(options.compilerOptions ?? {}) },
48
51
  plugins: "plugins" in options ? options.plugins : defaultOptions.plugins,
49
52
  project: options.project ?? defaultOptions.project,