@decohere/flux 0.0.1-dev.125 → 0.0.1-dev.127

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 CHANGED
@@ -140,7 +140,7 @@ On a watched change that reaches a served entry, Flux invalidates that subgraph,
140
140
 
141
141
  Saves less than the window apart (250ms by default) become one reboot. Saves further apart each reboot, and a save during a reboot folds into one follow-up reboot. Whatever the timing, the app ends up on the last save; a reboot in between may fail (an import not yet updated) and logs the error.
142
142
 
143
- The window adds its length to every reload, including a single save. Measured on a rename across six files (#484):
143
+ The window adds its length to every reload, including a single save. Measured on a rename across six files:
144
144
 
145
145
  | Gap between saves | Reboots at 250ms | Reboots at 2000ms |
146
146
  |---|---|---|
@@ -217,7 +217,7 @@ Logs name skipped libraries and deferred packages (script + cwd). Child processe
217
217
 
218
218
  ## Compile cache
219
219
 
220
- Flux keeps the code it compiles on disk, so starting again compiles only what changed (#514). On a cold start with nothing changed, it reads every file from the cache instead of compiling it (`pnpm bench flux-load`, `flux.load.cold-cached`).
220
+ Flux keeps the code it compiles on disk, so starting again compiles only what changed. On a cold start with nothing changed, it reads every file from the cache instead of compiling it (`pnpm bench flux-load`, `flux.load.cold-cached`).
221
221
 
222
222
  - **Where:** `<workspace>/node_modules/.cache/decohere/flux`. When the workspace has no `node_modules`, it's under `$XDG_CACHE_HOME/decohere`, then the OS temp directory.
223
223
  - **Settings:** `DECOHERE_CACHE_DIR=<dir>` moves the cache; `DECOHERE_CACHE=0` turns it off.
@@ -240,7 +240,7 @@ Only source files (`.ts`) that a served entry imports trigger a reboot.
240
240
 
241
241
  **Memory grows over a long session.** Each reboot imports changed modules under a new `?version=` URL, and Node's ES module cache never releases the old versions. That's fine for a working day; if a session runs for days with thousands of reboots, restart it.
242
242
 
243
- Flux uses **Forge’s compiler**, with one SWC config per project built once per run. SWC leaves imports as written; Flux's resolve hook maps each one to its TypeScript source: `@scope/pkg` and `@scope/pkg/sub` through the the workspace package aliases (and tsconfig `paths`), `./file.js` and `./file` to `file.ts` or `file.tsx`, `./file.mjs` to `file.mts`, `./file.cjs` to `file.cts` (which runs as CommonJS), and `./dir` to `dir/index.ts`. Doing it in one place, instead of in SWC (`jsc.paths`, `resolveFully`) and again in the hook, made loading about 20% faster once Node and SWC are warm (`pnpm bench flux-load`, #513). Before Node imports an entry, Flux compiles it and the files it imports, following their imports out from the entry, in parallel on SWC's thread pool (#661). The load hook is synchronous and would otherwise compile one file at a time; files the app never imports, such as tests, are not compiled. A file that fails to compile there is compiled again when Node loads it, and that load fails with the file's name, as before. That is a debug rule so you can edit a library and hit HMR without a pre-build or `node_modules` workspace symlink. Release still resolves through real `node_modules` (published `exports` / `main`).
243
+ Flux uses **Forge’s compiler**, with one SWC config per project built once per run. SWC leaves imports as written; Flux's resolve hook maps each one to its TypeScript source: `@scope/pkg` and `@scope/pkg/sub` through the the workspace package aliases (and tsconfig `paths`), `./file.js` and `./file` to `file.ts` or `file.tsx`, `./file.mjs` to `file.mts`, `./file.cjs` to `file.cts` (which runs as CommonJS), and `./dir` to `dir/index.ts`. Doing it in one place, instead of in SWC (`jsc.paths`, `resolveFully`) and again in the hook, made loading about 20% faster once Node and SWC are warm (`pnpm bench flux-load`). Before Node imports an entry, Flux compiles it and the files it imports, following their imports out from the entry, in parallel on SWC's thread pool. The load hook is synchronous and would otherwise compile one file at a time; files the app never imports, such as tests, are not compiled. A file that fails to compile there is compiled again when Node loads it, and that load fails with the file's name, as before. That is a debug rule so you can edit a library and hit HMR without a pre-build or `node_modules` workspace symlink. Release still resolves through real `node_modules` (published `exports` / `main`).
244
244
 
245
245
  Why aliases, and a tree of where a symlink misses `src/index.ts`: [Forge — debug path aliases](../forge/README.md#debug-path-aliases-not-node_modules-links).
246
246
 
@@ -27,7 +27,7 @@ class FluxModule extends _cli.ModuleManifest {
27
27
  builder.registerSingleton(_deferredscriptrunner.DeferredScriptRunner);
28
28
  }
29
29
  createWorkspace(options) {
30
- // Same workspace as `flux.run` / `flux.serve` and forge (#516).
30
+ // Same workspace as `flux.run` / `flux.serve` and forge.
31
31
  return (0, _forge.createWorkspace)(options);
32
32
  }
33
33
  }
@@ -325,7 +325,7 @@ class HotReloadServer extends _nodeevents.EventEmitter {
325
325
  /**
326
326
  * A failed boot (e.g. importing a file that doesn't exist yet) may have recorded no
327
327
  * dependency edges, so the graph can't tell whether this save fixes it. Any source
328
- * add or change retries failed entries (#512).
328
+ * add or change retries failed entries.
329
329
  */ retryFailedEntries(fullPath) {
330
330
  const failed = [
331
331
  ...this.entries.values()
@@ -369,7 +369,7 @@ class HotReloadServer extends _nodeevents.EventEmitter {
369
369
  // ── Dependency graph ─────────────────────────────────────────────────────
370
370
  /**
371
371
  * Every module that imports `moduleId`, directly or transitively. Visits each module
372
- * once: import graphs share modules (diamonds) and may legally contain cycles (#515).
372
+ * once: import graphs share modules (diamonds) and may legally contain cycles.
373
373
  */ getDependencyGraph(moduleId) {
374
374
  if (this.isSelf(moduleId)) return [];
375
375
  const found = new Set();
@@ -83,7 +83,7 @@ class SourceModuleLoader {
83
83
  transpileCache = new Map();
84
84
  /** Bumped when a file's cached code is dropped, so an up-front compile already running can't put it back. */ transpileVersions = new Map();
85
85
  /** The source files each entry's walk reached, so a reboot only walks out from what changed. */ reachedFrom = new Map();
86
- /** Compiled code on disk across runs (#514); null when caching is off. */ diskCache = null;
86
+ /** Compiled code on disk across runs; null when caching is off. */ diskCache = null;
87
87
  /** Up-front compiles in flight, shared by entries booting at the same time. */ compilingAhead = new Map();
88
88
  /** SWC options per project, built on first use and kept until the next `configure()`. */ swcConfigs = new Map();
89
89
  commonJsConfigs = new Map();
@@ -128,7 +128,7 @@ class SourceModuleLoader {
128
128
  if (this.hooksRegistered) return;
129
129
  this.hooksRegistered = true;
130
130
  // Compiled code carries inline source maps; Node only applies them to stack traces when
131
- // this is on. Without it, errors point at compiled line numbers (#506).
131
+ // this is on. Without it, errors point at compiled line numbers.
132
132
  process.setSourceMapsEnabled(true);
133
133
  (0, _nodemodule.registerHooks)({
134
134
  resolve: (specifier, context, next)=>{
@@ -194,7 +194,7 @@ class SourceModuleLoader {
194
194
  return new Map(entries.flat());
195
195
  }
196
196
  /**
197
- * Compiles the entry and the source files it imports, before Node imports it (#661). The load
197
+ * Compiles the entry and the source files it imports, before Node imports it. The load
198
198
  * hook is synchronous, so it would compile one file at a time on the main thread; async SWC
199
199
  * runs on the thread pool. Walks out from the entry, compiling each file's imports in parallel,
200
200
  * so files the app never imports (tests, other apps) are not compiled. A reboot walks out only
@@ -259,7 +259,7 @@ class SourceModuleLoader {
259
259
  loadTs(url) {
260
260
  if (!url.startsWith("file:")) return null;
261
261
  // fileURLToPath, not URL.pathname: decodes %20 and gives Windows paths, so files
262
- // whose path has a space still match the workspace's package list (#511).
262
+ // whose path has a space still match the workspace's package list.
263
263
  const cleanPath = (0, _nodeurl.fileURLToPath)(url);
264
264
  const fileInfo = this.fileInfoMap.get(cleanPath);
265
265
  if (fileInfo == null) return null;
@@ -277,7 +277,7 @@ class SourceModuleLoader {
277
277
  };
278
278
  }
279
279
  /**
280
- * Compiles a file for the load hook, through the disk cache (#514). Throws, naming the file,
280
+ * Compiles a file for the load hook, through the disk cache. Throws, naming the file,
281
281
  * when it can't be read or doesn't compile.
282
282
  */ compileSync(fullPath, project) {
283
283
  const file = new _io.FileEx({
@@ -308,7 +308,7 @@ class SourceModuleLoader {
308
308
  * Compiles a file ahead, through the disk cache; undefined when it doesn't compile, which the
309
309
  * load hook then reports (see {@link compileAhead}). The source and the cache entry are read
310
310
  * synchronously: for small files that is far cheaper than a trip through libuv's thread pool,
311
- * which async SWC needs for the compiles that miss (#514).
311
+ * which async SWC needs for the compiles that miss.
312
312
  */ async compileAsync(fullPath, project) {
313
313
  const file = new _io.FileEx({
314
314
  fullPath
@@ -332,13 +332,13 @@ class SourceModuleLoader {
332
332
  }
333
333
  /**
334
334
  * The project's SWC options, built once: rebuilding them for every file was about a quarter
335
- * of load time (#513). Import specifiers are left as written, without `jsc.paths` or
335
+ * of load time. Import specifiers are left as written, without `jsc.paths` or
336
336
  * `resolveFully`: the resolve hook maps them to source files (aliases, `.js` to `.ts`,
337
337
  * directory indexes), so SWC does not resolve them a second time against the disk.
338
338
  */ swcConfigFor(project, fullPath) {
339
339
  const config = this.esModuleConfigFor(project);
340
340
  if (!_workspace.sourceExtensions.isCommonJs(fullPath)) return config;
341
- // `.cts` is CommonJS: Node loads it with `require` semantics, so SWC emits CommonJS (#518).
341
+ // `.cts` is CommonJS: Node loads it with `require` semantics, so SWC emits CommonJS.
342
342
  // Kept per project, like the ES module options, so the disk cache hashes them once.
343
343
  const cached = this.commonJsConfigs.get(project);
344
344
  if (cached != null) return cached;
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "staticImports", {
12
12
  * The module specifiers a compiled ES module names in `import … from`, `export … from`, bare
13
13
  * `import "x"` and literal `import("x")`.
14
14
  *
15
- * Only a hint for compiling ahead (#661): a specifier it misses is compiled when Node loads it,
15
+ * Only a hint for compiling ahead: a specifier it misses is compiled when Node loads it,
16
16
  * and one it finds by mistake (an import written inside a string) costs one extra compile. So a
17
17
  * scan of SWC's output is enough; it never decides what runs.
18
18
  */ const STATIC = /\b(?:import|export)\s*(?:[\w$*{},\s]+?\s*from\s*)?["']([^"'\n]+)["']/g;
@@ -17,7 +17,7 @@ export class FluxModule extends ModuleManifest {
17
17
  builder.registerSingleton(DeferredScriptRunner);
18
18
  }
19
19
  createWorkspace(options) {
20
- // Same workspace as `flux.run` / `flux.serve` and forge (#516).
20
+ // Same workspace as `flux.run` / `flux.serve` and forge.
21
21
  return createWorkspace(options);
22
22
  }
23
23
  }
@@ -293,7 +293,7 @@ export class HotReloadServer extends EventEmitter {
293
293
  /**
294
294
  * A failed boot (e.g. importing a file that doesn't exist yet) may have recorded no
295
295
  * dependency edges, so the graph can't tell whether this save fixes it. Any source
296
- * add or change retries failed entries (#512).
296
+ * add or change retries failed entries.
297
297
  */ retryFailedEntries(fullPath) {
298
298
  const failed = [
299
299
  ...this.entries.values()
@@ -337,7 +337,7 @@ export class HotReloadServer extends EventEmitter {
337
337
  // ── Dependency graph ─────────────────────────────────────────────────────
338
338
  /**
339
339
  * Every module that imports `moduleId`, directly or transitively. Visits each module
340
- * once: import graphs share modules (diamonds) and may legally contain cycles (#515).
340
+ * once: import graphs share modules (diamonds) and may legally contain cycles.
341
341
  */ getDependencyGraph(moduleId) {
342
342
  if (this.isSelf(moduleId)) return [];
343
343
  const found = new Set();
@@ -5,7 +5,7 @@ import { packageAliases, sourceExtensions } from "@decohere/workspace";
5
5
  * Map a resolve-hook specifier to a versioned watched `.ts` file URL.
6
6
  * Covers relative `.js` / `.ts` / extensionless imports, directory imports (`./models` is
7
7
  * `./models/index.ts`), and bare workspace package names and subpaths. Flux compiles without
8
- * SWC's own path resolution, so this is the only place imports are mapped to sources (#513).
8
+ * SWC's own path resolution, so this is the only place imports are mapped to sources.
9
9
  */ export function rewriteServeSpecifier(options) {
10
10
  const { specifier, parentUrl, isWatchedTs, resolveBare, versionFileUrl } = options;
11
11
  const relativeTs = resolveRelativeWatchedTs(specifier, parentUrl, isWatchedTs);
@@ -27,7 +27,7 @@ export class SourceModuleLoader {
27
27
  transpileCache = new Map();
28
28
  /** Bumped when a file's cached code is dropped, so an up-front compile already running can't put it back. */ transpileVersions = new Map();
29
29
  /** The source files each entry's walk reached, so a reboot only walks out from what changed. */ reachedFrom = new Map();
30
- /** Compiled code on disk across runs (#514); null when caching is off. */ diskCache = null;
30
+ /** Compiled code on disk across runs; null when caching is off. */ diskCache = null;
31
31
  /** Up-front compiles in flight, shared by entries booting at the same time. */ compilingAhead = new Map();
32
32
  /** SWC options per project, built on first use and kept until the next `configure()`. */ swcConfigs = new Map();
33
33
  commonJsConfigs = new Map();
@@ -72,7 +72,7 @@ export class SourceModuleLoader {
72
72
  if (this.hooksRegistered) return;
73
73
  this.hooksRegistered = true;
74
74
  // Compiled code carries inline source maps; Node only applies them to stack traces when
75
- // this is on. Without it, errors point at compiled line numbers (#506).
75
+ // this is on. Without it, errors point at compiled line numbers.
76
76
  process.setSourceMapsEnabled(true);
77
77
  registerHooks({
78
78
  resolve: (specifier, context, next)=>{
@@ -138,7 +138,7 @@ export class SourceModuleLoader {
138
138
  return new Map(entries.flat());
139
139
  }
140
140
  /**
141
- * Compiles the entry and the source files it imports, before Node imports it (#661). The load
141
+ * Compiles the entry and the source files it imports, before Node imports it. The load
142
142
  * hook is synchronous, so it would compile one file at a time on the main thread; async SWC
143
143
  * runs on the thread pool. Walks out from the entry, compiling each file's imports in parallel,
144
144
  * so files the app never imports (tests, other apps) are not compiled. A reboot walks out only
@@ -203,7 +203,7 @@ export class SourceModuleLoader {
203
203
  loadTs(url) {
204
204
  if (!url.startsWith("file:")) return null;
205
205
  // fileURLToPath, not URL.pathname: decodes %20 and gives Windows paths, so files
206
- // whose path has a space still match the workspace's package list (#511).
206
+ // whose path has a space still match the workspace's package list.
207
207
  const cleanPath = fileURLToPath(url);
208
208
  const fileInfo = this.fileInfoMap.get(cleanPath);
209
209
  if (fileInfo == null) return null;
@@ -221,7 +221,7 @@ export class SourceModuleLoader {
221
221
  };
222
222
  }
223
223
  /**
224
- * Compiles a file for the load hook, through the disk cache (#514). Throws, naming the file,
224
+ * Compiles a file for the load hook, through the disk cache. Throws, naming the file,
225
225
  * when it can't be read or doesn't compile.
226
226
  */ compileSync(fullPath, project) {
227
227
  const file = new FileEx({
@@ -252,7 +252,7 @@ export class SourceModuleLoader {
252
252
  * Compiles a file ahead, through the disk cache; undefined when it doesn't compile, which the
253
253
  * load hook then reports (see {@link compileAhead}). The source and the cache entry are read
254
254
  * synchronously: for small files that is far cheaper than a trip through libuv's thread pool,
255
- * which async SWC needs for the compiles that miss (#514).
255
+ * which async SWC needs for the compiles that miss.
256
256
  */ async compileAsync(fullPath, project) {
257
257
  const file = new FileEx({
258
258
  fullPath
@@ -276,13 +276,13 @@ export class SourceModuleLoader {
276
276
  }
277
277
  /**
278
278
  * The project's SWC options, built once: rebuilding them for every file was about a quarter
279
- * of load time (#513). Import specifiers are left as written, without `jsc.paths` or
279
+ * of load time. Import specifiers are left as written, without `jsc.paths` or
280
280
  * `resolveFully`: the resolve hook maps them to source files (aliases, `.js` to `.ts`,
281
281
  * directory indexes), so SWC does not resolve them a second time against the disk.
282
282
  */ swcConfigFor(project, fullPath) {
283
283
  const config = this.esModuleConfigFor(project);
284
284
  if (!sourceExtensions.isCommonJs(fullPath)) return config;
285
- // `.cts` is CommonJS: Node loads it with `require` semantics, so SWC emits CommonJS (#518).
285
+ // `.cts` is CommonJS: Node loads it with `require` semantics, so SWC emits CommonJS.
286
286
  // Kept per project, like the ES module options, so the disk cache hashes them once.
287
287
  const cached = this.commonJsConfigs.get(project);
288
288
  if (cached != null) return cached;
@@ -2,7 +2,7 @@
2
2
  * The module specifiers a compiled ES module names in `import … from`, `export … from`, bare
3
3
  * `import "x"` and literal `import("x")`.
4
4
  *
5
- * Only a hint for compiling ahead (#661): a specifier it misses is compiled when Node loads it,
5
+ * Only a hint for compiling ahead: a specifier it misses is compiled when Node loads it,
6
6
  * and one it finds by mistake (an import written inside a string) costs one extra compile. So a
7
7
  * scan of SWC's output is enough; it never decides what runs.
8
8
  */ const STATIC = /\b(?:import|export)\s*(?:[\w$*{},\s]+?\s*from\s*)?["']([^"'\n]+)["']/g;
@@ -8,7 +8,7 @@ import { scribe } from "@decohere/scribe";
8
8
  /** Pruning runs at most this often, recorded by the mtime of a marker file. */ const PRUNE_EVERY_MS = 24 * 60 * 60 * 1000;
9
9
  const PRUNE_MARKER = ".last-prune";
10
10
  /**
11
- * Compiled code on disk, so a cold start doesn't compile files that haven't changed (#514).
11
+ * Compiled code on disk, so a cold start doesn't compile files that haven't changed.
12
12
  * Content-addressed: the key hashes the file's path and source, the SWC options it compiles
13
13
  * with, SWC's version and this cache's format, so any change to those is a miss, never a stale
14
14
  * hit. Entries are written to a temp file and renamed into place, so a process reading an entry
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decohere/flux",
3
- "version": "0.0.1-dev.125",
3
+ "version": "0.0.1-dev.127",
4
4
  "description": "Hot module reload server for Node.js ESM applications",
5
5
  "keywords": [
6
6
  "typescript",
@@ -34,12 +34,12 @@
34
34
  "test": "echo \"Error: no test specified\" && exit 1"
35
35
  },
36
36
  "dependencies": {
37
- "@decohere/core": "0.0.1-dev.125",
38
- "@decohere/crucible": "0.0.1-dev.125",
39
- "@decohere/devkit": "0.0.1-dev.125",
40
- "@decohere/forge": "0.0.1-dev.125",
41
- "@decohere/scribe": "0.0.1-dev.125",
42
- "@decohere/workspace": "0.0.1-dev.125",
37
+ "@decohere/core": "0.0.1-dev.127",
38
+ "@decohere/crucible": "0.0.1-dev.127",
39
+ "@decohere/devkit": "0.0.1-dev.127",
40
+ "@decohere/forge": "0.0.1-dev.127",
41
+ "@decohere/scribe": "0.0.1-dev.127",
42
+ "@decohere/workspace": "0.0.1-dev.127",
43
43
  "commander": "^13.1.0",
44
44
  "rxjs": "^7.8.2"
45
45
  },
@@ -29,7 +29,7 @@ export interface HotReloadServerOptions {
29
29
  /**
30
30
  * Quiet window in milliseconds after the last affecting save before a reboot.
31
31
  * Defaults to {@link DEFAULT_REBOOT_DEBOUNCE_MS}. Every reload waits this long, so a larger
32
- * window only pays off for saves known to come at a steady pace inside it (#484).
32
+ * window only pays off for saves known to come at a steady pace inside it.
33
33
  */
34
34
  rebootDebounceMs?: number;
35
35
  }
@@ -74,13 +74,13 @@ export declare class HotReloadServer extends EventEmitter<HotReloadServerEvents>
74
74
  /**
75
75
  * A failed boot (e.g. importing a file that doesn't exist yet) may have recorded no
76
76
  * dependency edges, so the graph can't tell whether this save fixes it. Any source
77
- * add or change retries failed entries (#512).
77
+ * add or change retries failed entries.
78
78
  */
79
79
  private retryFailedEntries;
80
80
  private reloadIfAffected;
81
81
  /**
82
82
  * Every module that imports `moduleId`, directly or transitively. Visits each module
83
- * once: import graphs share modules (diamonds) and may legally contain cycles (#515).
83
+ * once: import graphs share modules (diamonds) and may legally contain cycles.
84
84
  */
85
85
  private getDependencyGraph;
86
86
  private trackDependency;
@@ -9,6 +9,6 @@ export type RewriteServeSpecifierOptions = {
9
9
  * Map a resolve-hook specifier to a versioned watched `.ts` file URL.
10
10
  * Covers relative `.js` / `.ts` / extensionless imports, directory imports (`./models` is
11
11
  * `./models/index.ts`), and bare workspace package names and subpaths. Flux compiles without
12
- * SWC's own path resolution, so this is the only place imports are mapped to sources (#513).
12
+ * SWC's own path resolution, so this is the only place imports are mapped to sources.
13
13
  */
14
14
  export declare function rewriteServeSpecifier(options: RewriteServeSpecifierOptions): string | null;
@@ -34,7 +34,7 @@ export declare class SourceModuleLoader {
34
34
  private transpileVersions;
35
35
  /** The source files each entry's walk reached, so a reboot only walks out from what changed. */
36
36
  private reachedFrom;
37
- /** Compiled code on disk across runs (#514); null when caching is off. */
37
+ /** Compiled code on disk across runs; null when caching is off. */
38
38
  private diskCache;
39
39
  /** Up-front compiles in flight, shared by entries booting at the same time. */
40
40
  private compilingAhead;
@@ -56,7 +56,7 @@ export declare class SourceModuleLoader {
56
56
  dispose(): void;
57
57
  private buildFileInfoMap;
58
58
  /**
59
- * Compiles the entry and the source files it imports, before Node imports it (#661). The load
59
+ * Compiles the entry and the source files it imports, before Node imports it. The load
60
60
  * hook is synchronous, so it would compile one file at a time on the main thread; async SWC
61
61
  * runs on the thread pool. Walks out from the entry, compiling each file's imports in parallel,
62
62
  * so files the app never imports (tests, other apps) are not compiled. A reboot walks out only
@@ -74,7 +74,7 @@ export declare class SourceModuleLoader {
74
74
  private sourcePathOf;
75
75
  private loadTs;
76
76
  /**
77
- * Compiles a file for the load hook, through the disk cache (#514). Throws, naming the file,
77
+ * Compiles a file for the load hook, through the disk cache. Throws, naming the file,
78
78
  * when it can't be read or doesn't compile.
79
79
  */
80
80
  private compileSync;
@@ -82,12 +82,12 @@ export declare class SourceModuleLoader {
82
82
  * Compiles a file ahead, through the disk cache; undefined when it doesn't compile, which the
83
83
  * load hook then reports (see {@link compileAhead}). The source and the cache entry are read
84
84
  * synchronously: for small files that is far cheaper than a trip through libuv's thread pool,
85
- * which async SWC needs for the compiles that miss (#514).
85
+ * which async SWC needs for the compiles that miss.
86
86
  */
87
87
  private compileAsync;
88
88
  /**
89
89
  * The project's SWC options, built once: rebuilding them for every file was about a quarter
90
- * of load time (#513). Import specifiers are left as written, without `jsc.paths` or
90
+ * of load time. Import specifiers are left as written, without `jsc.paths` or
91
91
  * `resolveFully`: the resolve hook maps them to source files (aliases, `.js` to `.ts`,
92
92
  * directory indexes), so SWC does not resolve them a second time against the disk.
93
93
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Compiled code on disk, so a cold start doesn't compile files that haven't changed (#514).
2
+ * Compiled code on disk, so a cold start doesn't compile files that haven't changed.
3
3
  * Content-addressed: the key hashes the file's path and source, the SWC options it compiles
4
4
  * with, SWC's version and this cache's format, so any change to those is a miss, never a stale
5
5
  * hit. Entries are written to a temp file and renamed into place, so a process reading an entry