@ttsc/unplugin 0.30.2 → 0.30.3

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.
@@ -1,11 +1,10 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
1
  import { createUnplugin } from 'unplugin';
2
+ import { createEsbuildOptions } from './esbuild.mjs';
4
3
  import { resolveOptions } from './options.mjs';
5
4
  import { typescriptTransformSourcePattern } from './sourceExtensions.mjs';
6
5
  import { createTtscTransformCache, stripQuery, transformTtsc, beginTtscTransformBuild, resetTtscTransformCache, isDeclarationFile } from './transform.mjs';
7
6
  export { captureWatchInputBaseline, captureWatchInputFileBaseline, collectExternalInputHashes, collectProjectInputHashSnapshot, collectProjectInputHashes, isProjectWalkPath, isWatchInputKeyBaseline, watchInputEvidenceMatchesBaseline } from './transform.mjs';
8
- import { createViteServeMissingInputWatch } from './viteServe.mjs';
7
+ import { createViteServeInputWatch } from './viteServe.mjs';
9
8
  export { mergeMembershipPolicyOverlay, readProjectMembershipPolicy, readTsconfigSourceSnapshot } from './tsconfigPaths.mjs';
10
9
  export { discoverNearestProjectTsconfig, findNearestProjectTsconfig, findProjectTsconfigs } from './projectDiscovery.mjs';
11
10
 
@@ -41,10 +40,13 @@ const virtualModulePattern = /\0/;
41
40
  * server configured without a watcher takes the pass lifecycle with them,
42
41
  * having declared it will observe no edit at all.
43
42
  */
44
- const unpluginFactory = (rawOptions = {}) => {
43
+ const unpluginFactory = (rawOptions = {}, meta) => {
45
44
  const options = resolveOptions(rawOptions);
45
+ if (meta.framework === "esbuild") {
46
+ return createEsbuildOptions(options, isTransformTarget);
47
+ }
46
48
  const transformCache = createTtscTransformCache();
47
- const missingInputs = createViteServeMissingInputWatch();
49
+ const serveInputs = createViteServeInputWatch();
48
50
  let aliases;
49
51
  let viteCommand;
50
52
  let viteWatching = true;
@@ -59,13 +61,6 @@ const unpluginFactory = (rawOptions = {}) => {
59
61
  // old containers cannot dispose a replacement's freshly initialized cache.
60
62
  let viteBuildOwners = new WeakSet();
61
63
  let viteBuildLifecycles = 0;
62
- // esbuild schedules one-shot onDispose callbacks after it settles the build
63
- // Promise. Acquire ownership only at onStart: plugin setup runs before build
64
- // option validation, and a validation failure has no onDispose callback with
65
- // which to release a setup-time owner. Once a build has actually started, the
66
- // count keeps an older delayed callback from disposing its active generation.
67
- const esbuildOwners = new WeakSet();
68
- let esbuildLifecycles = 0;
69
64
  return {
70
65
  name,
71
66
  enforce: "pre",
@@ -95,14 +90,11 @@ const unpluginFactory = (rawOptions = {}) => {
95
90
  viteBuildWatching =
96
91
  config.build?.watch != null;
97
92
  },
98
- // Vite serve funnels every transform-context `addWatchFile()` into the
99
- // module's added-import graph (`_addedImports`), which import-analysis
100
- // resolves like real imports. Capture the dev server so the transform
101
- // hook can route watch inputs that do not exist yet — superseding
102
- // resolution candidates above all — around that graph and still
103
- // invalidate their importers when the path is created.
93
+ // Compiler dependencies belong to the filesystem watch graph. Vite's
94
+ // transform-context addWatchFile also inserts runtime imports, so none
95
+ // of those dependencies may use that channel during serve (#1368).
104
96
  configureServer(server) {
105
- missingInputs.attach(server);
97
+ serveInputs.attach(server);
106
98
  },
107
99
  // Vite calls buildEnd when the dev server closes, and Rollup calls it at
108
100
  // the end of every build phase; drop every poller and, once the last
@@ -119,15 +111,15 @@ const unpluginFactory = (rawOptions = {}) => {
119
111
  // fixing one of the two sites alone left this host recompiling the whole
120
112
  // project per edit (samchon/ttsc#1301). The watching build hands its
121
113
  // teardown to `closeWatcher` below instead.
122
- buildEnd() {
114
+ async buildEnd() {
123
115
  if (viteBuildOwners.delete(this)) {
124
116
  viteBuildLifecycles -= 1;
125
117
  }
126
118
  if (viteBuildLifecycles === 0) {
127
- missingInputs.dispose();
128
119
  if (viteCommand === "serve" || !viteBuildWatching) {
129
120
  resetTtscTransformCache(transformCache);
130
121
  }
122
+ await serveInputs.dispose();
131
123
  }
132
124
  },
133
125
  // The watching build's real teardown, and the only hook in a
@@ -144,11 +136,11 @@ const unpluginFactory = (rawOptions = {}) => {
144
136
  // `buildEnd` would then decrement a counter that is already zero and
145
137
  // strand it below zero, after which the disposal above could never fire
146
138
  // again for this plugin instance.
147
- closeWatcher() {
139
+ async closeWatcher() {
148
140
  viteBuildOwners = new WeakSet();
149
141
  viteBuildLifecycles = 0;
150
- missingInputs.dispose();
151
142
  resetTtscTransformCache(transformCache);
143
+ await serveInputs.dispose();
152
144
  },
153
145
  },
154
146
  // Rollup and Rolldown carry none of the Vite block's hooks, so before this
@@ -198,23 +190,14 @@ const unpluginFactory = (rawOptions = {}) => {
198
190
  resetTtscTransformCache(transformCache);
199
191
  });
200
192
  },
201
- esbuild: {
202
- setup(build) {
203
- build.onStart(() => {
204
- if (!esbuildOwners.has(build)) {
205
- esbuildOwners.add(build);
206
- esbuildLifecycles += 1;
207
- }
208
- });
209
- build.onDispose(() => {
210
- if (!esbuildOwners.delete(build)) {
211
- return;
212
- }
213
- esbuildLifecycles -= 1;
214
- if (esbuildLifecycles === 0) {
215
- resetTtscTransformCache(transformCache);
216
- }
217
- });
193
+ farm: {
194
+ // Farm calls buildStart only for the initial compilation. Every update
195
+ // opens a new pass so a failed verdict can recover, while an unchanged
196
+ // successful generation remains reusable across its module deliveries.
197
+ updateModules: {
198
+ executor() {
199
+ beginTtscTransformBuild(transformCache);
200
+ },
218
201
  },
219
202
  },
220
203
  buildStart() {
@@ -258,58 +241,35 @@ const unpluginFactory = (rawOptions = {}) => {
258
241
  return undefined;
259
242
  }
260
243
  return transformTtsc(file, source, options, aliases, transformCache, {
261
- // Register the derived watch inputs (plugin-reported `dependencies`
262
- // unioned with the host-owned reference graph) so type-only inputs
263
- // invalidate this module in watch mode and persistent caches;
264
- // bundlers erase type-only imports from their own module graph and
265
- // would otherwise serve stale generated code. Under Vite serve a
266
- // resolver input that is not proven to be a file must not enter
267
- // `addWatchFile`: import-analysis resolves added imports and 500s on
268
- // missing paths and directories, so those are watched against their
269
- // compiler predicates instead and invalidate this module when the
270
- // observation changes.
271
- addWatchFile: (watched, evidence) => {
272
- if (viteCommand === "serve" && missingInputs.serving()) {
273
- const observation = evidence?.state?.codec === "predicates"
274
- ? evidence.state.observation
275
- : undefined;
276
- const unsafePredicate = observation !== undefined &&
277
- observation.fileExists !== true &&
278
- observation.stat !== "file" &&
279
- observation.readFile?.ok !== true
280
- ? observation
281
- : undefined;
282
- if (unsafePredicate !== undefined) {
283
- missingInputs.watch(watched, path.resolve(file), unsafePredicate);
284
- return;
244
+ // A watcherless server has no invalidation channel and needs no
245
+ // watch-input derivation. Every other host keeps its native contract.
246
+ addWatchFiles: viteCommand === "serve" && !viteWatching
247
+ ? undefined
248
+ : (inputs, failed) => {
249
+ if (viteCommand === "serve") {
250
+ serveInputs.replace(file, inputs, failed);
285
251
  }
286
- // Trust the generation's recorded existence when it supplied one:
287
- // every cache hit revalidates it, and probing each input again
288
- // costs one `existsSync` per input per delivered module.
289
- const unavailable = evidence?.unavailable ??
290
- (evidence === undefined
291
- ? !fs.existsSync(watched)
292
- ? "missing"
293
- : undefined
294
- : evidence.missing
295
- ? "missing"
296
- : undefined);
297
- if (unavailable !== undefined) {
298
- missingInputs.watch(watched, path.resolve(file), unavailable === "not-file" ? "file" : "exists");
299
- return;
252
+ else {
253
+ const native = this.getNativeBuildContext?.();
254
+ for (const input of inputs) {
255
+ if (native?.framework === "rspack" &&
256
+ native.loaderContext !== undefined) {
257
+ // Compilation-level dependencies schedule a pass but do
258
+ // not invalidate Rspack's cached transformed modules.
259
+ if (input.evidence?.missing === true)
260
+ native.loaderContext.addMissingDependency(input.file);
261
+ else
262
+ native.loaderContext.addDependency(input.file);
263
+ }
264
+ else if (native?.framework === "farm") {
265
+ native.context.addWatchFile(file, input.file);
266
+ }
267
+ else {
268
+ this.addWatchFile(input.file);
269
+ }
270
+ }
300
271
  }
301
- }
302
- // A dev server configured without a watcher can never deliver a
303
- // change event, so a registration here buys nothing, and it is not
304
- // free: Vite's import analysis resolves every registered path like a
305
- // real import of the transformed module, once per module. The
306
- // adapter's own missing-input poll above stays active either way,
307
- // because it never depended on Vite's watcher.
308
- if (viteCommand === "serve" && !viteWatching) {
309
- return;
310
- }
311
- this.addWatchFile(watched);
312
- },
272
+ },
313
273
  // A module the plugin declared volatile depends on non-file inputs,
314
274
  // which no file-dependency snapshot can represent; mark it
315
275
  // uncacheable where the bundler exposes that control.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -425,10 +425,12 @@ export interface TtscTransformHooks {
425
425
  addWatchFile?: (file: string, evidence?: TtscWatchInputEvidence) => void;
426
426
  /**
427
427
  * Batched form of {@link addWatchFile}. When supplied, the transform calls it
428
- * once per delivered module and does not call `addWatchFile` for that
429
- * module.
428
+ * once per delivered module and does not call `addWatchFile` for that module.
429
+ * `failed` marks a recovery batch: a failed compiler can omit inputs from its
430
+ * previous successful result, so replacing hosts should retain those
431
+ * spellings until the next successful delivery.
430
432
  */
431
- addWatchFiles?: (inputs: readonly TtscWatchInput[]) => void;
433
+ addWatchFiles?: (inputs: readonly TtscWatchInput[], failed?: boolean) => void;
432
434
  /**
433
435
  * Invoked when the plugin declared the transformed file volatile (the
434
436
  * envelope's `volatile` list): its output depends on non-file inputs that no
@@ -425,10 +425,12 @@ export interface TtscTransformHooks {
425
425
  addWatchFile?: (file: string, evidence?: TtscWatchInputEvidence) => void;
426
426
  /**
427
427
  * Batched form of {@link addWatchFile}. When supplied, the transform calls it
428
- * once per delivered module and does not call `addWatchFile` for that
429
- * module.
428
+ * once per delivered module and does not call `addWatchFile` for that module.
429
+ * `failed` marks a recovery batch: a failed compiler can omit inputs from its
430
+ * previous successful result, so replacing hosts should retain those
431
+ * spellings until the next successful delivery.
430
432
  */
431
- addWatchFiles?: (inputs: readonly TtscWatchInput[]) => void;
433
+ addWatchFiles?: (inputs: readonly TtscWatchInput[], failed?: boolean) => void;
432
434
  /**
433
435
  * Invoked when the plugin declared the transformed file volatile (the
434
436
  * envelope's `volatile` list): its output depends on non-file inputs that no
@@ -425,10 +425,12 @@ export interface TtscTransformHooks {
425
425
  addWatchFile?: (file: string, evidence?: TtscWatchInputEvidence) => void;
426
426
  /**
427
427
  * Batched form of {@link addWatchFile}. When supplied, the transform calls it
428
- * once per delivered module and does not call `addWatchFile` for that
429
- * module.
428
+ * once per delivered module and does not call `addWatchFile` for that module.
429
+ * `failed` marks a recovery batch: a failed compiler can omit inputs from its
430
+ * previous successful result, so replacing hosts should retain those
431
+ * spellings until the next successful delivery.
430
432
  */
431
- addWatchFiles?: (inputs: readonly TtscWatchInput[]) => void;
433
+ addWatchFiles?: (inputs: readonly TtscWatchInput[], failed?: boolean) => void;
432
434
  /**
433
435
  * Invoked when the plugin declared the transformed file volatile (the
434
436
  * envelope's `volatile` list): its output depends on non-file inputs that no
@@ -65,14 +65,13 @@ class TtscUnstableGenerationError extends TtscTerminalGenerationError {
65
65
  /**
66
66
  * A compile this pass already attempted, whose envelope failed outright.
67
67
  *
68
- * The envelope cannot say whether the host reported diagnostics about the
69
- * project or failed to run at all: an ordinary type error arrives as an
70
- * `"exception"` carrying the compiler's own diagnostic text, exactly as a
71
- * crashed host would. Sniffing that message to tell the two apart would be a
72
- * guess, so the adapter uses the one boundary it genuinely owns. Inside a pass
73
- * the answer is already settled, so every later module replays it instead of
74
- * repeating a whole-project transform to reach the same verdict, which is what
75
- * made a single broken save cost one compile per delivered module
68
+ * Native project diagnostics carry a structured failure envelope; setup and
69
+ * host failures can still arrive as opaque exceptions. Both settle the current
70
+ * attempt, so the adapter uses the delivery boundary it owns rather than
71
+ * guessing retryability from a diagnostic message. Inside a pass the answer is
72
+ * already settled, so every later module replays it instead of repeating a
73
+ * whole-project transform to reach the same verdict, which is what made a
74
+ * single broken save cost one compile per delivered module
76
75
  * (samchon/ttsc#1303).
77
76
  *
78
77
  * The scope is exactly the pass. A host whose `buildStart` repeats drops the
@@ -1051,11 +1050,11 @@ function collectDeclaredIdentities(state, projectRoot, listed) {
1051
1050
  * invalidated, and the error stays on screen (samchon/ttsc#1312).
1052
1051
  *
1053
1052
  * A failure envelope can retain exact external input spellings from its graph
1054
- * and host metadata. A pre-transform typecheck failure may have no graph yet;
1055
- * its structured diagnostics, or the host's standard diagnostic lines when it
1056
- * could return only an exception, still name the external files that need a
1057
- * repair. The cost is paid only on a failure, and only until the next compile
1058
- * succeeds and narrows the set back to the derived inputs.
1053
+ * and host metadata, including missing resolution candidates on native
1054
+ * typecheck failures. For hosts that return no graph, structured diagnostics or
1055
+ * standard diagnostic lines provide only the paths they actually name. The cost
1056
+ * is paid only on a failure, and only until the next compile succeeds and
1057
+ * narrows the set back to the derived inputs.
1059
1058
  */
1060
1059
  function notifyFailedGenerationInputs(hooks, cached) {
1061
1060
  const addWatchFile = hooks?.addWatchFile;
@@ -1100,7 +1099,7 @@ function notifyFailedGenerationInputs(hooks, cached) {
1100
1099
  }
1101
1100
  }
1102
1101
  if (addWatchFiles !== undefined) {
1103
- addWatchFiles(inputs);
1102
+ addWatchFiles(inputs, true);
1104
1103
  return;
1105
1104
  }
1106
1105
  for (const input of inputs) {
@@ -3408,7 +3407,9 @@ membership) {
3408
3407
  });
3409
3408
  broker.pendingRegistrations += 1;
3410
3409
  broker.child.ref();
3411
- broker.child.channel?.ref();
3410
+ // Bun's IPC channel omits Node's Control.ref/unref methods. The child itself
3411
+ // still owns the outstanding acknowledgement on that runtime.
3412
+ broker.child.channel?.ref?.();
3412
3413
  const id = broker.nextId++;
3413
3414
  let resolveReady;
3414
3415
  const ready = new Promise((resolve) => {
@@ -3479,7 +3480,7 @@ membership) {
3479
3480
  // exit mid-build.
3480
3481
  if (broker.pendingRegistrations === 0 && broker.pendingDrains === 0) {
3481
3482
  broker.child.unref();
3482
- broker.child.channel?.unref();
3483
+ broker.child.channel?.unref?.();
3483
3484
  }
3484
3485
  }
3485
3486
  }
@@ -3595,7 +3596,7 @@ function startWindowsProjectMutationDrain(broker) {
3595
3596
  broker.pendingDrains -= 1;
3596
3597
  if (broker.pendingDrains === 0 && broker.pendingRegistrations === 0) {
3597
3598
  broker.child.unref();
3598
- broker.child.channel?.unref();
3599
+ broker.child.channel?.unref?.();
3599
3600
  }
3600
3601
  resolve();
3601
3602
  };
@@ -3606,7 +3607,7 @@ function startWindowsProjectMutationDrain(broker) {
3606
3607
  // process exits mid-build with nothing to report.
3607
3608
  broker.pendingDrains += 1;
3608
3609
  broker.child.ref();
3609
- broker.child.channel?.ref();
3610
+ broker.child.channel?.ref?.();
3610
3611
  const timer = setTimeout(release, WINDOWS_MUTATION_DRAIN_FALLBACK_MS);
3611
3612
  broker.drains.set(id, release);
3612
3613
  if (broker.child.send?.({ id, op: "drain" }) !== true) {
@@ -5699,13 +5700,12 @@ function formatUnknownError(error) {
5699
5700
  /**
5700
5701
  * Remove terminal colour and cursor sequences from text the adapter surfaces.
5701
5702
  *
5702
- * An ordinary type error reaches the adapter as an `"exception"` envelope whose
5703
- * `error` is the host's own rendered output, colour and all, and the envelope
5704
- * carries no structured diagnostics to format instead. What the adapter hands
5705
- * back is not going to a terminal: it becomes the `Error` a bundler reports, so
5706
- * it lands in a Vite overlay, a webpack error report or a CI annotation, where
5707
- * the escapes render as literal noise around the file and line the reader needs
5708
- * (samchon/ttsc#1312).
5703
+ * An opaque host exception can contain the host's own rendered output, colour
5704
+ * and all, with no structured diagnostics to format instead. What the adapter
5705
+ * hands back is not going to a terminal: it becomes the `Error` a bundler
5706
+ * reports, so it lands in a Vite overlay, a webpack error report or a CI
5707
+ * annotation, where the escapes render as literal noise around the file and
5708
+ * line the reader needs (samchon/ttsc#1312).
5709
5709
  *
5710
5710
  * The colour originates in the host's rendering rather than in anything this
5711
5711
  * adapter configures, so this is the adapter-side repair, applied to every