@alchemy.run/node-utils 2.0.0-beta.76 → 2.0.0-beta.78

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 (37) hide show
  1. package/THIRD_PARTY_LICENSES.md +11 -11
  2. package/lib/dependency-watcher.d.ts +28 -0
  3. package/lib/dependency-watcher.d.ts.map +1 -0
  4. package/lib/dependency-watcher.js +114 -0
  5. package/lib/dependency-watcher.js.map +1 -0
  6. package/lib/register-oxc.d.ts +61 -0
  7. package/lib/register-oxc.d.ts.map +1 -0
  8. package/lib/register-oxc.js +220 -0
  9. package/lib/register-oxc.js.map +1 -0
  10. package/lib/resolve-specifier.d.ts +46 -0
  11. package/lib/resolve-specifier.d.ts.map +1 -0
  12. package/lib/resolve-specifier.js +123 -0
  13. package/lib/resolve-specifier.js.map +1 -0
  14. package/lib/transform-cache.d.ts +63 -0
  15. package/lib/transform-cache.d.ts.map +1 -0
  16. package/lib/transform-cache.js +193 -0
  17. package/lib/transform-cache.js.map +1 -0
  18. package/lib/transform-source.d.ts +19 -0
  19. package/lib/transform-source.d.ts.map +1 -0
  20. package/lib/transform-source.js +213 -0
  21. package/lib/transform-source.js.map +1 -0
  22. package/lib/watch-import-bun.d.ts +30 -0
  23. package/lib/watch-import-bun.d.ts.map +1 -0
  24. package/lib/watch-import-bun.js +73 -0
  25. package/lib/watch-import-bun.js.map +1 -0
  26. package/lib/watch-import.d.ts +27 -0
  27. package/lib/watch-import.d.ts.map +1 -0
  28. package/lib/watch-import.js +79 -0
  29. package/lib/watch-import.js.map +1 -0
  30. package/package.json +21 -2
  31. package/src/dependency-watcher.ts +130 -0
  32. package/src/register-oxc.ts +337 -0
  33. package/src/resolve-specifier.ts +157 -0
  34. package/src/transform-cache.ts +226 -0
  35. package/src/transform-source.ts +254 -0
  36. package/src/watch-import-bun.ts +99 -0
  37. package/src/watch-import.ts +106 -0
@@ -6,7 +6,7 @@ respective license notices.
6
6
 
7
7
  ## Astro
8
8
 
9
- Portions of `packages/cloudflare-frameworks/src/astro` are derived from
9
+ Portions of `packages/frontend-frameworks/src/astro` are derived from
10
10
  `@astrojs/cloudflare`.
11
11
 
12
12
  Copyright (c) 2021 Fred K. Schott
@@ -33,7 +33,7 @@ SOFTWARE.
33
33
 
34
34
  ## SvelteKit
35
35
 
36
- Portions of `packages/cloudflare-frameworks/src/sveltekit` are derived from
36
+ Portions of `packages/frontend-frameworks/src/sveltekit` are derived from
37
37
  `@sveltejs/adapter-cloudflare`.
38
38
 
39
39
  Copyright (c) 2020 SvelteKit contributors
@@ -43,7 +43,7 @@ Astro section above.
43
43
 
44
44
  ## Waku
45
45
 
46
- Portions of `packages/cloudflare-frameworks/src/waku` are derived from Waku.
46
+ Portions of `packages/frontend-frameworks/src/waku` are derived from Waku.
47
47
 
48
48
  Copyright (c) 2023 Daishi Kato
49
49
 
@@ -65,7 +65,7 @@ License reproduced in the Astro section above.
65
65
 
66
66
  ## OpenNext for Cloudflare
67
67
 
68
- Portions of `packages/cloudflare-frameworks/src/nextjs`, including the build
68
+ Portions of `packages/frontend-frameworks/src/nextjs`, including the build
69
69
  runner and development-context integration, are derived from OpenNext for
70
70
  Cloudflare.
71
71
 
@@ -122,17 +122,17 @@ been dedicated to the public domain. See <https://www.sqlite.org/copyright.html>
122
122
 
123
123
  ## Upstream source references
124
124
 
125
- - Astro: <https://github.com/withastro/astro>
126
- - SvelteKit: <https://github.com/sveltejs/kit>
127
- - Waku: <https://github.com/wakujs/waku>
128
- - Cloudflare Workers SDK: <https://github.com/cloudflare/workers-sdk>
129
- - OpenNext for Cloudflare: <https://github.com/opennextjs/opennextjs-cloudflare>
125
+ - Astro: [`a2240c43830e29c1d85667f4c610655d6b10253f`](https://github.com/withastro/astro/tree/a2240c43830e29c1d85667f4c610655d6b10253f)
126
+ - SvelteKit: [`f36b3a4cd307bd8c89e03fa191becc175e7b3077`](https://github.com/sveltejs/kit/tree/f36b3a4cd307bd8c89e03fa191becc175e7b3077)
127
+ - Waku: [`39e868f2638c27de9635c68ebf965e14a4112e9b`](https://github.com/wakujs/waku/tree/39e868f2638c27de9635c68ebf965e14a4112e9b)
128
+ - Cloudflare Workers SDK: [`b7b4ff84477982e7c770bb93928287893fcf2e03`](https://github.com/cloudflare/workers-sdk/tree/b7b4ff84477982e7c770bb93928287893fcf2e03)
129
+ - OpenNext for Cloudflare: [`da4b7fc8c89441a6f96205635fa70e329d1f0df7`](https://github.com/opennextjs/opennextjs-cloudflare/tree/da4b7fc8c89441a6f96205635fa70e329d1f0df7)
130
130
  - SST: <https://github.com/sst/sst>
131
131
  - node-sanitize-filename: <https://github.com/parshap/node-sanitize-filename>
132
132
  - node-ignore: <https://github.com/kaelzhang/node-ignore>
133
133
  - SQLite: <https://github.com/sqlite/sqlite>
134
134
 
135
- The external `.vendor` Git submodules are separate works governed by the
136
- license files in their respective repositories. This notice covers code copied
135
+ The first-class `submodules/` checkouts (distilled, floci) are separate works
136
+ governed by the license files in their respective repositories. This notice covers code copied
137
137
  or adapted into the Alchemy repository; it does not replace the license
138
138
  documentation within those submodules.
@@ -0,0 +1,28 @@
1
+ import { type ChokidarOptions } from "chokidar";
2
+ export interface DependencyChange {
3
+ readonly paths: ReadonlySet<string>;
4
+ }
5
+ export type DependencyChangeListener = (change: DependencyChange) => void;
6
+ export interface DependencyWatcherOptions {
7
+ /** Chokidar options passed to the file watcher. */
8
+ readonly watch?: ChokidarOptions | undefined;
9
+ readonly debounceMs?: number | undefined;
10
+ }
11
+ /**
12
+ * Watches an explicit set of absolute file paths and delivers debounced
13
+ * batches only when their contents change. Chokidar follows editor atomic-save
14
+ * replacements without polling by default. The set is replaced wholesale
15
+ * with {@link set}, so the watcher always mirrors exactly the files the caller
16
+ * currently depends on.
17
+ */
18
+ export declare class DependencyWatcher {
19
+ #private;
20
+ constructor(options?: DependencyWatcherOptions);
21
+ get dependencies(): ReadonlySet<string>;
22
+ subscribe(listener: DependencyChangeListener): () => void;
23
+ /** Replace the watched set with `dependencies` (absolute paths). */
24
+ set(dependencies: ReadonlySet<string>): void;
25
+ close(): Promise<void>;
26
+ [Symbol.asyncDispose](): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=dependency-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-watcher.d.ts","sourceRoot":"","sources":["../src/dependency-watcher.ts"],"names":[],"mappings":"AAGA,OAAO,EAAS,KAAK,eAAe,EAAkB,MAAM,UAAU,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAE1E,MAAM,WAAW,wBAAwB;IACvC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;;IAU5B,YAAY,OAAO,GAAE,wBAA6B,EAUjD;IAED,IAAI,YAAY,IAAI,WAAW,CAAC,MAAM,CAAC,CAEtC;IAED,SAAS,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI,CAGxD;IAED,oEAAoE;IACpE,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAuB3C;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAM3B;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3C;CAsCF"}
@@ -0,0 +1,114 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { watch } from "chokidar";
5
+ /**
6
+ * Watches an explicit set of absolute file paths and delivers debounced
7
+ * batches only when their contents change. Chokidar follows editor atomic-save
8
+ * replacements without polling by default. The set is replaced wholesale
9
+ * with {@link set}, so the watcher always mirrors exactly the files the caller
10
+ * currently depends on.
11
+ */
12
+ export class DependencyWatcher {
13
+ #options;
14
+ #listeners = new Set();
15
+ #watcher;
16
+ #dependencies = new Set();
17
+ #fingerprints = new Map();
18
+ #pending = new Set();
19
+ #timer;
20
+ #closed = false;
21
+ constructor(options = {}) {
22
+ this.#options = options;
23
+ this.#watcher = watch([], {
24
+ ...options.watch,
25
+ ignoreInitial: true,
26
+ });
27
+ this.#watcher.on("all", (_event, changed) => {
28
+ const absolute = path.resolve(this.#cwd(), changed);
29
+ if (this.#dependencies.has(absolute))
30
+ this.#queue(absolute);
31
+ });
32
+ }
33
+ get dependencies() {
34
+ return this.#dependencies;
35
+ }
36
+ subscribe(listener) {
37
+ this.#listeners.add(listener);
38
+ return () => this.#listeners.delete(listener);
39
+ }
40
+ /** Replace the watched set with `dependencies` (absolute paths). */
41
+ set(dependencies) {
42
+ if (this.#closed)
43
+ return;
44
+ const previous = this.#dependencies;
45
+ this.#dependencies = dependencies;
46
+ const removed = [...previous].filter((dependency) => !dependencies.has(dependency));
47
+ const added = [...dependencies].filter((dependency) => !previous.has(dependency));
48
+ if (removed.length > 0) {
49
+ for (const dependency of removed) {
50
+ this.#fingerprints.delete(dependency);
51
+ this.#pending.delete(dependency);
52
+ }
53
+ void this.#watcher.unwatch(removed);
54
+ }
55
+ if (added.length > 0) {
56
+ for (const dependency of added) {
57
+ this.#fingerprints.set(dependency, this.#fingerprint(dependency));
58
+ }
59
+ this.#watcher.add(added);
60
+ }
61
+ }
62
+ async close() {
63
+ if (this.#closed)
64
+ return;
65
+ this.#closed = true;
66
+ if (this.#timer !== undefined)
67
+ clearTimeout(this.#timer);
68
+ await this.#watcher.close();
69
+ this.#listeners.clear();
70
+ }
71
+ async [Symbol.asyncDispose]() {
72
+ await this.close();
73
+ }
74
+ #cwd() {
75
+ return this.#options.watch?.cwd ?? process.cwd();
76
+ }
77
+ #queue(changed) {
78
+ this.#pending.add(changed);
79
+ if (this.#timer !== undefined)
80
+ clearTimeout(this.#timer);
81
+ this.#timer = setTimeout(() => {
82
+ this.#timer = undefined;
83
+ const pending = this.#pending;
84
+ this.#pending = new Set();
85
+ const paths = new Set();
86
+ for (const dependency of pending) {
87
+ const previous = this.#fingerprints.get(dependency);
88
+ const current = this.#fingerprint(dependency);
89
+ if (current === previous)
90
+ continue;
91
+ this.#fingerprints.set(dependency, current);
92
+ paths.add(dependency);
93
+ }
94
+ if (paths.size === 0)
95
+ return;
96
+ for (const listener of this.#listeners)
97
+ listener({ paths });
98
+ }, this.#options.debounceMs ?? 50);
99
+ }
100
+ #fingerprint(file) {
101
+ try {
102
+ return createHash("sha256")
103
+ .update(readFileSync(file))
104
+ .digest("base64url");
105
+ }
106
+ catch {
107
+ // Missing and unreadable are both materially different from the last
108
+ // successfully read contents, while repeated missing-file events fold
109
+ // onto the same value.
110
+ return undefined;
111
+ }
112
+ }
113
+ }
114
+ //# sourceMappingURL=dependency-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-watcher.js","sourceRoot":"","sources":["../src/dependency-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ export interface OxcLoaderOptions {
2
+ /**
3
+ * Additional package export conditions used during module resolution.
4
+ * They are made available alongside Node's ambient conditions to both the
5
+ * TypeScript-aware resolver and Node's package exports resolver.
6
+ */
7
+ readonly conditions?: ReadonlyArray<string> | undefined;
8
+ /**
9
+ * Honour `tsconfig.json` discovered upward from each file: compiler
10
+ * options for the transform, `paths`/`baseUrl` aliases for resolution.
11
+ * @default true
12
+ */
13
+ readonly tsconfig?: boolean | undefined;
14
+ /** Controls which file URLs belong to the fresh import graph. */
15
+ readonly shouldInvalidate?: ((url: string, parentURL: string | undefined) => boolean) | undefined;
16
+ /**
17
+ * Limits transformation to matching absolute file paths; everything else
18
+ * loads through Node untouched. Lets a published install transpile only
19
+ * the user's own TypeScript while alchemy and its dependencies run their
20
+ * built JavaScript.
21
+ */
22
+ readonly filter?: ((path: string) => boolean) | undefined;
23
+ /**
24
+ * On-disk cache of Oxc output shared by every process on the machine, so
25
+ * the CLI, its dev exec child and the local-provider sidecars transpile
26
+ * each source file once between them rather than once each. `false`
27
+ * disables it, a string names the directory.
28
+ * @default `$ALCHEMY_TRANSFORM_CACHE` (`0` disables), else a per-user
29
+ * directory under the OS temp directory
30
+ */
31
+ readonly cache?: boolean | string | undefined;
32
+ }
33
+ export interface RegisterOxcOptions extends OxcLoaderOptions {
34
+ /**
35
+ * Isolates one import graph in the runtime's module cache: every file
36
+ * URL the graph resolves carries this namespace as a query parameter, so
37
+ * the same files import again as fresh modules under a new namespace.
38
+ * This is how `alchemy dev` reloads the user's stack (see
39
+ * `watch-import.ts`); an un-namespaced registration is the process-wide
40
+ * TypeScript loader.
41
+ */
42
+ readonly namespace?: string | undefined;
43
+ /** Called once the runtime loads a file in this registration's graph. */
44
+ readonly onImport?: ((url: string) => void) | undefined;
45
+ }
46
+ export interface OxcLoader {
47
+ /**
48
+ * Imports a file under this registration's namespace. `specifier` is a
49
+ * file URL, an absolute path, or a path relative to `parentURL`.
50
+ */
51
+ import<T = unknown>(specifier: string, parentURL: string): Promise<T>;
52
+ unregister(): void;
53
+ }
54
+ /**
55
+ * Registers synchronous Node module hooks that transpile TypeScript with
56
+ * Rolldown's Oxc transformer and resolve it the way TypeScript (and tsx)
57
+ * does. A namespaced registration also provides a scoped import whose
58
+ * namespace propagates through the complete ESM graph.
59
+ */
60
+ export declare const registerOxc: (options?: RegisterOxcOptions) => OxcLoader;
61
+ //# sourceMappingURL=register-oxc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-oxc.d.ts","sourceRoot":"","sources":["../src/register-oxc.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,iEAAiE;IACjE,QAAQ,CAAC,gBAAgB,CAAC,EACtB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,GACzD,SAAS,CAAC;IACd;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IAC1D;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzD;AAED,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACtE,UAAU,IAAI,IAAI,CAAC;CACpB;AAkID;;;;;GAKG;AACH,eAAO,MAAM,WAAW,aAAa,kBAAkB,KAAQ,SA8H9D,CAAC"}
@@ -0,0 +1,220 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import * as NodeModule from "node:module";
10
+ import { registerHooks, } from "node:module";
11
+ import { pathToFileURL } from "node:url";
12
+ import { filePathOfUrl, isFileLikeSpecifier, isProjectPath, SpecifierResolver, splitSpecifierMetadata, } from "./resolve-specifier.js";
13
+ import { SourceTransformer } from "./transform-source.js";
14
+ const namespaceParameter = "alchemy-import-namespace";
15
+ const globalRegistrationKey = Symbol.for("@alchemy.run/node-utils/register-oxc");
16
+ const namespaceOf = (url) => {
17
+ if (url === undefined || !url.startsWith("file:"))
18
+ return undefined;
19
+ return new URL(url).searchParams.get(namespaceParameter) ?? undefined;
20
+ };
21
+ const withoutNamespace = (url) => {
22
+ if (!url.startsWith("file:"))
23
+ return url;
24
+ const parsed = new URL(url);
25
+ parsed.searchParams.delete(namespaceParameter);
26
+ return parsed.href;
27
+ };
28
+ const withNamespace = (url, namespace) => {
29
+ const parsed = new URL(url);
30
+ parsed.searchParams.set(namespaceParameter, namespace);
31
+ return parsed.href;
32
+ };
33
+ /**
34
+ * Node's module compile cache (`module.enableCompileCache`) keeps V8 code
35
+ * cache for compiled modules — transformed TypeScript included, since it is
36
+ * keyed by the compiled source — but Node only persists it once after the
37
+ * entry module evaluated and again on a clean exit. Alchemy processes load
38
+ * most of their graph lazily after that point (commands, the user's stack,
39
+ * provider layers) and usually stop on a signal, so without an explicit
40
+ * flush that code never reaches the cache. Flush once module loading has
41
+ * gone quiet; a no-op when the cache is off or this Node predates it.
42
+ */
43
+ const scheduleCompileCacheFlush = (() => {
44
+ let timer;
45
+ return () => {
46
+ if (NodeModule.getCompileCacheDir?.() === undefined)
47
+ return;
48
+ if (timer !== undefined)
49
+ clearTimeout(timer);
50
+ timer = setTimeout(() => {
51
+ timer = undefined;
52
+ NodeModule.flushCompileCache?.();
53
+ }, 1000);
54
+ timer.unref();
55
+ };
56
+ })();
57
+ /** Specifiers Node owns outright: builtins, data URLs, remote schemes. */
58
+ const isForeignSpecifier = (specifier) => /^(?:node:|data:|[a-z][a-z\d+.-]*:\/\/)/i.test(specifier) &&
59
+ !specifier.startsWith("file:");
60
+ /** A `require()` reaching the hooks: Node's CommonJS resolver wants paths, not URLs. */
61
+ const isRequireContext = (context) => context.conditions?.includes("require") === true &&
62
+ !context.conditions.includes("import");
63
+ const resolveWithCandidate = (candidate, metadata, context, nextResolve) => {
64
+ const specifier = isRequireContext(context)
65
+ ? candidate + metadata
66
+ : pathToFileURL(candidate).href + metadata;
67
+ try {
68
+ return nextResolve(specifier, context);
69
+ }
70
+ catch {
71
+ return undefined;
72
+ }
73
+ };
74
+ /**
75
+ * tsx-compatible resolution. Node's resolver decides in the end; Oxc's
76
+ * resolver supplies the TypeScript-aware candidate (tsconfig `paths`,
77
+ * `.js` → `.ts` substitution, extensionless and directory imports) that
78
+ * Node would not find on its own.
79
+ */
80
+ const resolveSpecifier = (resolver, specifier, context, nextResolve) => {
81
+ if (isForeignSpecifier(specifier))
82
+ return nextResolve(specifier, context);
83
+ const parentPath = filePathOfUrl(context.parentURL);
84
+ const { specifier: clean, metadata } = splitSpecifierMetadata(specifier);
85
+ const conditions = context.conditions ?? [];
86
+ // TypeScript's rules apply to project code. Dependencies keep Node's plain
87
+ // resolution so published packages behave exactly as they would without us.
88
+ if (parentPath !== undefined && isProjectPath(parentPath)) {
89
+ const candidate = resolver.resolve(parentPath, clean, conditions);
90
+ if (candidate !== undefined) {
91
+ const resolved = resolveWithCandidate(candidate, metadata, context, nextResolve);
92
+ if (resolved !== undefined)
93
+ return resolved;
94
+ }
95
+ }
96
+ return nextResolve(specifier, context);
97
+ };
98
+ /**
99
+ * `import data from "./x.json"` without an import attribute is how
100
+ * TypeScript projects import JSON (`resolveJsonModule`); Node insists on
101
+ * `with { type: "json" }` for ESM. Supply it, as tsx does.
102
+ */
103
+ const withJsonAttribute = (url, context) => {
104
+ if (!/\.json(?:[?#]|$)/.test(url) || context.importAttributes?.type) {
105
+ return context;
106
+ }
107
+ return {
108
+ ...context,
109
+ importAttributes: { ...context.importAttributes, type: "json" },
110
+ };
111
+ };
112
+ /**
113
+ * Registers synchronous Node module hooks that transpile TypeScript with
114
+ * Rolldown's Oxc transformer and resolve it the way TypeScript (and tsx)
115
+ * does. A namespaced registration also provides a scoped import whose
116
+ * namespace propagates through the complete ESM graph.
117
+ */
118
+ export const registerOxc = (options = {}) => {
119
+ // One global (un-namespaced) registration per process. Alchemy starts every
120
+ // Node process with `--import` of a file that calls this, and in-process
121
+ // callers (the dev exec child, tests) may call it again; a second copy of
122
+ // the hooks would only re-run the resolve chain. The marker lives on
123
+ // globalThis because a checkout can load this module twice (src/ and lib/).
124
+ const globalRegistration = globalThis;
125
+ if (options.namespace === undefined) {
126
+ const existing = globalRegistration[globalRegistrationKey];
127
+ if (existing !== undefined)
128
+ return existing;
129
+ }
130
+ const transformer = new SourceTransformer(options);
131
+ const resolver = new SpecifierResolver({
132
+ tsconfig: options.tsconfig ?? true,
133
+ });
134
+ const shouldInvalidate = options.shouldInvalidate ?? (() => true);
135
+ // Transformed sources reference their source maps (see transform-source);
136
+ // Node only reads and applies them to stack traces once source-map support
137
+ // is on.
138
+ const sourceMapsWereEnabled = process.sourceMapsEnabled;
139
+ process.setSourceMapsEnabled(true);
140
+ const hooks = registerHooks({
141
+ resolve(specifier, context, nextResolve) {
142
+ // A graph's entry carries the namespace itself (see `import` below);
143
+ // everything it imports inherits it from the importing module's URL.
144
+ const namespace = options.namespace === undefined
145
+ ? undefined
146
+ : (namespaceOf(specifier) ?? namespaceOf(context.parentURL));
147
+ if (options.namespace !== undefined && namespace !== options.namespace) {
148
+ return nextResolve(specifier, context);
149
+ }
150
+ const resolutionContext = options.conditions === undefined || options.conditions.length === 0
151
+ ? context
152
+ : {
153
+ ...context,
154
+ conditions: [
155
+ ...new Set([...options.conditions, ...context.conditions]),
156
+ ],
157
+ };
158
+ const resolved = resolveSpecifier(resolver, specifier, resolutionContext, nextResolve);
159
+ if (namespace !== undefined &&
160
+ resolved.url.startsWith("file:") &&
161
+ shouldInvalidate(withoutNamespace(resolved.url), context.parentURL === undefined
162
+ ? undefined
163
+ : withoutNamespace(context.parentURL))) {
164
+ return { ...resolved, url: withNamespace(resolved.url, namespace) };
165
+ }
166
+ return resolved;
167
+ },
168
+ load(url, context, nextLoad) {
169
+ scheduleCompileCacheFlush();
170
+ const namespace = namespaceOf(url);
171
+ if (options.namespace !== undefined && namespace !== options.namespace) {
172
+ return nextLoad(url, context);
173
+ }
174
+ const cleanUrl = withoutNamespace(url);
175
+ const filePath = filePathOfUrl(cleanUrl);
176
+ if (filePath === undefined)
177
+ return nextLoad(cleanUrl, context);
178
+ options.onImport?.(cleanUrl);
179
+ if (options.filter !== undefined && !options.filter(filePath)) {
180
+ return nextLoad(cleanUrl, withJsonAttribute(cleanUrl, context));
181
+ }
182
+ const transformed = transformer.transform(filePath, context.format);
183
+ if (transformed === undefined) {
184
+ return nextLoad(cleanUrl, withJsonAttribute(cleanUrl, context));
185
+ }
186
+ return { ...transformed, shortCircuit: true };
187
+ },
188
+ });
189
+ const loader = {
190
+ import(specifier, parentURL) {
191
+ if (!isFileLikeSpecifier(specifier)) {
192
+ throw new Error(`Cannot import '${specifier}': expected a file URL or path.`);
193
+ }
194
+ const base = parentURL.startsWith("file:")
195
+ ? parentURL
196
+ : pathToFileURL(parentURL).href;
197
+ const url = specifier.startsWith("file:")
198
+ ? specifier
199
+ : new URL(specifier.startsWith(".")
200
+ ? specifier
201
+ : pathToFileURL(specifier).href, base).href;
202
+ return import(__rewriteRelativeImportExtension(options.namespace === undefined
203
+ ? url
204
+ : withNamespace(url, options.namespace)));
205
+ },
206
+ unregister() {
207
+ hooks.deregister();
208
+ if (globalRegistration[globalRegistrationKey] === loader) {
209
+ delete globalRegistration[globalRegistrationKey];
210
+ }
211
+ if (sourceMapsWereEnabled === false)
212
+ process.setSourceMapsEnabled(false);
213
+ },
214
+ };
215
+ if (options.namespace === undefined) {
216
+ globalRegistration[globalRegistrationKey] = loader;
217
+ }
218
+ return loader;
219
+ };
220
+ //# sourceMappingURL=register-oxc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-oxc.js","sourceRoot":"","sources":["../src/register-oxc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * TypeScript-aware specifier resolution on top of Oxc's resolver, mirroring
3
+ * what tsx layers over Node's resolver:
4
+ *
5
+ * - `tsconfig.json` `paths` / `baseUrl` aliases, discovered per importing file
6
+ * - emitted-extension substitution (`./x.js` → `x.ts`/`x.tsx`, `.mjs` → `.mts`,
7
+ * `.cjs` → `.cts`, `.jsx` → `.tsx`), TypeScript source winning over an
8
+ * emitted sibling
9
+ * - extensionless specifiers and directory indexes, TypeScript first
10
+ *
11
+ * Node's own resolver stays the authority: every candidate this class
12
+ * produces is handed back to Node (`nextResolve`) so it decides the format,
13
+ * validates package exports, and reports the canonical error.
14
+ */
15
+ export interface SpecifierResolverOptions {
16
+ /** Discover `tsconfig.json` upward from each importing file. */
17
+ readonly tsconfig: boolean;
18
+ }
19
+ export declare const nodeModulesSegment: string;
20
+ /** Local project code: a file path outside every `node_modules` directory. */
21
+ export declare const isProjectPath: (filePath: string) => boolean;
22
+ /** Whether TypeScript's extension substitution applies to this importer. */
23
+ export declare const isTypeScriptPath: (filePath: string) => boolean;
24
+ export declare const isFileLikeSpecifier: (specifier: string) => boolean;
25
+ /**
26
+ * Splits `?query#fragment` metadata off a specifier. Bare specifiers never
27
+ * carry fragments in Node, so only `?` is honoured there.
28
+ */
29
+ export declare const splitSpecifierMetadata: (specifier: string) => {
30
+ specifier: string;
31
+ metadata: string;
32
+ };
33
+ export declare const filePathOfUrl: (url: string | undefined) => string | undefined;
34
+ export declare class SpecifierResolver {
35
+ #private;
36
+ constructor(options: SpecifierResolverOptions);
37
+ /**
38
+ * Resolves `specifier` as imported from `parentPath` to an absolute file
39
+ * path, or `undefined` when Oxc cannot resolve it (Node then reports the
40
+ * error), when it is a builtin, or when a bare specifier lands inside
41
+ * `node_modules` — packages are Node's business, only `paths` aliases
42
+ * that map onto project files are ours.
43
+ */
44
+ resolve(parentPath: string, specifier: string, conditions: ReadonlyArray<string>): string | undefined;
45
+ }
46
+ //# sourceMappingURL=resolve-specifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-specifier.d.ts","sourceRoot":"","sources":["../src/resolve-specifier.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,kBAAkB,QAAuC,CAAC;AAEvE,8EAA8E;AAC9E,eAAO,MAAM,aAAa,aAAc,MAAM,YACN,CAAC;AAIzC,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,aAAc,MAAM,YACZ,CAAC;AAEtC,eAAO,MAAM,mBAAmB,cAAe,MAAM,YAMzB,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,sBAAsB,cAAe,MAAM;;;CAUvD,CAAC;AAEF,eAAO,MAAM,aAAa,QAAS,MAAM,GAAG,SAAS,uBAOpD,CAAC;AAEF,qBAAa,iBAAiB;;IAK5B,YAAY,OAAO,EAAE,wBAAwB,EA6B5C;IAuBD;;;;;;OAMG;IACH,OAAO,CACL,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,GAChC,MAAM,GAAG,SAAS,CAmBpB;CACF"}