@decohere/flux 0.0.1-dev.12 → 0.0.1-dev.121
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 +273 -0
- package/commonjs/src/deferred-script-runner.js +56 -0
- package/commonjs/src/flux.command.js +3 -3
- package/commonjs/src/flux.js +56 -0
- package/commonjs/src/flux.module.js +9 -8
- package/commonjs/src/hot-reload-server.js +307 -219
- package/commonjs/src/index.js +34 -2
- package/commonjs/src/rewrite-serve-specifier.js +61 -0
- package/commonjs/src/run.action.js +47 -0
- package/commonjs/src/run.command.js +65 -0
- package/commonjs/src/serve.action.js +78 -7
- package/commonjs/src/serve.command.js +35 -4
- package/commonjs/src/slice-serve.js +130 -0
- package/commonjs/src/source-module-loader.js +378 -0
- package/commonjs/src/static-imports.js +37 -0
- package/commonjs/src/transpile-disk-cache.js +148 -0
- package/es6/src/deferred-script-runner.js +46 -0
- package/es6/src/flux.command.js +3 -3
- package/es6/src/flux.js +41 -0
- package/es6/src/flux.module.js +9 -8
- package/es6/src/hot-reload-server.js +287 -175
- package/es6/src/index.js +5 -3
- package/es6/src/rewrite-serve-specifier.js +51 -0
- package/es6/src/run.action.js +37 -0
- package/es6/src/run.command.js +55 -0
- package/es6/src/serve.action.js +73 -9
- package/es6/src/serve.command.js +35 -4
- package/es6/src/slice-serve.js +105 -0
- package/es6/src/source-module-loader.js +322 -0
- package/es6/src/static-imports.js +27 -0
- package/es6/src/transpile-disk-cache.js +142 -0
- package/package.json +8 -6
- package/types/src/deferred-script-runner.d.ts +18 -0
- package/types/src/flux.command.d.ts +2 -2
- package/types/src/flux.d.ts +43 -0
- package/types/src/flux.module.d.ts +6 -4
- package/types/src/hot-reload-server.d.ts +57 -23
- package/types/src/index.d.ts +8 -1
- package/types/src/rewrite-serve-specifier.d.ts +14 -0
- package/types/src/run.action.d.ts +15 -0
- package/types/src/run.command.d.ts +11 -0
- package/types/src/serve.action.d.ts +13 -3
- package/types/src/serve.command.d.ts +7 -1
- package/types/src/slice-serve.d.ts +52 -0
- package/types/src/source-module-loader.d.ts +96 -0
- package/types/src/static-imports.d.ts +5 -0
- package/types/src/transpile-disk-cache.d.ts +38 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
-
import type { Workspace } from "@decohere/
|
|
2
|
+
import type { Workspace } from "@decohere/workspace";
|
|
3
|
+
/** Default quiet window before a file-change reboot. */
|
|
4
|
+
export declare const DEFAULT_REBOOT_DEBOUNCE_MS = 250;
|
|
5
|
+
export declare function resolveRebootDebounceMs(value: number | undefined): number;
|
|
6
|
+
/** Info-level HMR start block — keep `flux reboot` in the text so operators can search the buffer. */
|
|
7
|
+
export declare function formatFluxRebootStart(labels: readonly string[], triggers?: readonly string[]): string;
|
|
8
|
+
/** Info-level HMR finish block. */
|
|
9
|
+
export declare function formatFluxRebootReady(labels: readonly string[], elapsedMs: number): string;
|
|
3
10
|
export interface HotReloadServerEvents {
|
|
4
11
|
start: [];
|
|
5
12
|
reboot: [];
|
|
@@ -9,56 +16,83 @@ export interface HotReloadServerOptions {
|
|
|
9
16
|
buildConfig: string;
|
|
10
17
|
/** Name of the project to serve. Defaults to the first project in the workspace. */
|
|
11
18
|
project?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Multiple Flux app package names to boot in one process (directory slice).
|
|
21
|
+
* When set, takes precedence over {@link project}.
|
|
22
|
+
*/
|
|
23
|
+
projects?: readonly string[];
|
|
12
24
|
/**
|
|
13
25
|
* Pre-built Workspace instance to use instead of running WorkspaceFactory.
|
|
14
26
|
* Useful in tests to bypass filesystem-based workspace discovery.
|
|
15
27
|
*/
|
|
16
28
|
workspace?: Workspace;
|
|
29
|
+
/**
|
|
30
|
+
* Quiet window in milliseconds after the last affecting save before a reboot.
|
|
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).
|
|
33
|
+
*/
|
|
34
|
+
rebootDebounceMs?: number;
|
|
17
35
|
}
|
|
18
36
|
export declare class HotReloadServer extends EventEmitter<HotReloadServerEvents> {
|
|
19
37
|
private readonly logger;
|
|
38
|
+
private readonly loader;
|
|
20
39
|
private disposed;
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
private
|
|
24
|
-
|
|
40
|
+
/** Absolute entry paths currently served (one or more Flux apps). */
|
|
41
|
+
private entries;
|
|
42
|
+
private pendingEntryReboots;
|
|
43
|
+
/** Source paths that scheduled the next reboot (cleared when that reboot starts). */
|
|
44
|
+
private pendingTriggers;
|
|
25
45
|
private watchSubscription?;
|
|
26
|
-
/** Map from absolute .ts source file path to project info */
|
|
27
|
-
private fileInfoMap;
|
|
28
46
|
private moduleCache;
|
|
29
47
|
private dependencies;
|
|
30
|
-
private
|
|
31
|
-
private
|
|
48
|
+
private rebootTail;
|
|
49
|
+
private rebootDebounceGen;
|
|
50
|
+
private rebootInFlight;
|
|
51
|
+
private rebootFollowUp;
|
|
52
|
+
private rebootQueued;
|
|
53
|
+
/** Modules whose reverse-graph edges are pruned at reboot, not on schedule. */
|
|
54
|
+
private pendingGraphPrune;
|
|
55
|
+
private scheduleReboot;
|
|
32
56
|
start(options: HotReloadServerOptions): Promise<void>;
|
|
33
57
|
dispose(): Promise<void>;
|
|
34
58
|
[Symbol.asyncDispose](): Promise<void>;
|
|
59
|
+
private bootEntries;
|
|
35
60
|
private bootEntry;
|
|
36
|
-
private
|
|
61
|
+
private bindScheduleReboot;
|
|
62
|
+
private requestReboot;
|
|
63
|
+
private runReboot;
|
|
64
|
+
private disposeEntries;
|
|
37
65
|
private disposeEntry;
|
|
38
|
-
private
|
|
39
|
-
private
|
|
40
|
-
private resolveProject;
|
|
41
|
-
private buildFileInfoMap;
|
|
42
|
-
private registerHooks;
|
|
43
|
-
/**
|
|
44
|
-
* Pre-next specifier rewriter: if specifier is a .js import that maps to a
|
|
45
|
-
* known .ts source file, returns the versioned .ts file URL so next() never
|
|
46
|
-
* tries to load a non-existent .js file from disk.
|
|
47
|
-
*/
|
|
48
|
-
private rewriteJsToTs;
|
|
66
|
+
private requireWorkspace;
|
|
67
|
+
private resolveProjects;
|
|
49
68
|
/**
|
|
50
69
|
* Post-next dependency tracker: records which source files import which
|
|
51
70
|
* other source files so that reloadIfAffected can traverse the graph.
|
|
52
71
|
*/
|
|
53
72
|
private onPostResolve;
|
|
54
|
-
private loadTs;
|
|
55
73
|
private onFileChange;
|
|
74
|
+
/**
|
|
75
|
+
* A failed boot (e.g. importing a file that doesn't exist yet) may have recorded no
|
|
76
|
+
* dependency edges, so the graph can't tell whether this save fixes it. Any source
|
|
77
|
+
* add or change retries failed entries (#512).
|
|
78
|
+
*/
|
|
79
|
+
private retryFailedEntries;
|
|
56
80
|
private reloadIfAffected;
|
|
81
|
+
/**
|
|
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).
|
|
84
|
+
*/
|
|
57
85
|
private getDependencyGraph;
|
|
58
86
|
private trackDependency;
|
|
59
87
|
private getCachedOrNew;
|
|
60
88
|
private versionModule;
|
|
61
|
-
private
|
|
89
|
+
private invalidateModuleCaches;
|
|
90
|
+
private prunePendingDependencyEdges;
|
|
91
|
+
/** Remove these modules as parents so boot can rebuild edges without stale importers. */
|
|
92
|
+
private pruneDependencyParents;
|
|
62
93
|
private invalidateAllSourceFiles;
|
|
63
94
|
private isSelf;
|
|
95
|
+
private labelsFor;
|
|
96
|
+
private takeTriggers;
|
|
97
|
+
private formatTrigger;
|
|
64
98
|
}
|
package/types/src/index.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
export { DeferredScriptRunner } from "./deferred-script-runner.js";
|
|
2
|
+
export type { FluxRunOptions, FluxServeOptions } from "./flux.js";
|
|
3
|
+
export { flux } from "./flux.js";
|
|
1
4
|
export { FluxModule } from "./flux.module.js";
|
|
2
5
|
export type { HotReloadServerOptions } from "./hot-reload-server.js";
|
|
3
|
-
export { HotReloadServer } from "./hot-reload-server.js";
|
|
6
|
+
export { DEFAULT_REBOOT_DEBOUNCE_MS, HotReloadServer } from "./hot-reload-server.js";
|
|
7
|
+
export type { RunOptions } from "./run.action.js";
|
|
4
8
|
export type { ServeOptions } from "./serve.action.js";
|
|
9
|
+
export { type ClassifiedSlice, classifySliceProject, classifySliceProjects, normalizeSlicePrefix, projectsInSlice, projectsInSlices, resolveDeferScript, type SliceKind, type SliceProjectView, } from "./slice-serve.js";
|
|
10
|
+
export type { SourceModuleLoaderOptions } from "./source-module-loader.js";
|
|
11
|
+
export { SourceModuleLoader } from "./source-module-loader.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type RewriteServeSpecifierOptions = {
|
|
2
|
+
specifier: string;
|
|
3
|
+
parentUrl: string;
|
|
4
|
+
isWatchedTs: (absolutePath: string) => boolean;
|
|
5
|
+
resolveBare: (specifier: string) => string | null;
|
|
6
|
+
versionFileUrl: (fileUrl: string) => string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Map a resolve-hook specifier to a versioned watched `.ts` file URL.
|
|
10
|
+
* Covers relative `.js` / `.ts` / extensionless imports, directory imports (`./models` is
|
|
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).
|
|
13
|
+
*/
|
|
14
|
+
export declare function rewriteServeSpecifier(options: RewriteServeSpecifierOptions): string | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Workspace } from "@decohere/workspace";
|
|
2
|
+
import { type Action, ActionResponse } from "@decohere/devkit/cli";
|
|
3
|
+
export type RunOptions = {
|
|
4
|
+
/** Absolute or cwd-relative path to a `.ts` entry file. */
|
|
5
|
+
entry: string;
|
|
6
|
+
configuration: string;
|
|
7
|
+
/** Arguments forwarded to the entry (bin-style `process.argv.slice(2)`). */
|
|
8
|
+
args?: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare class RunAction implements Action<RunOptions> {
|
|
11
|
+
private readonly workspace;
|
|
12
|
+
private readonly logger;
|
|
13
|
+
constructor(workspace: Workspace);
|
|
14
|
+
run(options: RunOptions): Promise<ActionResponse>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DecohereCommand } from "@decohere/devkit/cli";
|
|
2
|
+
import { RunAction } from "./run.action.js";
|
|
3
|
+
export declare class RunCommand extends DecohereCommand {
|
|
4
|
+
get actions(): (typeof RunAction)[];
|
|
5
|
+
constructor(name: string);
|
|
6
|
+
/**
|
|
7
|
+
* Commander passes positionals before options when `<entry> [args...]` is declared.
|
|
8
|
+
* The CLI host ModuleFactory expects `(opts, cmd)` — normalize and stash entry/args on opts.
|
|
9
|
+
*/
|
|
10
|
+
action(fn: (...args: any[]) => void | Promise<void>): this;
|
|
11
|
+
}
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { Workspace } from "@decohere/
|
|
2
|
-
import { type Action, ActionResponse } from "@decohere/
|
|
1
|
+
import { Workspace } from "@decohere/workspace";
|
|
2
|
+
import { type Action, ActionResponse } from "@decohere/devkit/cli";
|
|
3
|
+
import { DeferredScriptRunner } from "./deferred-script-runner.js";
|
|
3
4
|
import { HotReloadServer } from "./hot-reload-server.js";
|
|
4
5
|
export type ServeOptions = {
|
|
5
6
|
configuration: string;
|
|
6
7
|
project?: string;
|
|
8
|
+
/** One or more module directory tokens (`funding`, `shell`, `projects/funding`). */
|
|
9
|
+
slices?: string[];
|
|
10
|
+
rebootDebounceMs?: number;
|
|
7
11
|
};
|
|
8
12
|
export declare class ServeAction implements Action<ServeOptions> {
|
|
9
13
|
private readonly server;
|
|
10
14
|
private readonly workspace;
|
|
11
|
-
|
|
15
|
+
private readonly deferredScripts;
|
|
16
|
+
private readonly logger;
|
|
17
|
+
constructor(server: HotReloadServer, workspace: Workspace, deferredScripts: DeferredScriptRunner);
|
|
12
18
|
run(options: ServeOptions): Promise<ActionResponse>;
|
|
19
|
+
private runSlices;
|
|
20
|
+
private toSliceViews;
|
|
21
|
+
private toSliceView;
|
|
22
|
+
private findProject;
|
|
13
23
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { DecohereCommand } from "@decohere/
|
|
1
|
+
import { DecohereCommand } from "@decohere/devkit/cli";
|
|
2
2
|
import { ServeAction } from "./serve.action.js";
|
|
3
3
|
export declare class ServeCommand extends DecohereCommand {
|
|
4
4
|
get actions(): (typeof ServeAction)[];
|
|
5
5
|
constructor(name: string);
|
|
6
|
+
runsUntilStopped(): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Commander passes positional args before options when `[slices...]` is declared.
|
|
9
|
+
* The CLI host ModuleFactory expects `(opts, cmd)` — normalize here.
|
|
10
|
+
*/
|
|
11
|
+
action(fn: (...args: any[]) => void | Promise<void>): this;
|
|
6
12
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Directory-slice helpers for `flux serve <dir>…` — classify workspace packages as
|
|
3
|
+
* Flux apps, Nixpacks-style script deferrals, or libraries to skip.
|
|
4
|
+
*/
|
|
5
|
+
export type SliceProjectView = {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
/** Relative project dir from workspace root (e.g. `projects/funding/api`). */
|
|
8
|
+
readonly projectDirectory: string;
|
|
9
|
+
readonly main: string;
|
|
10
|
+
readonly scripts: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
export type SliceKind = "flux" | "defer" | "skip";
|
|
13
|
+
export type ClassifiedSlice = {
|
|
14
|
+
readonly flux: SliceProjectView[];
|
|
15
|
+
readonly defer: SliceProjectView[];
|
|
16
|
+
readonly skip: SliceProjectView[];
|
|
17
|
+
};
|
|
18
|
+
/** Preferred package scripts for foreign toolchains (Nixpacks-style). */
|
|
19
|
+
export declare const DEFER_SCRIPT_CANDIDATES: readonly ["dev", "serve"];
|
|
20
|
+
/**
|
|
21
|
+
* Normalize a CLI slice token to a `projects/…` prefix without a trailing slash.
|
|
22
|
+
* `funding` and `projects/funding` both become `projects/funding`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function normalizeSlicePrefix(slice: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* True when `projectDirectory` belongs to the slice token.
|
|
27
|
+
*
|
|
28
|
+
* Matches:
|
|
29
|
+
* - nested: `projects/funding`, `projects/funding/api`
|
|
30
|
+
* - flat dotted package dirs: `projects/funding.web` for token `funding`
|
|
31
|
+
*
|
|
32
|
+
* Does not match siblings that only share a string prefix (`funding` vs `funding-fee.api`).
|
|
33
|
+
*/
|
|
34
|
+
export declare function isUnderSlice(projectDirectory: string, slicePrefix: string): boolean;
|
|
35
|
+
export declare function projectsInSlice(projects: readonly SliceProjectView[], slice: string): SliceProjectView[];
|
|
36
|
+
/** Union of packages under any of the slice tokens (deduped by package name). */
|
|
37
|
+
export declare function projectsInSlices(projects: readonly SliceProjectView[], slices: readonly string[]): SliceProjectView[];
|
|
38
|
+
/** Script invokes Flux (in-process serve stays on Flux, not deferred). */
|
|
39
|
+
export declare function isFluxOwnedScript(script: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* First Nixpacks-style serve script that is not Flux-owned.
|
|
42
|
+
* Prefers `dev`, then `serve`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveDeferScript(scripts: Record<string, string>): string | undefined;
|
|
45
|
+
/** Convention: Flux Node apps use `main` ending in `main.ts` / `main.tsx`. */
|
|
46
|
+
export declare function isFluxAppMain(main: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Classify one package. Foreign serve scripts win over `main.ts` (Vite apps
|
|
49
|
+
* often have a main entry but must not be HMR-booted by Flux).
|
|
50
|
+
*/
|
|
51
|
+
export declare function classifySliceProject(project: SliceProjectView): SliceKind;
|
|
52
|
+
export declare function classifySliceProjects(projects: readonly SliceProjectView[], slices: string | readonly string[]): ClassifiedSlice;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { ResolveFnOutput } from "node:module";
|
|
2
|
+
import type { Project, Workspace } from "@decohere/workspace";
|
|
3
|
+
export interface SourceModuleLoaderOptions {
|
|
4
|
+
/** Build configuration name. */
|
|
5
|
+
buildConfig: string;
|
|
6
|
+
/**
|
|
7
|
+
* Pre-built Workspace instance to use instead of running WorkspaceFactory.
|
|
8
|
+
* Useful in tests to bypass filesystem-based workspace discovery.
|
|
9
|
+
*/
|
|
10
|
+
workspace?: Workspace;
|
|
11
|
+
/**
|
|
12
|
+
* Map a watched `.ts` file URL for ESM resolution.
|
|
13
|
+
* Hot reload passes a `?version=` bust; one-shot run uses identity.
|
|
14
|
+
*/
|
|
15
|
+
versionFileUrl?: (fileUrl: string) => string;
|
|
16
|
+
/** Optional post-resolve hook (e.g. dependency tracking for HMR). */
|
|
17
|
+
onResolved?: (result: ResolveFnOutput, parentUrl: string) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Registers Node ESM resolve/load hooks and SWC-transpiles workspace `.ts`
|
|
21
|
+
* on the fly. No file watching and no entry reboot — that belongs to
|
|
22
|
+
* {@link HotReloadServer}.
|
|
23
|
+
*/
|
|
24
|
+
export declare class SourceModuleLoader {
|
|
25
|
+
private readonly logger;
|
|
26
|
+
private readonly transpiler;
|
|
27
|
+
private disposed;
|
|
28
|
+
private hooksRegistered;
|
|
29
|
+
private workspace?;
|
|
30
|
+
private buildConfig;
|
|
31
|
+
private fileInfoMap;
|
|
32
|
+
private transpileCache;
|
|
33
|
+
/** Bumped when a file's cached code is dropped, so an up-front compile already running can't put it back. */
|
|
34
|
+
private transpileVersions;
|
|
35
|
+
/** The source files each entry's walk reached, so a reboot only walks out from what changed. */
|
|
36
|
+
private reachedFrom;
|
|
37
|
+
/** Compiled code on disk across runs (#514); null when caching is off. */
|
|
38
|
+
private diskCache;
|
|
39
|
+
/** Up-front compiles in flight, shared by entries booting at the same time. */
|
|
40
|
+
private compilingAhead;
|
|
41
|
+
/** SWC options per project, built on first use and kept until the next `configure()`. */
|
|
42
|
+
private swcConfigs;
|
|
43
|
+
private commonJsConfigs;
|
|
44
|
+
private aliasPaths;
|
|
45
|
+
private aliasBaseUrl;
|
|
46
|
+
private versionFileUrl;
|
|
47
|
+
private onResolved?;
|
|
48
|
+
getWorkspace(): Workspace | undefined;
|
|
49
|
+
hasSourceFile(absolutePath: string): boolean;
|
|
50
|
+
sourceFilePaths(): IterableIterator<string>;
|
|
51
|
+
setSourceFile(absolutePath: string, project: Project): void;
|
|
52
|
+
configure(options: SourceModuleLoaderOptions): Promise<void>;
|
|
53
|
+
registerHooks(): void;
|
|
54
|
+
importEntry(absolutePath: string): Promise<unknown>;
|
|
55
|
+
invalidateTranspile(...absolutePaths: string[]): void;
|
|
56
|
+
dispose(): void;
|
|
57
|
+
private buildFileInfoMap;
|
|
58
|
+
/**
|
|
59
|
+
* Compiles the entry and the source files it imports, before Node imports it (#661). The load
|
|
60
|
+
* hook is synchronous, so it would compile one file at a time on the main thread; async SWC
|
|
61
|
+
* runs on the thread pool. Walks out from the entry, compiling each file's imports in parallel,
|
|
62
|
+
* so files the app never imports (tests, other apps) are not compiled. A reboot walks out only
|
|
63
|
+
* from the files it reached before that are no longer cached (the saved ones), so their new
|
|
64
|
+
* imports are found without visiting the rest of the graph again.
|
|
65
|
+
*
|
|
66
|
+
* A file that fails here is left out of the cache instead of failing the boot: the load hook
|
|
67
|
+
* then compiles it again and throws as before, naming the file. The walk is a hint; whatever
|
|
68
|
+
* it misses is compiled by the load hook when Node gets to it.
|
|
69
|
+
*/
|
|
70
|
+
private compileAhead;
|
|
71
|
+
/** The file's compiled code, from the cache or compiled now; undefined if it isn't a source. */
|
|
72
|
+
private compiledAhead;
|
|
73
|
+
/** The source file a specifier names, mapped the way the resolve hook maps it. */
|
|
74
|
+
private sourcePathOf;
|
|
75
|
+
private loadTs;
|
|
76
|
+
/**
|
|
77
|
+
* Compiles a file for the load hook, through the disk cache (#514). Throws, naming the file,
|
|
78
|
+
* when it can't be read or doesn't compile.
|
|
79
|
+
*/
|
|
80
|
+
private compileSync;
|
|
81
|
+
/**
|
|
82
|
+
* Compiles a file ahead, through the disk cache; undefined when it doesn't compile, which the
|
|
83
|
+
* load hook then reports (see {@link compileAhead}). The source and the cache entry are read
|
|
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).
|
|
86
|
+
*/
|
|
87
|
+
private compileAsync;
|
|
88
|
+
/**
|
|
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
|
|
91
|
+
* `resolveFully`: the resolve hook maps them to source files (aliases, `.js` to `.ts`,
|
|
92
|
+
* directory indexes), so SWC does not resolve them a second time against the disk.
|
|
93
|
+
*/
|
|
94
|
+
private swcConfigFor;
|
|
95
|
+
private esModuleConfigFor;
|
|
96
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiled code on disk, so a cold start doesn't compile files that haven't changed (#514).
|
|
3
|
+
* Content-addressed: the key hashes the file's path and source, the SWC options it compiles
|
|
4
|
+
* with, SWC's version and this cache's format, so any change to those is a miss, never a stale
|
|
5
|
+
* hit. Entries are written to a temp file and renamed into place, so a process reading an entry
|
|
6
|
+
* another is writing sees all of it or none.
|
|
7
|
+
*
|
|
8
|
+
* The cache is an optimisation: if it can't read or write its directory, it says so once and
|
|
9
|
+
* turns itself off for the process, and flux compiles as it would without it.
|
|
10
|
+
*/
|
|
11
|
+
export declare class TranspileDiskCache {
|
|
12
|
+
private readonly dir;
|
|
13
|
+
private readonly logger;
|
|
14
|
+
private disabled;
|
|
15
|
+
private constructor();
|
|
16
|
+
/** The cache for a workspace, or null when caching is off (`DECOHERE_CACHE=0`). */
|
|
17
|
+
static forWorkspace(rootDir: string): TranspileDiskCache | null;
|
|
18
|
+
get directory(): string;
|
|
19
|
+
/**
|
|
20
|
+
* The key for a file compiled with `baseOptions`: the per-file options are those plus the
|
|
21
|
+
* file's path (forge's `createFileConfig`), so hashing the base once per project and adding
|
|
22
|
+
* the path covers them without serialising options for every file.
|
|
23
|
+
*/
|
|
24
|
+
keyFor(fullPath: string, source: string, baseOptions: object): string;
|
|
25
|
+
private readonly optionsHashes;
|
|
26
|
+
private optionsHash;
|
|
27
|
+
readSync(key: string): string | undefined;
|
|
28
|
+
read(key: string): Promise<string | undefined>;
|
|
29
|
+
writeSync(key: string, code: string): void;
|
|
30
|
+
write(key: string, code: string): Promise<void>;
|
|
31
|
+
/** Deletes entries older than 30 days, if it hasn't done so in the last day. */
|
|
32
|
+
pruneIfDue(now?: number): Promise<void>;
|
|
33
|
+
private entryPath;
|
|
34
|
+
private tempPath;
|
|
35
|
+
/** A missing entry is a miss; any other read error turns the cache off. */
|
|
36
|
+
private missOrDisable;
|
|
37
|
+
private disable;
|
|
38
|
+
}
|