@absolutejs/absolute 0.20.0-beta.72 → 0.20.0-beta.73
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/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/{dev-rbvkxpj7.js → dev-p7s1ej32.js} +224 -1
- package/dist/cli/index.js +1 -1
- package/dist/dev/importCostPreload.js +206 -0
- package/dist/dev/importCostReport.js +730 -0
- package/dist/dev/serverBootstrap.js +60 -11
- package/dist/index.js +19 -1
- package/dist/index.js.map +4 -4
- package/dist/src/dev/earlyListener.d.ts +32 -0
- package/dist/src/dev/importCost/deferability.d.ts +11 -0
- package/dist/src/dev/importCost/dominators.d.ts +37 -0
- package/dist/src/dev/importCost/format.d.ts +29 -0
- package/dist/src/dev/importCost/instrument.d.ts +5 -0
- package/dist/src/dev/importCost/moduleGraph.d.ts +13 -0
- package/dist/src/dev/importCost/recorder.d.ts +37 -0
- package/dist/src/dev/importCost/report.d.ts +3 -0
- package/dist/src/dev/importCost/scope.d.ts +10 -0
- package/dist/src/dev/importCost/selfTimes.d.ts +17 -0
- package/dist/src/dev/importCostPreload.d.ts +1 -0
- package/dist/src/dev/importCostReport.d.ts +1 -0
- package/dist/types/globals.d.ts +15 -0
- package/package.json +7 -7
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { Server } from 'bun';
|
|
2
2
|
export declare const BOOT_STATUS_HEADER = "X-Absolute-Boot";
|
|
3
|
+
/** Written by the child on fd 3 the instant the real server is bound, so
|
|
4
|
+
* the CLI can close its placeholder. A dedicated pipe rather than stdout:
|
|
5
|
+
* the marker must never reach the developer's terminal or the instance
|
|
6
|
+
* log, and stdout chunks coalesce in ways that make stripping a line out
|
|
7
|
+
* of the forwarded stream unreliable. */
|
|
8
|
+
export declare const PARENT_HANDOFF_MARKER = "absolute:listening";
|
|
9
|
+
/** Set on the child by the CLI when the CLI itself holds the placeholder
|
|
10
|
+
* on the dev port. The child then skips its own placeholder and binds the
|
|
11
|
+
* real server with `reusePort` so the two can overlap. */
|
|
12
|
+
export declare const PARENT_LISTENER_ENV = "ABSOLUTE_PARENT_LISTENER";
|
|
3
13
|
export type EarlyListenerOptions = {
|
|
4
14
|
host: string;
|
|
5
15
|
port: number;
|
|
@@ -7,6 +17,10 @@ export type EarlyListenerOptions = {
|
|
|
7
17
|
cert: string;
|
|
8
18
|
key: string;
|
|
9
19
|
} | null;
|
|
20
|
+
/** Bind with `SO_REUSEPORT` so the child's real server can bind the
|
|
21
|
+
* same port before this placeholder goes away. Only the CLI parent
|
|
22
|
+
* sets it. */
|
|
23
|
+
reusePort?: boolean;
|
|
10
24
|
};
|
|
11
25
|
export type EarlyListener = {
|
|
12
26
|
/** The placeholder server, or null while a bind retry is pending or
|
|
@@ -32,7 +46,25 @@ export declare const buildingResponse: (request: Request, startedAt: number) =>
|
|
|
32
46
|
* `networking` plugin: any `Bun.serve` that targets the placeholder's
|
|
33
47
|
* port first releases it. Installed once per process by the bootstrap. */
|
|
34
48
|
export declare const installEarlyListenerServeGuard: (port: number) => void;
|
|
49
|
+
/** Defensive hand-off for the parent-owned path: any `Bun.serve` that
|
|
50
|
+
* targets the dev port is bound with `reusePort` (so it can come up while
|
|
51
|
+
* the CLI's placeholder is still listening) and reports the bind back to
|
|
52
|
+
* the CLI. The `networking` plugin does both explicitly; this guard is
|
|
53
|
+
* what makes entries that call `.listen()` without it work too, mirroring
|
|
54
|
+
* `installEarlyListenerServeGuard` on the child-owned path. */
|
|
55
|
+
export declare const installParentPortHandoffGuard: (port: number) => void;
|
|
56
|
+
/** `SO_REUSEPORT` is POSIX-only; Windows has no equivalent that lets two
|
|
57
|
+
* processes share a listening socket, so the parent-side placeholder is
|
|
58
|
+
* not offered there and the child's own placeholder stays in charge. */
|
|
59
|
+
export declare const parentListenerSupported: () => boolean;
|
|
60
|
+
/** True when the CLI parent, not this process, owns the placeholder. */
|
|
61
|
+
export declare const parentOwnsDevPort: () => boolean;
|
|
35
62
|
export declare const releaseEarlyListener: () => boolean;
|
|
63
|
+
/** Tell the CLI parent that the real server is bound, so it can close its
|
|
64
|
+
* placeholder. Idempotent, and silent when there is no hand-off pipe (the
|
|
65
|
+
* bootstrap run directly, or a parent that never bound) — the CLI also
|
|
66
|
+
* releases on the ready banner, so a missed signal is not fatal. */
|
|
67
|
+
export declare const signalParentPortHandoff: (port: number) => void;
|
|
36
68
|
/** Bind the placeholder. A failed bind (the previous child's socket is
|
|
37
69
|
* still draining, or the port genuinely conflicts) is retried in the
|
|
38
70
|
* background for a few seconds and then given up on silently — the real
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EntryImport = {
|
|
2
|
+
line: number;
|
|
3
|
+
/** Why it is not deferrable, when it is not. */
|
|
4
|
+
reason: string | null;
|
|
5
|
+
specifier: string;
|
|
6
|
+
verdict: EntryImportVerdict;
|
|
7
|
+
};
|
|
8
|
+
export type EntryImportVerdict = 'deferrable' | 'side-effect import' | 'type-only' | 'used at module scope';
|
|
9
|
+
/** One verdict per top-level import (and re-export) of the entry, in source
|
|
10
|
+
* order. Pure: give it the entry's text, get the verdicts back. */
|
|
11
|
+
export declare const analyzeEntryImports: (sourceText: string, fileName: string) => EntryImport[];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type ImportCandidate = {
|
|
2
|
+
specifier: string;
|
|
3
|
+
/** Module index the specifier resolved to, or `-1` if it never loaded. */
|
|
4
|
+
target: number;
|
|
5
|
+
};
|
|
6
|
+
export type ImportSaving = {
|
|
7
|
+
/** Modules that become unreachable when this edge is removed. */
|
|
8
|
+
count: number;
|
|
9
|
+
savingMs: number;
|
|
10
|
+
specifier: string;
|
|
11
|
+
target: number;
|
|
12
|
+
};
|
|
13
|
+
export type ImportSavings = {
|
|
14
|
+
attributedCount: number;
|
|
15
|
+
attributedMs: number;
|
|
16
|
+
candidates: ImportSaving[];
|
|
17
|
+
reachableCount: number;
|
|
18
|
+
sharedBaseCount: number;
|
|
19
|
+
sharedBaseMs: number;
|
|
20
|
+
totalMs: number;
|
|
21
|
+
};
|
|
22
|
+
export type SavingsInput = {
|
|
23
|
+
candidates: readonly ImportCandidate[];
|
|
24
|
+
edges: ReadonlyArray<readonly number[]>;
|
|
25
|
+
/** Module whose top-level imports the candidates are — the user's entry. */
|
|
26
|
+
entry: number;
|
|
27
|
+
/** Process root (the dev bootstrap), where reachability starts. */
|
|
28
|
+
root: number;
|
|
29
|
+
selfMs: readonly number[];
|
|
30
|
+
};
|
|
31
|
+
/** The modules dominated by the edge `from -> to`: reachable from the root
|
|
32
|
+
* today, unreachable once that edge is gone. */
|
|
33
|
+
export declare const dominatedByEdge: (edges: ReadonlyArray<readonly number[]>, root: number, fromIndex: number, toIndex: number, reachable?: Uint8Array) => number[];
|
|
34
|
+
/** Modules reachable from `root`, optionally with the single edge
|
|
35
|
+
* `skipFrom -> skipTo` removed. */
|
|
36
|
+
export declare const reachableFrom: (edges: ReadonlyArray<readonly number[]>, root: number, skipFrom?: number, skipTo?: number) => Uint8Array<ArrayBuffer>;
|
|
37
|
+
export declare const summarizeImportSavings: (input: SavingsInput) => ImportSavings;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type ImportCostReport = {
|
|
2
|
+
entryLabel: string;
|
|
3
|
+
/** Modules whose exit call never ran; their self time is approximate. */
|
|
4
|
+
incomplete: number;
|
|
5
|
+
/** Out-of-order exits, i.e. top-level `await` interleaving. */
|
|
6
|
+
interleaved: number;
|
|
7
|
+
/** The entry's own body: everything it does after its imports, including
|
|
8
|
+
* the `prepare()` the framework's boot build runs inside. */
|
|
9
|
+
entryBodyMs: number;
|
|
10
|
+
moduleCount: number;
|
|
11
|
+
/** Time that ran outside every instrumented module: CommonJS
|
|
12
|
+
* dependencies, native modules, and the dev server's concurrent boot
|
|
13
|
+
* build. Deliberately not credited to any import. */
|
|
14
|
+
outsideMs: number;
|
|
15
|
+
/** The recorder's own read-and-rewrite time, excluded from every figure
|
|
16
|
+
* above and reported so the numbers can be sanity-checked. */
|
|
17
|
+
overheadMs: number;
|
|
18
|
+
rows: readonly ImportCostRow[];
|
|
19
|
+
sharedBaseCount: number;
|
|
20
|
+
sharedBaseMs: number;
|
|
21
|
+
totalMs: number;
|
|
22
|
+
};
|
|
23
|
+
export type ImportCostRow = {
|
|
24
|
+
count: number;
|
|
25
|
+
savingMs: number;
|
|
26
|
+
specifier: string;
|
|
27
|
+
verdict: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const formatImportCostReport: (report: ImportCostReport) => string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type ImportCostLoader = 'js' | 'jsx' | 'ts' | 'tsx';
|
|
2
|
+
/** The Bun loader to hand back with the rewritten contents. Bun infers
|
|
3
|
+
* CommonJS versus ESM from the source, so `.cjs`/`.mjs` both take `js`. */
|
|
4
|
+
export declare const importCostLoader: (path: string) => "ts" | "js" | "tsx" | "jsx";
|
|
5
|
+
export declare const instrumentModuleSource: (source: string, moduleIndex: number) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type StaticGraph = {
|
|
2
|
+
edges: number[][];
|
|
3
|
+
/** Modules that import a file this diagnostic could not instrument — a
|
|
4
|
+
* CommonJS dependency. Bun loads and parses those inside the gap that
|
|
5
|
+
* would otherwise be charged to this module, so its parse time is not
|
|
6
|
+
* its own and must not be credited to an import. */
|
|
7
|
+
hasUninstrumentedImports: Uint8Array;
|
|
8
|
+
};
|
|
9
|
+
/** Adjacency built from re-scanning every loaded module's source. */
|
|
10
|
+
export declare const buildStaticEdges: (moduleIds: readonly string[]) => StaticGraph;
|
|
11
|
+
/** One inferred edge per orphan module: the innermost module whose body was
|
|
12
|
+
* still open when the orphan started evaluating is the one that asked for it. */
|
|
13
|
+
export declare const inferDynamicEdges: (edges: ReadonlyArray<readonly number[]>, events: readonly number[], root: number) => [number, number][];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type ImportCostRecorder = {
|
|
2
|
+
/** The `.absolutejs-hmr-*` copy of the user's entry that the dev
|
|
3
|
+
* bootstrap actually imports. Set by the bootstrap. */
|
|
4
|
+
entryModule: string | null;
|
|
5
|
+
/** The developer's own server entry path, for reporting. */
|
|
6
|
+
entryOriginalModule: string | null;
|
|
7
|
+
/** Flat pairs of `code, timeMs`, where `code = moduleIndex * 4 + kind`
|
|
8
|
+
* and kind is one of `IMPORT_COST_EVENT`. Numbers, not objects: two
|
|
9
|
+
* array pushes per boundary is cheap enough to leave the timings alone. */
|
|
10
|
+
events: number[];
|
|
11
|
+
moduleIds: string[];
|
|
12
|
+
moduleIndexes: Map<string, number>;
|
|
13
|
+
/** Cleared before the report runs so the report's own imports (and any
|
|
14
|
+
* later `--hot` re-evaluation) never land in the measurement. */
|
|
15
|
+
recording: boolean;
|
|
16
|
+
/** The first module of the process — the dev bootstrap. Reachability is
|
|
17
|
+
* rooted here rather than at the user's entry so that anything the
|
|
18
|
+
* bootstrap loads on its own (the framework runtime, via the boot
|
|
19
|
+
* prebuild) is correctly seen as shared rather than as the entry's. */
|
|
20
|
+
rootModule: string | null;
|
|
21
|
+
};
|
|
22
|
+
type ImportCostEventKinds = {
|
|
23
|
+
enter: number;
|
|
24
|
+
exit: number;
|
|
25
|
+
loadEnd: number;
|
|
26
|
+
loadStart: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const IMPORT_COST_ENV = "ABSOLUTE_DEV_IMPORT_COST";
|
|
29
|
+
/** Event kinds packed into the low bits of each event code.
|
|
30
|
+
* `loadStart`/`loadEnd` bracket the plugin's own work so that reading and
|
|
31
|
+
* rewriting a module is charged to nobody, and the gap that follows — Bun
|
|
32
|
+
* parsing that module and resolving its imports — is charged to it. */
|
|
33
|
+
export declare const IMPORT_COST_EVENT: ImportCostEventKinds;
|
|
34
|
+
export declare const IMPORT_COST_EVENT_KINDS = 4;
|
|
35
|
+
export declare const ensureImportCostRecorder: () => ImportCostRecorder;
|
|
36
|
+
export declare const importCostEnabled: () => boolean;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type EsmRegions = {
|
|
2
|
+
/** Directories inside an ESM region that switch back to CommonJS. */
|
|
3
|
+
cjsPrefixes: string[];
|
|
4
|
+
/** Directories whose subtree is ESM. */
|
|
5
|
+
esmPrefixes: string[];
|
|
6
|
+
};
|
|
7
|
+
/** The ESM regions of an app's installed dependencies. */
|
|
8
|
+
export declare const esmRegions: (root: string) => EsmRegions;
|
|
9
|
+
/** The `onLoad` filter: app sources, `.mjs`, and files in ESM regions. */
|
|
10
|
+
export declare const instrumentableFilter: (regions: EsmRegions) => RegExp;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SelfTimes = {
|
|
2
|
+
evalMs: number[];
|
|
3
|
+
/** Timestamp of each module's first enter, or `NaN` if it never ran. */
|
|
4
|
+
firstEnterMs: number[];
|
|
5
|
+
incomplete: number[];
|
|
6
|
+
interleaved: number;
|
|
7
|
+
/** Time spent inside the plugin's own read-and-rewrite, charged to nobody. */
|
|
8
|
+
overheadMs: number;
|
|
9
|
+
/** Time with no module open and nothing being parsed: uninstrumented
|
|
10
|
+
* CommonJS dependencies, native modules, and the dev server's own
|
|
11
|
+
* concurrent work. Deliberately credited to no import. */
|
|
12
|
+
unownedMs: number;
|
|
13
|
+
parseMs: number[];
|
|
14
|
+
/** Modules' own parse plus evaluation, exclusive of their children. */
|
|
15
|
+
selfMs: number[];
|
|
16
|
+
};
|
|
17
|
+
export declare const computeSelfTimes: (events: readonly number[], moduleCount: number) => SelfTimes;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { reportImportCost } from './importCost/report';
|
package/dist/types/globals.d.ts
CHANGED
|
@@ -9,6 +9,16 @@ declare global {
|
|
|
9
9
|
* watchers and can observe entry/configuration edits. */
|
|
10
10
|
var __absoluteEntryWatcherReady: boolean | undefined;
|
|
11
11
|
var __absoluteEntryCopies: Set<string> | undefined;
|
|
12
|
+
/** Import-cost diagnostic (`ABSOLUTE_DEV_IMPORT_COST=1`). The recorder is
|
|
13
|
+
* filled by the preloaded `onLoad` plugin, read by the report, and
|
|
14
|
+
* written to by the dev bootstrap — three separate bundles, so it lives
|
|
15
|
+
* here rather than in module state. Stays unset unless the flag is on. */
|
|
16
|
+
var __absoluteImportCost:
|
|
17
|
+
| import('../src/dev/importCost/recorder').ImportCostRecorder
|
|
18
|
+
| undefined;
|
|
19
|
+
var __absoluteImportCostEnter: ((moduleIndex: number) => void) | undefined;
|
|
20
|
+
var __absoluteImportCostExit: ((moduleIndex: number) => void) | undefined;
|
|
21
|
+
var __absoluteImportCostReport: (() => Promise<void>) | undefined;
|
|
12
22
|
var __absoluteEntryBootstrapSequence: number | undefined;
|
|
13
23
|
var __absoluteEntryCleanupRegistered: boolean | undefined;
|
|
14
24
|
var __absoluteEntryWatcherStarted: boolean | undefined;
|
|
@@ -53,6 +63,11 @@ declare global {
|
|
|
53
63
|
| import('../src/dev/earlyListener').EarlyListener
|
|
54
64
|
| undefined;
|
|
55
65
|
var __absoluteEarlyListenerServeGuard: boolean | undefined;
|
|
66
|
+
/** Parent-owned hand-off (see `src/dev/earlyListener.ts`): the CLI holds
|
|
67
|
+
* the "Building…" placeholder, so this child skips its own, binds the
|
|
68
|
+
* real server with `reusePort` and reports the bind back exactly once. */
|
|
69
|
+
var __absoluteParentPortHandoffGuard: boolean | undefined;
|
|
70
|
+
var __absoluteParentHandoffSignalled: boolean | undefined;
|
|
56
71
|
/** Label of the boot step currently running (shown on the placeholder
|
|
57
72
|
* page). See `src/dev/bootLifecycle.ts`. */
|
|
58
73
|
var __absoluteBootPhase: string | undefined;
|
package/package.json
CHANGED
|
@@ -300,12 +300,12 @@
|
|
|
300
300
|
"main": "./dist/index.js",
|
|
301
301
|
"name": "@absolutejs/absolute",
|
|
302
302
|
"optionalDependencies": {
|
|
303
|
-
"@absolutejs/native-darwin-arm64": "0.20.0-beta.
|
|
304
|
-
"@absolutejs/native-darwin-x64": "0.20.0-beta.
|
|
305
|
-
"@absolutejs/native-linux-arm64": "0.20.0-beta.
|
|
306
|
-
"@absolutejs/native-linux-x64": "0.20.0-beta.
|
|
307
|
-
"@absolutejs/native-windows-arm64": "0.20.0-beta.
|
|
308
|
-
"@absolutejs/native-windows-x64": "0.20.0-beta.
|
|
303
|
+
"@absolutejs/native-darwin-arm64": "0.20.0-beta.73",
|
|
304
|
+
"@absolutejs/native-darwin-x64": "0.20.0-beta.73",
|
|
305
|
+
"@absolutejs/native-linux-arm64": "0.20.0-beta.73",
|
|
306
|
+
"@absolutejs/native-linux-x64": "0.20.0-beta.73",
|
|
307
|
+
"@absolutejs/native-windows-arm64": "0.20.0-beta.73",
|
|
308
|
+
"@absolutejs/native-windows-x64": "0.20.0-beta.73"
|
|
309
309
|
},
|
|
310
310
|
"overrides": {
|
|
311
311
|
"@sinclair/typebox": "0.34.52",
|
|
@@ -525,7 +525,7 @@
|
|
|
525
525
|
]
|
|
526
526
|
}
|
|
527
527
|
},
|
|
528
|
-
"version": "0.20.0-beta.
|
|
528
|
+
"version": "0.20.0-beta.73",
|
|
529
529
|
"workspaces": [
|
|
530
530
|
"tests/fixtures/*",
|
|
531
531
|
"tests/fixtures/_packages/*"
|