@ttsc/unplugin 0.28.5 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -11
- package/lib/api.js +10 -0
- package/lib/api.js.map +1 -1
- package/lib/api.mjs +3 -2
- package/lib/api.mjs.map +1 -1
- package/lib/bun-register.d.cts +10 -7
- package/lib/bun-register.d.mts +10 -7
- package/lib/bun-register.d.ts +10 -7
- package/lib/bun-register.js +90 -24
- package/lib/bun-register.js.map +1 -1
- package/lib/bun-register.mjs +90 -24
- package/lib/bun-register.mjs.map +1 -1
- package/lib/bun.d.cts +10 -8
- package/lib/bun.d.mts +10 -8
- package/lib/bun.d.ts +10 -8
- package/lib/bun.js +19 -17
- package/lib/bun.js.map +1 -1
- package/lib/bun.mjs +20 -18
- package/lib/bun.mjs.map +1 -1
- package/lib/core/index.d.cts +10 -8
- package/lib/core/index.d.mts +10 -8
- package/lib/core/index.d.ts +10 -8
- package/lib/core/index.js +88 -16
- package/lib/core/index.js.map +1 -1
- package/lib/core/index.mjs +81 -18
- package/lib/core/index.mjs.map +1 -1
- package/lib/core/projectDiscovery.d.cts +55 -0
- package/lib/core/projectDiscovery.d.mts +55 -0
- package/lib/core/projectDiscovery.d.ts +55 -0
- package/lib/core/projectDiscovery.js +187 -0
- package/lib/core/projectDiscovery.js.map +1 -0
- package/lib/core/projectDiscovery.mjs +182 -0
- package/lib/core/projectDiscovery.mjs.map +1 -0
- package/lib/core/sourceExtensions.d.cts +10 -0
- package/lib/core/sourceExtensions.d.mts +10 -0
- package/lib/core/sourceExtensions.d.ts +10 -0
- package/lib/core/sourceExtensions.js +38 -0
- package/lib/core/sourceExtensions.js.map +1 -0
- package/lib/core/sourceExtensions.mjs +32 -0
- package/lib/core/sourceExtensions.mjs.map +1 -0
- package/lib/core/transform.d.cts +96 -16
- package/lib/core/transform.d.mts +96 -16
- package/lib/core/transform.d.ts +96 -16
- package/lib/core/transform.js +1295 -309
- package/lib/core/transform.js.map +1 -1
- package/lib/core/transform.mjs +1290 -310
- package/lib/core/transform.mjs.map +1 -1
- package/lib/core/tsconfigPaths.d.cts +55 -3
- package/lib/core/tsconfigPaths.d.mts +55 -3
- package/lib/core/tsconfigPaths.d.ts +55 -3
- package/lib/core/tsconfigPaths.js +260 -46
- package/lib/core/tsconfigPaths.js.map +1 -1
- package/lib/core/tsconfigPaths.mjs +255 -47
- package/lib/core/tsconfigPaths.mjs.map +1 -1
- package/lib/core/viteServe.d.cts +18 -21
- package/lib/core/viteServe.d.mts +18 -21
- package/lib/core/viteServe.d.ts +18 -21
- package/lib/core/viteServe.js +88 -47
- package/lib/core/viteServe.js.map +1 -1
- package/lib/core/viteServe.mjs +89 -49
- package/lib/core/viteServe.mjs.map +1 -1
- package/lib/next.d.cts +7 -0
- package/lib/next.d.mts +7 -0
- package/lib/next.d.ts +7 -0
- package/lib/next.js +186 -54
- package/lib/next.js.map +1 -1
- package/lib/next.mjs +186 -55
- package/lib/next.mjs.map +1 -1
- package/lib/turbopack.d.cts +6 -4
- package/lib/turbopack.d.mts +6 -4
- package/lib/turbopack.d.ts +6 -4
- package/lib/turbopack.js +11 -10
- package/lib/turbopack.js.map +1 -1
- package/lib/turbopack.mjs +11 -10
- package/lib/turbopack.mjs.map +1 -1
- package/package.json +7 -4
- package/src/bun-register.ts +112 -25
- package/src/bun.ts +60 -50
- package/src/core/index.ts +114 -19
- package/src/core/projectDiscovery.ts +256 -0
- package/src/core/sourceExtensions.ts +47 -0
- package/src/core/transform.ts +1671 -361
- package/src/core/tsconfigPaths.ts +406 -46
- package/src/core/viteServe.ts +125 -74
- package/src/next.ts +230 -54
- package/src/turbopack.ts +11 -10
package/README.md
CHANGED
|
@@ -120,7 +120,7 @@ export default withTtsc(nextConfig);
|
|
|
120
120
|
|
|
121
121
|
`withTtsc` covers both of Next.js's bundlers. It injects the webpack plugin and wires the Turbopack loader rules, with the options you pass reaching both, so the same config works whether Next runs on Turbopack (the default in current majors) or on webpack. Your own `webpack` hook and `turbopack` block are preserved: unrelated rules and settings survive, and a rule you already wired for this loader by hand is left alone rather than registered twice.
|
|
122
122
|
|
|
123
|
-
That last part is decided by exact spelling. `withTtsc` declines to add its own rule when your glob is one it has measured against a real Turbopack build as naming every file with the extension
|
|
123
|
+
That last part is decided by exact spelling. `withTtsc` declines to add its own rule when your glob is one it has measured against a real Turbopack build as naming every file with the extension: `*.ext`, `**/*.ext`, and `{**/,}*.ext` for each of `ts`, `tsx`, `mts`, and `cts`; plus the `*.{...}`, `{*.ext,...}`, `**/*.{...}`, `**/{*.ext,...}`, and `**/**/*.{...}` forms for every canonical combination of two or more extensions chosen from that same list. Any other spelling keeps your rule and gains ours beside it, so a module may be transformed twice rather than not at all. The list is exact on purpose: treating an unmeasured glob as project-wide once left every module in a project with no `ttsc` rule at all, and a build that transforms twice is recoverable in a way a build that never transforms is not.
|
|
124
124
|
|
|
125
125
|
### Turbopack
|
|
126
126
|
|
|
@@ -134,6 +134,8 @@ const nextConfig = {
|
|
|
134
134
|
rules: {
|
|
135
135
|
"*.ts": { loaders: ["@ttsc/unplugin/turbopack"] },
|
|
136
136
|
"*.tsx": { loaders: ["@ttsc/unplugin/turbopack"] },
|
|
137
|
+
"*.mts": { loaders: ["@ttsc/unplugin/turbopack"] },
|
|
138
|
+
"*.cts": { loaders: ["@ttsc/unplugin/turbopack"] },
|
|
137
139
|
},
|
|
138
140
|
},
|
|
139
141
|
};
|
|
@@ -181,9 +183,9 @@ import register from "@ttsc/unplugin/bun-register";
|
|
|
181
183
|
register({ project: "tsconfig.build.json" });
|
|
182
184
|
```
|
|
183
185
|
|
|
184
|
-
Importing the module registers it, so a bare `import "@ttsc/unplugin/bun-register"` is enough when the defaults are right.
|
|
186
|
+
Importing the module registers it, so a bare `import "@ttsc/unplugin/bun-register"` is enough when the defaults are right. CommonJS and ESM loads in the same Bun process share that one registration. Calls made before the first transformable TypeScript load use last-call-wins and capture their options by value, which lets an immediate explicit call replace the preload defaults without installing a second loader. Entering the first such load locks the options synchronously for the module-loading session. A later call with the same structural value is idempotent, while a different value throws and requires restarting the Bun process.
|
|
185
187
|
|
|
186
|
-
Under `Bun.build`, the adapter yields to the next loader for declarations, `node_modules`, source that `ttsc` leaves unchanged, and entries supplied through `Bun.build({ files })`. In-memory entries remain with Bun because ttsc transforms filesystem-backed project inputs. Bun's runtime `onLoad` contract does not accept an undefined result, so `Bun.plugin()` explicitly passes excluded and unchanged filesystem files through with their original source. `Bun.build`
|
|
188
|
+
Under `Bun.build`, the adapter yields to the next loader for declarations, `node_modules`, source that `ttsc` leaves unchanged, and entries supplied through `Bun.build({ files })`. In-memory entries remain with Bun because ttsc transforms filesystem-backed project inputs. Bun's runtime `onLoad` contract does not accept an undefined result, so `Bun.plugin()` explicitly passes excluded and unchanged filesystem files through with their original source. Each `Bun.build` opens a delivery pass through `onStart`, then `onEnd` disposes the completed project generation and its filesystem trackers. The runtime API has neither lifecycle hook, so one setup is treated as one immutable module-loading session: restart the Bun process after changing source, tsconfig, or plugin inputs.
|
|
187
189
|
|
|
188
190
|
## Configuration
|
|
189
191
|
|
|
@@ -308,7 +310,7 @@ Each entrypoint supports ESM import and CJS require. In CommonJS configs, read t
|
|
|
308
310
|
|
|
309
311
|
`@ttsc/unplugin/bun-register` is the Bun **runtime** entry rather than a bundler adapter, covered under [Bun](#bun) above. `@ttsc/unplugin/api` exposes the transform core itself (`transformTtsc`, `resolveOptions`, the cache lifecycle) for hosts that are not unplugin-shaped; `@ttsc/metro` is built on it.
|
|
310
312
|
|
|
311
|
-
That entry point also exposes the project-membership rule
|
|
313
|
+
That entry point also exposes the project-membership rule (`readProjectMembershipPolicy`, `mergeMembershipPolicyOverlay`, `ITtscProjectMembershipPolicy`, `isProjectWalkPath`, and the input-hash collectors), which decides which files can enter the compiled program and therefore which changes invalidate a cached compile. These exist so a host that keeps its own cache asks that question exactly the way the transform core asks it: `@ttsc/metro` folds them into Metro's static transformer key, and the two halves disagreeing about one project is the bug class they exist to prevent. They are shaped for that use rather than as a general-purpose configuration reader, and they move with the core rather than under a stability guarantee of their own. Build a host on them if you need it; pin your `@ttsc/unplugin` version if you do.
|
|
312
314
|
|
|
313
315
|
### Options
|
|
314
316
|
|
|
@@ -337,16 +339,16 @@ Not every Vite alias form can be forwarded, because a tsconfig `paths` map canno
|
|
|
337
339
|
| `resolve.alias` form | Forwarded |
|
|
338
340
|
| --- | --- |
|
|
339
341
|
| `{ "@": "/src" }`, or the array form with a string `find` | yes |
|
|
340
|
-
| array form with a `RegExp` `find`, such as `{ find: /^~/ }` | no
|
|
341
|
-
| a string `find` containing `*` | no
|
|
342
|
+
| array form with a `RegExp` `find`, such as `{ find: /^~/ }` | no: `paths` has no regular-expression form |
|
|
343
|
+
| a string `find` containing `*` | no: a `paths` key already reads `*` as its own wildcard |
|
|
342
344
|
|
|
343
|
-
In both unforwarded cases the compile resolves that specifier through the tsconfig's `paths` alone, so declare it there if `ttsc` must resolve through it
|
|
345
|
+
In both unforwarded cases the compile resolves that specifier through the tsconfig's `paths` alone, so declare it there if `ttsc` must resolve through it. A prefix `RegExp` such as `/^~/` is written as a `"~/*"` entry. Reducing simple prefix patterns automatically is deliberately not attempted: distinguishing `/^~/` from `/^@app/`, which also matches `@apple`, needs enough of a regular-expression engine that a wrong reduction becomes likely, and a mistranslated alias resolves imports to the wrong file without saying so.
|
|
344
346
|
|
|
345
347
|
A `find` containing `*` is also reported once on stderr, naming the alias and the reason. A `RegExp` `find` is not, and the asymmetry is deliberate: Vite merges two `RegExp` aliases of its own into every resolved config, for `@vite/env` and `@vite/client`, so a report on that form would fire in every build of every project and name aliases you never wrote.
|
|
346
348
|
|
|
347
349
|
### Cache and Watch Invalidation
|
|
348
350
|
|
|
349
|
-
Editing a type that only a generated validator depends on invalidates the module, in watch mode, in webpack's filesystem cache and in Turbopack's `fileDependencies`, even though the bundler erased the type-only import from its own graph. The adapter registers each transformed file's reference closure, the global-scope files, the configs and the
|
|
351
|
+
Editing a type that only a generated validator depends on invalidates the module, in watch mode, in webpack's filesystem cache and in Turbopack's `fileDependencies`, even though the bundler erased the type-only import from its own graph. The adapter registers each transformed file's reference closure, the global-scope files, the configs, the importer resolution inputs and the universal automatic-type inputs with the bundler, plus whatever the plugins themselves report. The [setup guide](https://ttsc.dev/docs/setup/unplugin) describes how that set is derived and proven.
|
|
350
352
|
|
|
351
353
|
One whole-project compile already contains every module's output, so the adapter compiles the project once and serves every module from that one result. Everything below is about when it may keep doing that.
|
|
352
354
|
|
|
@@ -354,14 +356,16 @@ One whole-project compile already contains every module's output, so the adapter
|
|
|
354
356
|
|
|
355
357
|
A host with a build boundary opens a delivery pass there. The pass's first delivery proves the whole generation against the current filesystem once, and after that each module's first delivery in the pass is settled by the supplied source alone. `buildStart` repeats per rebuild under webpack, Rspack, Rollup, Rolldown, esbuild and `vite build --watch`, so a pass boundary means "each module is requested at most once from here", not "the compiled program is stale".
|
|
356
358
|
|
|
357
|
-
Hosts with no build boundary (Metro workers, the Turbopack loader, and a watching Vite dev server, whose one `buildStart` spans later HMR edits) validate each generation hit against the inputs that can affect the module being asked for: its reference closure, the global-scope files, the configs,
|
|
359
|
+
Hosts with no build boundary (Metro workers, the Turbopack loader, and a watching Vite dev server, whose one `buildStart` spans later HMR edits) validate each generation hit against the inputs that can affect the module being asked for: its reference closure, the global-scope files, the configs, importer resolution inputs, universal automatic-type inputs, and plugin dependencies. Sibling modules share one proof of the closure rather than repeating it per module.
|
|
358
360
|
|
|
359
|
-
Project membership comes from the resolved configuration rather than from a list of directory names. `allowJs` and `resolveJsonModule` decide which file extensions can enter the program, so a bundle emitted beside your sources is not a membership change for a project that compiles no JavaScript. `outDir
|
|
361
|
+
Project membership comes from the resolved configuration rather than from a list of directory names. `allowJs` and `resolveJsonModule` decide which file extensions can enter the program, so a bundle emitted beside your sources is not a membership change for a project that compiles no JavaScript. When no top-level `exclude` is declared, TypeScript uses `outDir` and `declarationDir` as implicit directory exclusions; an explicit `exclude`, including an empty array, replaces those defaults with its own entries. An adapter's `compilerOptions` replace or clear inherited `outDir` and `declarationDir` values before membership is derived, and `${configDir}` paths follow TypeScript's config-relative substitution. Everywhere else, a directory takes part in membership only while it can hold a program input, so an output directory no configuration names still costs nothing as long as what it holds is not admissible, and the first source appearing in it is detected because the directory is walked and watched throughout. A project that does admit JavaScript should name its bundler's output directory in `exclude`, since otherwise an emitted `.js` there is a program input like any other. Emptying and recreating a directory the effective exclusions name, which `emptyOutDir` and `output.clean` do on every build, costs nothing either.
|
|
360
362
|
|
|
361
363
|
#### When it is discarded
|
|
362
364
|
|
|
363
365
|
An input change or an explicit cache lifecycle reset permits a new generation. Opening a pass is not such a reset.
|
|
364
366
|
|
|
367
|
+
Closing a webpack or Rspack compiler disposes its generation at the compiler's shutdown hook. esbuild disposes after a one-shot build or after the last overlapping build context closes; an older delayed disposal cannot clear a replacement build that has already reached `onStart`. These terminal boundaries release generation-owned filesystem trackers without discarding the generation on each rebuild.
|
|
368
|
+
|
|
365
369
|
A compile that failed outright is retained for the rest of that pass, so its remaining modules replay the verdict instead of repeating an identical failing compile once per module, and the next pass attempts it again. A host with no pass boundary keeps evicting a failed compile on every delivery, so a transient toolchain failure never becomes permanent for a long-lived worker.
|
|
366
370
|
|
|
367
371
|
#### What this changes for you
|
|
@@ -374,7 +378,7 @@ A Bun runtime plugin registration is one process-scoped module-loading session,
|
|
|
374
378
|
|
|
375
379
|
A dev server started without a watcher (`server.watch: null`, which is what `vitest --run` configures) takes the pass lifecycle instead of per-delivery validation. Nothing can deliver a change event to such a session, so per-delivery validation there buys incoherence rather than freshness: modules delivered before an edit and after it would come from two different compilations of one program.
|
|
376
380
|
|
|
377
|
-
Freshness proofs rest on filesystem
|
|
381
|
+
Freshness proofs rest on filesystem observations, so two environments need care. A project on a network mount that accepts a watch and then reports nothing should be treated as one where notifications do not work. For metadata reuse, the adapter rewrites its own retained probe before validation and accepts only older stamps on the same reporting device. A clock rollback cannot strand historical proof because the previous reference is discarded before that write, and an unavailable or cross-volume probe keeps the byte comparison instead. A constant offset from the process clock is irrelevant because the process clock is never compared.
|
|
378
382
|
|
|
379
383
|
The [setup guide](https://ttsc.dev/docs/setup/unplugin) describes how these proofs are built.
|
|
380
384
|
|
package/lib/api.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./core/index.js');
|
|
4
4
|
var transform = require('./core/transform.js');
|
|
5
|
+
var projectDiscovery = require('./core/projectDiscovery.js');
|
|
5
6
|
var tsconfigPaths = require('./core/tsconfigPaths.js');
|
|
6
7
|
var options = require('./core/options.js');
|
|
7
8
|
|
|
@@ -11,13 +12,22 @@ exports.isTransformTarget = index.isTransformTarget;
|
|
|
11
12
|
exports.sourceFilePattern = index.sourceFilePattern;
|
|
12
13
|
exports.unplugin = index.default;
|
|
13
14
|
exports.beginTtscTransformBuild = transform.beginTtscTransformBuild;
|
|
15
|
+
exports.captureWatchInputBaseline = transform.captureWatchInputBaseline;
|
|
16
|
+
exports.captureWatchInputFileBaseline = transform.captureWatchInputFileBaseline;
|
|
14
17
|
exports.collectExternalInputHashes = transform.collectExternalInputHashes;
|
|
18
|
+
exports.collectProjectInputHashSnapshot = transform.collectProjectInputHashSnapshot;
|
|
15
19
|
exports.collectProjectInputHashes = transform.collectProjectInputHashes;
|
|
16
20
|
exports.createTtscTransformCache = transform.createTtscTransformCache;
|
|
17
21
|
exports.isProjectWalkPath = transform.isProjectWalkPath;
|
|
22
|
+
exports.isWatchInputKeyBaseline = transform.isWatchInputKeyBaseline;
|
|
18
23
|
exports.resetTtscTransformCache = transform.resetTtscTransformCache;
|
|
19
24
|
exports.transformTtsc = transform.transformTtsc;
|
|
25
|
+
exports.watchInputEvidenceMatchesBaseline = transform.watchInputEvidenceMatchesBaseline;
|
|
26
|
+
exports.discoverNearestProjectTsconfig = projectDiscovery.discoverNearestProjectTsconfig;
|
|
27
|
+
exports.findNearestProjectTsconfig = projectDiscovery.findNearestProjectTsconfig;
|
|
28
|
+
exports.findProjectTsconfigs = projectDiscovery.findProjectTsconfigs;
|
|
20
29
|
exports.mergeMembershipPolicyOverlay = tsconfigPaths.mergeMembershipPolicyOverlay;
|
|
21
30
|
exports.readProjectMembershipPolicy = tsconfigPaths.readProjectMembershipPolicy;
|
|
31
|
+
exports.readTsconfigSourceSnapshot = tsconfigPaths.readTsconfigSourceSnapshot;
|
|
22
32
|
exports.resolveOptions = options.resolveOptions;
|
|
23
33
|
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/api.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { isTransformTarget, sourceFilePattern, default as unplugin } from './core/index.mjs';
|
|
2
|
-
export { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, transformTtsc } from './core/transform.mjs';
|
|
3
|
-
export {
|
|
2
|
+
export { beginTtscTransformBuild, captureWatchInputBaseline, captureWatchInputFileBaseline, collectExternalInputHashes, collectProjectInputHashSnapshot, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, isWatchInputKeyBaseline, resetTtscTransformCache, transformTtsc, watchInputEvidenceMatchesBaseline } from './core/transform.mjs';
|
|
3
|
+
export { discoverNearestProjectTsconfig, findNearestProjectTsconfig, findProjectTsconfigs } from './core/projectDiscovery.mjs';
|
|
4
|
+
export { mergeMembershipPolicyOverlay, readProjectMembershipPolicy, readTsconfigSourceSnapshot } from './core/tsconfigPaths.mjs';
|
|
4
5
|
export { resolveOptions } from './core/options.mjs';
|
|
5
6
|
//# sourceMappingURL=api.mjs.map
|
package/lib/api.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
package/lib/bun-register.d.cts
CHANGED
|
@@ -11,14 +11,17 @@ import type { TtscUnpluginOptions } from "./core/options.cjs";
|
|
|
11
11
|
* "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
12
12
|
* `tsconfig.json`, identical to the bundler adapters.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* The first call registers one loader. Calls before its first transformable
|
|
15
|
+
* TypeScript load use last-call-wins and capture options by value, so an
|
|
16
|
+
* explicit call right after importing this module replaces the preload defaults
|
|
17
|
+
* without installing a shadowing loader. Entering the first such load locks
|
|
18
|
+
* that snapshot synchronously. Later calls with a structurally identical value
|
|
19
|
+
* are idempotent; a different value throws rather than pretending a resolved
|
|
20
|
+
* loader changed configuration.
|
|
19
21
|
*
|
|
20
|
-
* @throws When called explicitly off the Bun runtime
|
|
21
|
-
*
|
|
22
|
+
* @throws When called explicitly off the Bun runtime, when options are not
|
|
23
|
+
* structured-cloneable, or when a different option value is supplied after
|
|
24
|
+
* the first load. The auto-registration below stays silent off Bun so the
|
|
22
25
|
* module is harmless to import from Node (tests, tooling).
|
|
23
26
|
*/
|
|
24
27
|
export declare function register(options?: TtscUnpluginOptions): void;
|
package/lib/bun-register.d.mts
CHANGED
|
@@ -11,14 +11,17 @@ import type { TtscUnpluginOptions } from "./core/options.mjs";
|
|
|
11
11
|
* "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
12
12
|
* `tsconfig.json`, identical to the bundler adapters.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* The first call registers one loader. Calls before its first transformable
|
|
15
|
+
* TypeScript load use last-call-wins and capture options by value, so an
|
|
16
|
+
* explicit call right after importing this module replaces the preload defaults
|
|
17
|
+
* without installing a shadowing loader. Entering the first such load locks
|
|
18
|
+
* that snapshot synchronously. Later calls with a structurally identical value
|
|
19
|
+
* are idempotent; a different value throws rather than pretending a resolved
|
|
20
|
+
* loader changed configuration.
|
|
19
21
|
*
|
|
20
|
-
* @throws When called explicitly off the Bun runtime
|
|
21
|
-
*
|
|
22
|
+
* @throws When called explicitly off the Bun runtime, when options are not
|
|
23
|
+
* structured-cloneable, or when a different option value is supplied after
|
|
24
|
+
* the first load. The auto-registration below stays silent off Bun so the
|
|
22
25
|
* module is harmless to import from Node (tests, tooling).
|
|
23
26
|
*/
|
|
24
27
|
export declare function register(options?: TtscUnpluginOptions): void;
|
package/lib/bun-register.d.ts
CHANGED
|
@@ -11,14 +11,17 @@ import type { TtscUnpluginOptions } from "./core/options";
|
|
|
11
11
|
* "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
12
12
|
* `tsconfig.json`, identical to the bundler adapters.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* The first call registers one loader. Calls before its first transformable
|
|
15
|
+
* TypeScript load use last-call-wins and capture options by value, so an
|
|
16
|
+
* explicit call right after importing this module replaces the preload defaults
|
|
17
|
+
* without installing a shadowing loader. Entering the first such load locks
|
|
18
|
+
* that snapshot synchronously. Later calls with a structurally identical value
|
|
19
|
+
* are idempotent; a different value throws rather than pretending a resolved
|
|
20
|
+
* loader changed configuration.
|
|
19
21
|
*
|
|
20
|
-
* @throws When called explicitly off the Bun runtime
|
|
21
|
-
*
|
|
22
|
+
* @throws When called explicitly off the Bun runtime, when options are not
|
|
23
|
+
* structured-cloneable, or when a different option value is supplied after
|
|
24
|
+
* the first load. The auto-registration below stays silent off Bun so the
|
|
22
25
|
* module is harmless to import from Node (tests, tooling).
|
|
23
26
|
*/
|
|
24
27
|
export declare function register(options?: TtscUnpluginOptions): void;
|
package/lib/bun-register.js
CHANGED
|
@@ -2,22 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var node_util = require('node:util');
|
|
5
6
|
var bun = require('./bun.js');
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Pending and locked options for the single runtime loader.
|
|
9
10
|
*
|
|
10
11
|
* Bun uses the first matching `onLoad` hook and does not fall through to a
|
|
11
12
|
* later overlapping plugin (oven-sh/bun#20583). Registering twice — once
|
|
12
13
|
* implicitly on import, once explicitly — would let the default loader shadow
|
|
13
|
-
* the configured one. Instead exactly one Bun plugin is registered
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* the
|
|
14
|
+
* the configured one. Instead exactly one Bun plugin is registered. Calls made
|
|
15
|
+
* before its first load replace this detached snapshot; entering the first
|
|
16
|
+
* transformable load locks that value synchronously for the process's immutable
|
|
17
|
+
* module-loading session. State is keyed by the Bun runtime in a global weak
|
|
18
|
+
* map so loading both emitted module conditions cannot install two overlapping
|
|
19
|
+
* loaders.
|
|
17
20
|
*/
|
|
18
|
-
|
|
19
|
-
/** Whether the single runtime loader has already been registered with Bun. */
|
|
20
|
-
let registered = false;
|
|
21
|
+
const BUN_REGISTRATION_STATES = Symbol.for("@ttsc/unplugin/bun-register/states/v1");
|
|
21
22
|
/**
|
|
22
23
|
* Register the ttsc transform as a Bun **runtime** plugin.
|
|
23
24
|
*
|
|
@@ -30,14 +31,17 @@ let registered = false;
|
|
|
30
31
|
* "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
31
32
|
* `tsconfig.json`, identical to the bundler adapters.
|
|
32
33
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* The first call registers one loader. Calls before its first transformable
|
|
35
|
+
* TypeScript load use last-call-wins and capture options by value, so an
|
|
36
|
+
* explicit call right after importing this module replaces the preload defaults
|
|
37
|
+
* without installing a shadowing loader. Entering the first such load locks
|
|
38
|
+
* that snapshot synchronously. Later calls with a structurally identical value
|
|
39
|
+
* are idempotent; a different value throws rather than pretending a resolved
|
|
40
|
+
* loader changed configuration.
|
|
38
41
|
*
|
|
39
|
-
* @throws When called explicitly off the Bun runtime
|
|
40
|
-
*
|
|
42
|
+
* @throws When called explicitly off the Bun runtime, when options are not
|
|
43
|
+
* structured-cloneable, or when a different option value is supplied after
|
|
44
|
+
* the first load. The auto-registration below stays silent off Bun so the
|
|
41
45
|
* module is harmless to import from Node (tests, tooling).
|
|
42
46
|
*/
|
|
43
47
|
function register(options) {
|
|
@@ -47,15 +51,50 @@ function register(options) {
|
|
|
47
51
|
"(globalThis.Bun.plugin is unavailable). Use a bundler adapter such as " +
|
|
48
52
|
"@ttsc/unplugin/vite for non-Bun toolchains.");
|
|
49
53
|
}
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
const state = registrationState(runtime);
|
|
55
|
+
const snapshot = snapshotOptions(options);
|
|
56
|
+
if (state.optionsLocked) {
|
|
57
|
+
if (node_util.isDeepStrictEqual(snapshot, state.lockedOptions)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
throw new Error("@ttsc/unplugin/bun-register options are locked because the runtime " +
|
|
61
|
+
"loader has started handling a TypeScript module. Restart the Bun " +
|
|
62
|
+
"process to use different compiler or plugin options.");
|
|
63
|
+
}
|
|
64
|
+
state.activeOptions = snapshot;
|
|
65
|
+
ensureRegistered(runtime, state);
|
|
66
|
+
}
|
|
67
|
+
/** Install the runtime's one loader without changing its pending options. */
|
|
68
|
+
function ensureRegistered(runtime, state) {
|
|
69
|
+
if (state.registered)
|
|
52
70
|
return;
|
|
71
|
+
state.registered = true;
|
|
72
|
+
try {
|
|
73
|
+
runtime.plugin(bun.default(() => lockOptions(state)));
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
state.registered = false;
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Lock and return the detached option snapshot at first load-handler entry. */
|
|
81
|
+
function lockOptions(state) {
|
|
82
|
+
if (!state.optionsLocked) {
|
|
83
|
+
state.lockedOptions = state.activeOptions;
|
|
84
|
+
state.optionsLocked = true;
|
|
85
|
+
}
|
|
86
|
+
return state.lockedOptions;
|
|
87
|
+
}
|
|
88
|
+
/** Detach JSON-shaped options from mutations made after `register` returns. */
|
|
89
|
+
function snapshotOptions(options) {
|
|
90
|
+
if (options === undefined)
|
|
91
|
+
return undefined;
|
|
92
|
+
try {
|
|
93
|
+
return structuredClone(options);
|
|
94
|
+
}
|
|
95
|
+
catch (cause) {
|
|
96
|
+
throw new TypeError("@ttsc/unplugin/bun-register options must contain structured-cloneable values.", { cause });
|
|
53
97
|
}
|
|
54
|
-
registered = true;
|
|
55
|
-
// Register a single loader whose options are read from `activeOptions` on
|
|
56
|
-
// first load, so an explicit call made after the import-time auto-register
|
|
57
|
-
// still wins.
|
|
58
|
-
runtime.plugin(bun.default(() => activeOptions));
|
|
59
98
|
}
|
|
60
99
|
function bunRuntime() {
|
|
61
100
|
const runtime = globalThis.Bun;
|
|
@@ -63,11 +102,38 @@ function bunRuntime() {
|
|
|
63
102
|
? runtime
|
|
64
103
|
: undefined;
|
|
65
104
|
}
|
|
105
|
+
/** Resolve the shared state owned by one concrete Bun runtime object. */
|
|
106
|
+
function registrationState(runtime) {
|
|
107
|
+
const holder = globalThis;
|
|
108
|
+
let states = holder[BUN_REGISTRATION_STATES];
|
|
109
|
+
if (!(states instanceof WeakMap)) {
|
|
110
|
+
states = new WeakMap();
|
|
111
|
+
Object.defineProperty(holder, BUN_REGISTRATION_STATES, {
|
|
112
|
+
configurable: false,
|
|
113
|
+
enumerable: false,
|
|
114
|
+
value: states,
|
|
115
|
+
writable: false,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const registrations = states;
|
|
119
|
+
const existing = registrations.get(runtime);
|
|
120
|
+
if (existing !== undefined)
|
|
121
|
+
return existing;
|
|
122
|
+
const created = {
|
|
123
|
+
activeOptions: undefined,
|
|
124
|
+
lockedOptions: undefined,
|
|
125
|
+
optionsLocked: false,
|
|
126
|
+
registered: false,
|
|
127
|
+
};
|
|
128
|
+
registrations.set(runtime, created);
|
|
129
|
+
return created;
|
|
130
|
+
}
|
|
66
131
|
// Auto-register on import so a `bunfig.toml` `preload` entry — which only
|
|
67
132
|
// imports the module — takes effect. Guarded so importing from Node (a stray
|
|
68
133
|
// import, or a unit test) is a harmless no-op rather than a throw.
|
|
69
|
-
|
|
70
|
-
|
|
134
|
+
const runtime = bunRuntime();
|
|
135
|
+
if (runtime !== undefined) {
|
|
136
|
+
ensureRegistered(runtime, registrationState(runtime));
|
|
71
137
|
}
|
|
72
138
|
|
|
73
139
|
exports.default = register;
|
package/lib/bun-register.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun-register.js","sources":["../src/bun-register.ts"],"sourcesContent":[null],"names":["bun"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bun-register.js","sources":["../src/bun-register.ts"],"sourcesContent":[null],"names":["isDeepStrictEqual","bun"],"mappings":"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"}
|
package/lib/bun-register.mjs
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
1
2
|
import bun from './bun.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* Pending and locked options for the single runtime loader.
|
|
5
6
|
*
|
|
6
7
|
* Bun uses the first matching `onLoad` hook and does not fall through to a
|
|
7
8
|
* later overlapping plugin (oven-sh/bun#20583). Registering twice — once
|
|
8
9
|
* implicitly on import, once explicitly — would let the default loader shadow
|
|
9
|
-
* the configured one. Instead exactly one Bun plugin is registered
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* the
|
|
10
|
+
* the configured one. Instead exactly one Bun plugin is registered. Calls made
|
|
11
|
+
* before its first load replace this detached snapshot; entering the first
|
|
12
|
+
* transformable load locks that value synchronously for the process's immutable
|
|
13
|
+
* module-loading session. State is keyed by the Bun runtime in a global weak
|
|
14
|
+
* map so loading both emitted module conditions cannot install two overlapping
|
|
15
|
+
* loaders.
|
|
13
16
|
*/
|
|
14
|
-
|
|
15
|
-
/** Whether the single runtime loader has already been registered with Bun. */
|
|
16
|
-
let registered = false;
|
|
17
|
+
const BUN_REGISTRATION_STATES = Symbol.for("@ttsc/unplugin/bun-register/states/v1");
|
|
17
18
|
/**
|
|
18
19
|
* Register the ttsc transform as a Bun **runtime** plugin.
|
|
19
20
|
*
|
|
@@ -26,14 +27,17 @@ let registered = false;
|
|
|
26
27
|
* "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
27
28
|
* `tsconfig.json`, identical to the bundler adapters.
|
|
28
29
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
30
|
+
* The first call registers one loader. Calls before its first transformable
|
|
31
|
+
* TypeScript load use last-call-wins and capture options by value, so an
|
|
32
|
+
* explicit call right after importing this module replaces the preload defaults
|
|
33
|
+
* without installing a shadowing loader. Entering the first such load locks
|
|
34
|
+
* that snapshot synchronously. Later calls with a structurally identical value
|
|
35
|
+
* are idempotent; a different value throws rather than pretending a resolved
|
|
36
|
+
* loader changed configuration.
|
|
34
37
|
*
|
|
35
|
-
* @throws When called explicitly off the Bun runtime
|
|
36
|
-
*
|
|
38
|
+
* @throws When called explicitly off the Bun runtime, when options are not
|
|
39
|
+
* structured-cloneable, or when a different option value is supplied after
|
|
40
|
+
* the first load. The auto-registration below stays silent off Bun so the
|
|
37
41
|
* module is harmless to import from Node (tests, tooling).
|
|
38
42
|
*/
|
|
39
43
|
function register(options) {
|
|
@@ -43,15 +47,50 @@ function register(options) {
|
|
|
43
47
|
"(globalThis.Bun.plugin is unavailable). Use a bundler adapter such as " +
|
|
44
48
|
"@ttsc/unplugin/vite for non-Bun toolchains.");
|
|
45
49
|
}
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
const state = registrationState(runtime);
|
|
51
|
+
const snapshot = snapshotOptions(options);
|
|
52
|
+
if (state.optionsLocked) {
|
|
53
|
+
if (isDeepStrictEqual(snapshot, state.lockedOptions)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
throw new Error("@ttsc/unplugin/bun-register options are locked because the runtime " +
|
|
57
|
+
"loader has started handling a TypeScript module. Restart the Bun " +
|
|
58
|
+
"process to use different compiler or plugin options.");
|
|
59
|
+
}
|
|
60
|
+
state.activeOptions = snapshot;
|
|
61
|
+
ensureRegistered(runtime, state);
|
|
62
|
+
}
|
|
63
|
+
/** Install the runtime's one loader without changing its pending options. */
|
|
64
|
+
function ensureRegistered(runtime, state) {
|
|
65
|
+
if (state.registered)
|
|
48
66
|
return;
|
|
67
|
+
state.registered = true;
|
|
68
|
+
try {
|
|
69
|
+
runtime.plugin(bun(() => lockOptions(state)));
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
state.registered = false;
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Lock and return the detached option snapshot at first load-handler entry. */
|
|
77
|
+
function lockOptions(state) {
|
|
78
|
+
if (!state.optionsLocked) {
|
|
79
|
+
state.lockedOptions = state.activeOptions;
|
|
80
|
+
state.optionsLocked = true;
|
|
81
|
+
}
|
|
82
|
+
return state.lockedOptions;
|
|
83
|
+
}
|
|
84
|
+
/** Detach JSON-shaped options from mutations made after `register` returns. */
|
|
85
|
+
function snapshotOptions(options) {
|
|
86
|
+
if (options === undefined)
|
|
87
|
+
return undefined;
|
|
88
|
+
try {
|
|
89
|
+
return structuredClone(options);
|
|
90
|
+
}
|
|
91
|
+
catch (cause) {
|
|
92
|
+
throw new TypeError("@ttsc/unplugin/bun-register options must contain structured-cloneable values.", { cause });
|
|
49
93
|
}
|
|
50
|
-
registered = true;
|
|
51
|
-
// Register a single loader whose options are read from `activeOptions` on
|
|
52
|
-
// first load, so an explicit call made after the import-time auto-register
|
|
53
|
-
// still wins.
|
|
54
|
-
runtime.plugin(bun(() => activeOptions));
|
|
55
94
|
}
|
|
56
95
|
function bunRuntime() {
|
|
57
96
|
const runtime = globalThis.Bun;
|
|
@@ -59,11 +98,38 @@ function bunRuntime() {
|
|
|
59
98
|
? runtime
|
|
60
99
|
: undefined;
|
|
61
100
|
}
|
|
101
|
+
/** Resolve the shared state owned by one concrete Bun runtime object. */
|
|
102
|
+
function registrationState(runtime) {
|
|
103
|
+
const holder = globalThis;
|
|
104
|
+
let states = holder[BUN_REGISTRATION_STATES];
|
|
105
|
+
if (!(states instanceof WeakMap)) {
|
|
106
|
+
states = new WeakMap();
|
|
107
|
+
Object.defineProperty(holder, BUN_REGISTRATION_STATES, {
|
|
108
|
+
configurable: false,
|
|
109
|
+
enumerable: false,
|
|
110
|
+
value: states,
|
|
111
|
+
writable: false,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const registrations = states;
|
|
115
|
+
const existing = registrations.get(runtime);
|
|
116
|
+
if (existing !== undefined)
|
|
117
|
+
return existing;
|
|
118
|
+
const created = {
|
|
119
|
+
activeOptions: undefined,
|
|
120
|
+
lockedOptions: undefined,
|
|
121
|
+
optionsLocked: false,
|
|
122
|
+
registered: false,
|
|
123
|
+
};
|
|
124
|
+
registrations.set(runtime, created);
|
|
125
|
+
return created;
|
|
126
|
+
}
|
|
62
127
|
// Auto-register on import so a `bunfig.toml` `preload` entry — which only
|
|
63
128
|
// imports the module — takes effect. Guarded so importing from Node (a stray
|
|
64
129
|
// import, or a unit test) is a harmless no-op rather than a throw.
|
|
65
|
-
|
|
66
|
-
|
|
130
|
+
const runtime = bunRuntime();
|
|
131
|
+
if (runtime !== undefined) {
|
|
132
|
+
ensureRegistered(runtime, registrationState(runtime));
|
|
67
133
|
}
|
|
68
134
|
|
|
69
135
|
export { register as default, register };
|
package/lib/bun-register.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun-register.mjs","sources":["../src/bun-register.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bun-register.mjs","sources":["../src/bun-register.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/lib/bun.d.cts
CHANGED
|
@@ -20,19 +20,19 @@ export type BunLoader = "ts" | "tsx";
|
|
|
20
20
|
*
|
|
21
21
|
* The provider form exists for the runtime registration path (`bun-register`),
|
|
22
22
|
* where a single Bun plugin is registered on import but its effective options
|
|
23
|
-
* may be overridden by
|
|
24
|
-
*
|
|
25
|
-
* at registration, lets
|
|
26
|
-
* shadowing loader.
|
|
23
|
+
* may be overridden by explicit `register(options)` calls made before the first
|
|
24
|
+
* transformable TypeScript load. Resolving through the provider on that first
|
|
25
|
+
* load, rather than at registration, lets the last pending call win without Bun
|
|
26
|
+
* ever seeing a second shadowing loader.
|
|
27
27
|
*/
|
|
28
28
|
export type TtscBunOptions = TtscUnpluginOptions | (() => TtscUnpluginOptions | undefined);
|
|
29
29
|
/**
|
|
30
30
|
* Minimal subset of the Bun `BuildConfig` plugin build object.
|
|
31
31
|
*
|
|
32
|
-
* `onLoad` drives the source transform. Bun's bundler also exposes `onStart
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
32
|
+
* `onLoad` drives the source transform. Bun's bundler also exposes `onStart`
|
|
33
|
+
* and `onEnd`, which bracket the shared plugin's build lifecycle. The runtime
|
|
34
|
+
* plugin API omits those hooks, so plugin setup itself starts its one
|
|
35
|
+
* process-scoped module-loading session.
|
|
36
36
|
*/
|
|
37
37
|
export interface BunLikeBuild {
|
|
38
38
|
/**
|
|
@@ -51,6 +51,8 @@ export interface BunLikeBuild {
|
|
|
51
51
|
* Optional because `Bun.plugin()` runtime builders do not expose this hook.
|
|
52
52
|
*/
|
|
53
53
|
onStart?(callback: () => void | Promise<void>): void;
|
|
54
|
+
/** Register a callback for deterministic bundler-session teardown. */
|
|
55
|
+
onEnd?(callback: () => void | Promise<void>): void;
|
|
54
56
|
/**
|
|
55
57
|
* Register a loader callback for files matching `filter`.
|
|
56
58
|
*
|