@decohere/flux 0.0.1-dev.124 → 0.0.1-dev.126
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 +3 -3
- package/commonjs/src/flux.module.js +1 -1
- package/commonjs/src/hot-reload-server.js +2 -2
- package/commonjs/src/source-module-loader.js +8 -8
- package/commonjs/src/static-imports.js +1 -1
- package/es6/src/flux.module.js +1 -1
- package/es6/src/hot-reload-server.js +2 -2
- package/es6/src/rewrite-serve-specifier.js +1 -1
- package/es6/src/source-module-loader.js +8 -8
- package/es6/src/static-imports.js +1 -1
- package/es6/src/transpile-disk-cache.js +1 -1
- package/package.json +7 -7
- package/types/src/hot-reload-server.d.ts +3 -3
- package/types/src/rewrite-serve-specifier.d.ts +1 -1
- package/types/src/source-module-loader.d.ts +5 -5
- package/types/src/transpile-disk-cache.d.ts +1 -1
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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;
|
package/es6/src/flux.module.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.0.1-dev.126",
|
|
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.
|
|
38
|
-
"@decohere/crucible": "0.0.1-dev.
|
|
39
|
-
"@decohere/devkit": "0.0.1-dev.
|
|
40
|
-
"@decohere/forge": "0.0.1-dev.
|
|
41
|
-
"@decohere/scribe": "0.0.1-dev.
|
|
42
|
-
"@decohere/workspace": "0.0.1-dev.
|
|
37
|
+
"@decohere/core": "0.0.1-dev.126",
|
|
38
|
+
"@decohere/crucible": "0.0.1-dev.126",
|
|
39
|
+
"@decohere/devkit": "0.0.1-dev.126",
|
|
40
|
+
"@decohere/forge": "0.0.1-dev.126",
|
|
41
|
+
"@decohere/scribe": "0.0.1-dev.126",
|
|
42
|
+
"@decohere/workspace": "0.0.1-dev.126",
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|