vite-devtools-svelte 0.5.0 → 0.6.1
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 +17 -5
- package/dist/analyzers/api.d.ts +17 -4
- package/dist/analyzers/assets.d.ts +0 -1
- package/dist/analyzers/build.d.ts +7 -1
- package/dist/analyzers/html.d.ts +24 -0
- package/dist/analyzers/http.d.ts +9 -0
- package/dist/analyzers/module-graph.d.ts +9 -0
- package/dist/analyzers/og.d.ts +18 -4
- package/dist/analyzers/project.d.ts +1 -0
- package/dist/analyzers/routes.d.ts +22 -1
- package/dist/analyzers/script.d.ts +26 -0
- package/dist/analyzers/source.d.ts +8 -3
- package/dist/analyzers/text.d.ts +6 -0
- package/dist/client/assets/ApiPlayground-r3PMCbhw.js +3 -0
- package/dist/client/assets/Assets-F6ySiRNw.js +1 -0
- package/dist/client/assets/BuildAnalysis-Ci5Or0e4.js +1 -0
- package/dist/client/assets/CaptureNotice-DNYJjRjY.js +1 -0
- package/dist/client/assets/{Components-Co50xTrv.css → Components-DcHDCSmh.css} +1 -1
- package/dist/client/assets/Components-DzrFq-Jl.js +2 -0
- package/dist/client/assets/DataTable-C8wIHfdk.js +1 -0
- package/dist/client/assets/DataTable-gMBzprA7.css +1 -0
- package/dist/client/assets/ErrorDashboard-DvBrkCGu.js +1 -0
- package/dist/client/assets/FpsMonitor-Bot5x4nP.js +1 -0
- package/dist/client/assets/FpsMonitor-D0MLqumc.css +1 -0
- package/dist/client/assets/Inspect-TF2sVdn4.js +4 -0
- package/dist/client/assets/Inspector-pD5_jg0-.js +1 -0
- package/dist/client/assets/LiveControls-BDWnVlkm.js +1 -0
- package/dist/client/assets/LoadProfiler-9jiBcPzy.css +1 -0
- package/dist/client/assets/LoadProfiler-RcwiKanZ.js +1 -0
- package/dist/client/assets/ModuleGraph-BscNTo-U.js +1 -0
- package/dist/client/assets/OGPreview-Ca39RUrW.js +1 -0
- package/dist/client/assets/Overview-CNCVS-EJ.js +1 -0
- package/dist/client/assets/Panel-BoUvB1nh.js +1 -0
- package/dist/client/assets/Panel-b1jDvzob.css +1 -0
- package/dist/client/assets/ReactiveGraph-BInCBdAu.css +1 -0
- package/dist/client/assets/ReactiveGraph-BmQbARuQ.js +17 -0
- package/dist/client/assets/RefreshButton-QYzgSJG9.js +1 -0
- package/dist/client/assets/RenderProfiler-Brp8i8K4.js +1 -0
- package/dist/client/assets/RenderProfiler-C0XQZUzw.css +1 -0
- package/dist/client/assets/ResourceEmpty-BBhK6GZB.js +1 -0
- package/dist/client/assets/Routes-BS5YDx3C.js +1 -0
- package/dist/client/assets/SearchField-C1RVVJht.js +1 -0
- package/dist/client/assets/Segmented-CK2euuus.js +1 -0
- package/dist/client/assets/SplitView-D7jY4n9A.js +1 -0
- package/dist/client/assets/StatList-Cd2sByRK.js +1 -0
- package/dist/client/assets/StatList-CwVfs0x8.css +1 -0
- package/dist/client/assets/StateTimeline-CaYBN88_.js +1 -0
- package/dist/client/assets/TreeView-T5wWFSLQ.js +1 -0
- package/dist/client/assets/VirtualList-CLxNqdaN.js +1 -0
- package/dist/client/assets/browser-agent-rpc-BXhoSh1z-DrvKG05N.js +1 -0
- package/dist/client/assets/capture.svelte-CetYVdiG.js +1 -0
- package/dist/client/assets/collections-BtFss6Lo.js +1 -0
- package/dist/client/assets/index-BBFupqc_.js +3 -0
- package/dist/client/assets/index-C_6yCKMs.css +1 -0
- package/dist/client/assets/kind-options-BLIV2wQY.js +1 -0
- package/dist/client/assets/nanoid-Cya-tyvy.js +1 -0
- package/dist/client/assets/reactive-BQ_s2f5H.js +1 -0
- package/dist/client/assets/reactive-selection.svelte-DI6qEBmx.js +1 -0
- package/dist/client/assets/resource-f-V9vBwK.css +1 -0
- package/dist/client/assets/resource.svelte-GBY8qvgR.js +5 -0
- package/dist/client/assets/versions-Dmo1-Hsc.js +1 -0
- package/dist/client/index.html +5 -2
- package/dist/index.mjs +2464 -1951
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/http.d.ts +24 -0
- package/dist/mcp/issues.d.ts +10 -6
- package/dist/mcp/server.d.ts +6 -17
- package/dist/mcp/sessions.d.ts +27 -17
- package/dist/mcp/stats.d.ts +13 -0
- package/dist/plugin.d.ts +14 -22
- package/dist/runtime/ids.d.ts +3 -0
- package/dist/runtime/index.d.ts +18 -0
- package/dist/runtime/transform.d.ts +22 -0
- package/dist/{collector.d.ts → server/collector.d.ts} +59 -119
- package/dist/server/compiler-warnings.d.ts +13 -0
- package/dist/{devframe.d.ts → server/devframe.d.ts} +11 -11
- package/dist/server/load-profile.d.ts +12 -0
- package/dist/{mount.d.ts → server/mount.d.ts} +6 -9
- package/dist/server/payload.d.ts +11 -0
- package/dist/server/reactive.d.ts +30 -0
- package/dist/server/ring.d.ts +11 -0
- package/dist/{security.d.ts → server/security.d.ts} +13 -3
- package/dist/server/state-timeline.d.ts +72 -0
- package/package.json +9 -4
- package/skills/vite-devtools-svelte-perf-audit/SKILL.md +2 -2
- package/skills/vite-devtools-svelte-perf-fix/SKILL.md +3 -3
- package/dist/client/assets/ApiPlayground-B28mCUlr.js +0 -3
- package/dist/client/assets/Assets-BVT22xZ3.js +0 -1
- package/dist/client/assets/Badge-BBLKgCiU.css +0 -1
- package/dist/client/assets/Badge-x4Lbd8pc.js +0 -1
- package/dist/client/assets/BuildAnalysis-BscZFEWI.js +0 -1
- package/dist/client/assets/CaptureNotice-D0u6WNeR.js +0 -1
- package/dist/client/assets/Components-sw5zdu0k.js +0 -1
- package/dist/client/assets/DataTable-CdM2Vyvn.js +0 -1
- package/dist/client/assets/DataTable-CdVIFm8T.css +0 -1
- package/dist/client/assets/ErrorDashboard-BwGMVW_-.js +0 -1
- package/dist/client/assets/FpsMonitor-BmS11Tn7.css +0 -1
- package/dist/client/assets/FpsMonitor-C0FeLiag.js +0 -1
- package/dist/client/assets/Inspect-B-jb8MaB.js +0 -3
- package/dist/client/assets/Inspector-C4wr2Zb4.js +0 -1
- package/dist/client/assets/LoadProfiler-WeP1orWN.js +0 -1
- package/dist/client/assets/LoadProfiler-cg28l5zW.css +0 -1
- package/dist/client/assets/ModuleGraph-BYer7OEL.js +0 -1
- package/dist/client/assets/OGPreview-MRxnmCmb.js +0 -1
- package/dist/client/assets/Overview-CDBKKylY.js +0 -1
- package/dist/client/assets/ReactiveGraph-Bni33DP4.js +0 -5
- package/dist/client/assets/ReactiveGraph-Bq_aP4uo.css +0 -1
- package/dist/client/assets/RenderProfiler-2rA8kCUf.js +0 -1
- package/dist/client/assets/RenderProfiler-CS1FAvX6.css +0 -1
- package/dist/client/assets/Routes-BZ5XcmEt.js +0 -1
- package/dist/client/assets/SearchField-D85HSGV_.js +0 -1
- package/dist/client/assets/Segmented-BCcIUjA2.js +0 -1
- package/dist/client/assets/SplitView-DVk1HAf9.js +0 -1
- package/dist/client/assets/StateTimeline-DjTXe54T.js +0 -1
- package/dist/client/assets/TreeView-e7dNH8HW.js +0 -1
- package/dist/client/assets/VirtualList-Ba0GhFn8.js +0 -1
- package/dist/client/assets/browser-agent-rpc-BXhoSh1z-UMmvacmP.js +0 -1
- package/dist/client/assets/capture.svelte-fve1ihQA.js +0 -1
- package/dist/client/assets/format-CW_NXiBg.js +0 -1
- package/dist/client/assets/index-CuoAAt-d.js +0 -7
- package/dist/client/assets/index-u73uo_Ri.css +0 -1
- package/dist/client/assets/reactive-BSjTkgqc.js +0 -1
- package/dist/client/assets/reactive-selection.svelte-BmjgYyWR.js +0 -1
- package/dist/client/assets/versions-zyEGB_mz.js +0 -1
- package/dist/runtime.d.ts +0 -19
- /package/dist/client/assets/{versions-CMau2xlU.css → LiveControls-CMau2xlU.css} +0 -0
- /package/dist/{template-injector.d.ts → server/template-injector.d.ts} +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { Logger } from 'vite';
|
|
4
|
+
import { Collector } from '../server/collector.js';
|
|
5
|
+
/** Dev-server path of the MCP endpoint. */
|
|
6
|
+
export declare const MCP_PATH = "/__svelte-devtools/mcp";
|
|
7
|
+
/**
|
|
8
|
+
* Whether the request's `x-svelte-devtools-token` header is exactly `token`.
|
|
9
|
+
* Constant-time for equal lengths (the length itself is not secret: every
|
|
10
|
+
* token is a UUID). A repeated header (string array) is never accepted.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isValidMcpToken(header: string | string[] | undefined, token: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Connect middleware for the MCP endpoint: lets AI agents (Claude Code etc.)
|
|
15
|
+
* read metrics and run measurement sessions over the Streamable HTTP
|
|
16
|
+
* transport. Same-origin is *not* required because MCP clients are local
|
|
17
|
+
* processes that don't run inside a browser tab; the token is the gate.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createMcpMiddleware(opts: {
|
|
20
|
+
token: string;
|
|
21
|
+
collector: Collector;
|
|
22
|
+
logger: Logger;
|
|
23
|
+
createServer: () => McpServer;
|
|
24
|
+
}): (req: IncomingMessage, res: ServerResponse) => void;
|
package/dist/mcp/issues.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RenderProfile, ReactiveGraph, LoadProfile, FpsSample } from '../types.js';
|
|
2
|
-
|
|
2
|
+
type IssueKind = 'slow-component-render' | 'over-rendered-component' | 'slow-load' | 'fps-drop' | 'effect-overconnected';
|
|
3
3
|
export interface PerformanceIssue {
|
|
4
4
|
id: string;
|
|
5
5
|
kind: IssueKind;
|
|
@@ -12,15 +12,18 @@ export interface PerformanceIssue {
|
|
|
12
12
|
suggestedTool: string;
|
|
13
13
|
}
|
|
14
14
|
export interface IssueThresholds {
|
|
15
|
-
/** Per-render time (ms) above which a component render is considered slow. */
|
|
15
|
+
/** Per-render time (ms) at or above which a component render is considered slow. */
|
|
16
16
|
avgRenderTimeMs?: number;
|
|
17
|
-
/** Render count above which a component is considered over-rendered. */
|
|
17
|
+
/** Render count at or above which a component is considered over-rendered. */
|
|
18
18
|
renderCount?: number;
|
|
19
|
-
/** Load duration (ms) above which a SvelteKit load is slow. */
|
|
19
|
+
/** Load duration (ms) at or above which a SvelteKit load is slow. */
|
|
20
20
|
loadDurationMs?: number;
|
|
21
|
-
/** FPS below which we record a drop. */
|
|
21
|
+
/** FPS strictly below which we record a drop. */
|
|
22
22
|
fpsDropThreshold?: number;
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Dependency count (incoming edges: what the effect reads) at or above
|
|
25
|
+
* which an effect is over-connected.
|
|
26
|
+
*/
|
|
24
27
|
effectMaxDeps?: number;
|
|
25
28
|
}
|
|
26
29
|
export interface IssueInputs {
|
|
@@ -59,3 +62,4 @@ export interface ReactiveProblems {
|
|
|
59
62
|
}>;
|
|
60
63
|
}
|
|
61
64
|
export declare function summarizeReactiveProblems(graph: ReactiveGraph, t?: IssueThresholds): ReactiveProblems;
|
|
65
|
+
export {};
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
3
2
|
import { RenderProfile, ReactiveGraph, LoadProfile, FpsSample, ComponentInstance, ProjectInfo, RouteInfo, ComponentRelation, CaptureInfoMap, ReactiveGraphRequest, ReactiveGraphResult, ReactiveSummary, ReactiveSummaryRequest, StateTimelineDelta } from '../types.js';
|
|
4
3
|
import { SessionStore } from './sessions.js';
|
|
5
4
|
export interface McpDeps {
|
|
6
5
|
getProject: () => ProjectInfo;
|
|
7
6
|
getRoutes: () => RouteInfo[];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* The served page load's components with its epoch, read together
|
|
11
|
-
* (`get_live_components` with `includeMeta`).
|
|
12
|
-
*/
|
|
13
|
-
getLiveSnapshot?: () => {
|
|
7
|
+
/** The served page load's components with its epoch, read together. */
|
|
8
|
+
getLiveSnapshot: () => {
|
|
14
9
|
epoch: string | null;
|
|
15
10
|
total: number;
|
|
16
11
|
components: ComponentInstance[];
|
|
@@ -22,17 +17,11 @@ export interface McpDeps {
|
|
|
22
17
|
getLoadProfiles: () => LoadProfile[];
|
|
23
18
|
getFpsSamples: () => FpsSample[];
|
|
24
19
|
sessions: SessionStore;
|
|
25
|
-
getReactiveSummary
|
|
26
|
-
getReactiveScope
|
|
27
|
-
getStateTimelineDelta
|
|
28
|
-
getCaptureInfo
|
|
20
|
+
getReactiveSummary: (req: ReactiveSummaryRequest) => Promise<ReactiveSummary>;
|
|
21
|
+
getReactiveScope: (req: ReactiveGraphRequest) => Promise<ReactiveGraphResult>;
|
|
22
|
+
getStateTimelineDelta: (since?: number) => StateTimelineDelta;
|
|
23
|
+
getCaptureInfo: () => CaptureInfoMap;
|
|
29
24
|
}
|
|
30
25
|
/** Most timeline entries one `get_state_timeline` call returns. */
|
|
31
26
|
export declare const MCP_TIMELINE_LIMIT = 500;
|
|
32
|
-
/** Default / largest JSON size of one old/new value in `get_state_timeline` output. */
|
|
33
|
-
export declare const MCP_VALUE_CHARS: {
|
|
34
|
-
readonly default: 2048;
|
|
35
|
-
readonly max: 32768;
|
|
36
|
-
};
|
|
37
27
|
export declare function buildMcpServer(deps: McpDeps): McpServer;
|
|
38
|
-
export { StreamableHTTPServerTransport };
|
package/dist/mcp/sessions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RenderProfile, LoadProfile, FpsSample } from '../types.js';
|
|
2
|
-
|
|
2
|
+
interface SessionSnapshot {
|
|
3
3
|
/** componentId -> { renderCount, totalRenderTime } at snapshot moment */
|
|
4
4
|
renderProfiles: Array<{
|
|
5
5
|
componentId: number;
|
|
@@ -47,6 +47,7 @@ export interface SessionDelta {
|
|
|
47
47
|
drops: number;
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
type Verdict = 'improved' | 'regressed' | 'unchanged';
|
|
50
51
|
export interface SessionDiff {
|
|
51
52
|
a: {
|
|
52
53
|
id: string;
|
|
@@ -60,33 +61,40 @@ export interface SessionDiff {
|
|
|
60
61
|
totalRenderTimeDeltaA: number;
|
|
61
62
|
totalRenderTimeDeltaB: number;
|
|
62
63
|
diff: number;
|
|
63
|
-
verdict:
|
|
64
|
+
verdict: Verdict;
|
|
64
65
|
};
|
|
65
66
|
load: {
|
|
66
67
|
avgA: number;
|
|
67
68
|
avgB: number;
|
|
68
69
|
diff: number;
|
|
69
|
-
verdict:
|
|
70
|
+
verdict: Verdict;
|
|
70
71
|
};
|
|
71
72
|
fps: {
|
|
72
73
|
avgA: number;
|
|
73
74
|
avgB: number;
|
|
74
75
|
diff: number;
|
|
75
|
-
verdict:
|
|
76
|
+
verdict: Verdict;
|
|
76
77
|
};
|
|
77
78
|
}
|
|
79
|
+
interface SessionSummary {
|
|
80
|
+
id: string;
|
|
81
|
+
label: string;
|
|
82
|
+
startedAt: number;
|
|
83
|
+
endedAt?: number;
|
|
84
|
+
persisted: boolean;
|
|
85
|
+
active: boolean;
|
|
86
|
+
}
|
|
78
87
|
export interface MetricGetters {
|
|
79
88
|
getRenderProfiles: () => RenderProfile[];
|
|
80
89
|
getLoadProfiles: () => LoadProfile[];
|
|
81
90
|
getFpsSamples: () => FpsSample[];
|
|
82
91
|
}
|
|
83
92
|
/**
|
|
84
|
-
*
|
|
85
|
-
* reach the store from MCP clients and become file names, so
|
|
86
|
-
* (path separators, `..`, absolute paths) is rejected before
|
|
87
|
-
* (review C-7).
|
|
93
|
+
* Whether `id` has the only shape `start()` issues: `s_<Date.now() base36>_<6
|
|
94
|
+
* hex>`. Ids reach the store from MCP clients and become file names, so
|
|
95
|
+
* anything else (path separators, `..`, absolute paths) is rejected before
|
|
96
|
+
* touching disk (review C-7).
|
|
88
97
|
*/
|
|
89
|
-
export declare const SESSION_ID_PATTERN: RegExp;
|
|
90
98
|
export declare function isSessionId(id: unknown): id is string;
|
|
91
99
|
export interface SessionStoreOptions {
|
|
92
100
|
persistDir: string;
|
|
@@ -99,25 +107,27 @@ export declare class SessionStore {
|
|
|
99
107
|
private readonly getters;
|
|
100
108
|
constructor(opts: SessionStoreOptions);
|
|
101
109
|
start(label: string, persist: boolean): SessionRecord;
|
|
110
|
+
private get activeRecord();
|
|
102
111
|
/** Called by the plugin whenever a new load profile arrives. */
|
|
103
112
|
recordLoadProfile(p: LoadProfile): void;
|
|
104
113
|
/** Called by the plugin whenever a new fps sample arrives. */
|
|
105
114
|
recordFpsSample(s: FpsSample): void;
|
|
106
115
|
end(keep: 'memory' | 'disk' | 'discard'): SessionRecord;
|
|
107
116
|
get(id: string): SessionRecord | undefined;
|
|
108
|
-
list():
|
|
109
|
-
id: string;
|
|
110
|
-
label: string;
|
|
111
|
-
startedAt: number;
|
|
112
|
-
endedAt?: number;
|
|
113
|
-
persisted: boolean;
|
|
114
|
-
active: boolean;
|
|
115
|
-
}>;
|
|
117
|
+
list(): SessionSummary[];
|
|
116
118
|
delete(id: string): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* The delta of a record in hand. `end('discard')` removes the record from
|
|
121
|
+
* the store, so end_session must not look it up again by id (it used to,
|
|
122
|
+
* and failed with "Session not found" for every discarded session).
|
|
123
|
+
*/
|
|
124
|
+
deltaOf(rec: SessionRecord): SessionDelta;
|
|
117
125
|
delta(id: string): SessionDelta;
|
|
126
|
+
private found;
|
|
118
127
|
compare(idA: string, idB: string): SessionDiff;
|
|
119
128
|
/** The session's file, guaranteed to be a direct child of `persistDir`. */
|
|
120
129
|
private pathFor;
|
|
121
130
|
private persistToDisk;
|
|
122
131
|
private loadFromDisk;
|
|
123
132
|
}
|
|
133
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Arithmetic mean, 0 for no values. */
|
|
2
|
+
export declare function avg(xs: number[]): number;
|
|
3
|
+
/** Smallest value, `fallback` for no values (reduce, not `Math.min(...)`: long lists overflow the stack). */
|
|
4
|
+
export declare function min<T>(xs: number[], fallback: T): number | T;
|
|
5
|
+
/** Largest value, `fallback` for no values. */
|
|
6
|
+
export declare function max<T>(xs: number[], fallback: T): number | T;
|
|
7
|
+
/** Rounded to 2 decimals. */
|
|
8
|
+
export declare function round(n: number): number;
|
|
9
|
+
/** Average render time of a profile, 0 when it never rendered. */
|
|
10
|
+
export declare function avgRenderTime(p: {
|
|
11
|
+
renderCount: number;
|
|
12
|
+
totalRenderTime: number;
|
|
13
|
+
}): number;
|
package/dist/plugin.d.ts
CHANGED
|
@@ -5,27 +5,19 @@ export interface SvelteDevtoolsOptions {
|
|
|
5
5
|
* @default true
|
|
6
6
|
*/
|
|
7
7
|
componentTracking?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Require the one-time code before a browser can use the standalone
|
|
10
|
+
* DevTools (`/.svelte-devtools/`). Set `false` to skip it on a trusted,
|
|
11
|
+
* single-user machine.
|
|
12
|
+
*
|
|
13
|
+
* Beware: without it, any page or device that can reach the dev server
|
|
14
|
+
* can read files in your project through the DevTools (including other
|
|
15
|
+
* devices when the dev server listens on a LAN address, `--host`).
|
|
16
|
+
* Inside the Vite DevTools dock this option has no effect: use
|
|
17
|
+
* `DevTools({ clientAuth: false })` from `@vitejs/devtools` instead.
|
|
18
|
+
* The MCP endpoint keeps its own token either way.
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
clientAuth?: boolean;
|
|
8
22
|
}
|
|
9
|
-
/**
|
|
10
|
-
* Component-tracking transform for one compiled client `.svelte` module:
|
|
11
|
-
* imports the runtime and names the file for the wrapper's next `push()`.
|
|
12
|
-
* `null` when the module has no component (`$.push(`) to track.
|
|
13
|
-
*
|
|
14
|
-
* Nothing is inserted as a new line, so every original line keeps its
|
|
15
|
-
* number (`map: null` = mappings unchanged; stack traces and the
|
|
16
|
-
* compiler's sourcemap stay aligned).
|
|
17
|
-
*/
|
|
18
|
-
export declare function injectComponentTracking(code: string, id: string): string | null;
|
|
19
|
-
/** A Svelte module (`.svelte.js` / `.svelte.ts`, runes outside components). */
|
|
20
|
-
export declare const SVELTE_MODULE_RE: RegExp;
|
|
21
|
-
/**
|
|
22
|
-
* Module-scope transform for one client Svelte module: signals created while
|
|
23
|
-
* its body runs (shared state, `export const cart = $state(...)`) are tracked
|
|
24
|
-
* under a scope named after the file. The body is bracketed by enter/leave
|
|
25
|
-
* calls; nothing is inserted as a new line. The bracket is plain JS, so it
|
|
26
|
-
* works before or after vite-plugin-svelte compiles the module (with
|
|
27
|
-
* `svelteDevtools()` listed before `sveltekit()`, a `.svelte.ts` module is
|
|
28
|
-
* compiled after this transform). `null` for a server-compiled module.
|
|
29
|
-
*/
|
|
30
|
-
export declare function injectModuleTracking(code: string, id: string): string | null;
|
|
31
23
|
export declare function svelteDevtools(options?: SvelteDevtoolsOptions): Plugin[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { RESOLVED_RUNTIME_ID, RUNTIME_MODULE_ID, WRAPPER_MODULE_ID } from './ids.js';
|
|
2
|
+
/**
|
|
3
|
+
* Wrapper code for svelte/internal/client (`./wrapper.js`).
|
|
4
|
+
*
|
|
5
|
+
* Re-exports everything from the real module, then overrides:
|
|
6
|
+
* - push/pop: component lifecycle tracking
|
|
7
|
+
* - tag/tag_proxy: named signal/proxy tracking (Svelte dev mode)
|
|
8
|
+
* - state/derived/proxy: type markers consumed by tag/tag_proxy
|
|
9
|
+
* - user_effect/user_pre_effect: effect tracking
|
|
10
|
+
* - template_effect/deferred_template_effect: render count/time profiling
|
|
11
|
+
* - each/if/key/await/component/boundary: block-callback owner attribution
|
|
12
|
+
*
|
|
13
|
+
* This single module replaces all post-compilation regex transforms
|
|
14
|
+
* for reactive tracking, making the approach Svelte-compiler-output agnostic.
|
|
15
|
+
*/
|
|
16
|
+
export declare const wrapperCode: string;
|
|
17
|
+
/** The devtools runtime (`./client.js`), installed once as `window.__SVELTE_DEVTOOLS__`. */
|
|
18
|
+
export declare const runtimeCode: string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component-tracking transform for one compiled client `.svelte` module:
|
|
3
|
+
* imports the runtime and names the file for the wrapper's next `push()`.
|
|
4
|
+
* `null` when the module has no component (`$.push($$props`) to track.
|
|
5
|
+
*
|
|
6
|
+
* Nothing is inserted as a new line, so every original line keeps its
|
|
7
|
+
* number (`map: null` = mappings unchanged; stack traces and the
|
|
8
|
+
* compiler's sourcemap stay aligned).
|
|
9
|
+
*/
|
|
10
|
+
export declare function injectComponentTracking(code: string, id: string): string | null;
|
|
11
|
+
/** A Svelte module (`.svelte.js` / `.svelte.ts`, runes outside components); `file` has no query. */
|
|
12
|
+
export declare function isSvelteModule(file: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Module-scope transform for one client Svelte module: signals created while
|
|
15
|
+
* its body runs (shared state, `export const cart = $state(...)`) are tracked
|
|
16
|
+
* under a scope named after the file. The body is bracketed by enter/leave
|
|
17
|
+
* calls; nothing is inserted as a new line. The bracket is plain JS, so it
|
|
18
|
+
* works before or after vite-plugin-svelte compiles the module (with
|
|
19
|
+
* `svelteDevtools()` listed before `sveltekit()`, a `.svelte.ts` module is
|
|
20
|
+
* compiled after this transform). `null` for a server-compiled module.
|
|
21
|
+
*/
|
|
22
|
+
export declare function injectModuleTracking(code: string, id: string): string | null;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { CaptureInfoMap, CompilerWarning, ComponentInstance, FpsSample, LoadProfile,
|
|
1
|
+
import { CaptureInfoMap, CompilerWarning, ComponentInstance, FpsSample, LoadProfile, ReactiveGraphRequest, ReactiveGraphResult, ReactiveSummary, ReactiveSummaryRequest, RenderProfile, RuntimeError, StateChange, StateTimelineDelta, StateTimelineEntry, DatasetVersions } from '../types.js';
|
|
2
|
+
import { Payload } from './payload.js';
|
|
3
|
+
import { TimelinePush } from './state-timeline.js';
|
|
4
|
+
export { STATE_TIMELINE_BYTES } from './state-timeline.js';
|
|
2
5
|
export declare const LIMITS: {
|
|
3
6
|
readonly liveComponents: 50000;
|
|
4
7
|
readonly renderProfiles: 5000;
|
|
@@ -14,9 +17,8 @@ export declare const LIMITS: {
|
|
|
14
17
|
export declare const RUNTIME_REQUEST_TIMEOUT = 1000;
|
|
15
18
|
/** A pull answered within this window is reused instead of asking the runtime again. */
|
|
16
19
|
export declare const PULL_FRESHNESS = 1000;
|
|
17
|
-
/**
|
|
18
|
-
export declare const
|
|
19
|
-
export type DatasetKey = keyof DatasetVersions;
|
|
20
|
+
/** A consumer (DevTools UI tab, MCP agent) counts as watching until its lease expires. */
|
|
21
|
+
export declare const LEASE_TTL = 15000;
|
|
20
22
|
/** App page loads (tabs / reloads) whose component tree + profiles are kept, LRU. */
|
|
21
23
|
export declare const MAX_EPOCHS = 4;
|
|
22
24
|
/** Hot-channel event names shared with `runtime.ts` (stable contract, see docs/devframe-migration.md §6). */
|
|
@@ -38,23 +40,13 @@ export declare const HOT_EVENTS: {
|
|
|
38
40
|
/** server → runtime(s): `{ active: boolean }` — whether any consumer is watching. */
|
|
39
41
|
readonly subscription: "svelte-devtools:subscription";
|
|
40
42
|
};
|
|
41
|
-
/** Defaults and bounds for `get-reactive-summary` (§6.7 I). */
|
|
42
|
-
export declare const SUMMARY_DEFAULTS: {
|
|
43
|
-
readonly topK: 50;
|
|
44
|
-
readonly maxTopK: 200;
|
|
45
|
-
readonly windowMs: 10000;
|
|
46
|
-
readonly minWindowMs: 1000;
|
|
47
|
-
readonly maxWindowMs: 60000;
|
|
48
|
-
};
|
|
49
|
-
/** A consumer (DevTools UI tab, MCP agent) counts as watching until its lease expires. */
|
|
50
|
-
export declare const LEASE_TTL = 15000;
|
|
51
43
|
export interface HotClient {
|
|
52
44
|
send(event: string, payload: unknown): void;
|
|
53
45
|
}
|
|
54
46
|
export interface HotChannel {
|
|
55
47
|
send(event: string, payload: unknown): void;
|
|
56
|
-
on(event: string, listener: (payload:
|
|
57
|
-
off?(event: string, listener: (payload:
|
|
48
|
+
on(event: string, listener: (payload: unknown, client: HotClient) => void): void;
|
|
49
|
+
off?(event: string, listener: (payload: unknown, client: HotClient) => void): void;
|
|
58
50
|
}
|
|
59
51
|
export interface CollectorHooks {
|
|
60
52
|
onFpsSample?: (sample: FpsSample) => void;
|
|
@@ -66,49 +58,35 @@ export interface CollectorHooks {
|
|
|
66
58
|
* feeds it, the devframe RPC layer and the MCP server read from it.
|
|
67
59
|
*/
|
|
68
60
|
export declare class Collector {
|
|
69
|
-
private readonly hooks;
|
|
70
61
|
private epochs;
|
|
71
62
|
private servedEpoch;
|
|
72
63
|
private liveCache;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
64
|
+
/** Epochs we asked for a full snapshot (delta without a base); answered once per epoch. */
|
|
65
|
+
private resyncRequested;
|
|
66
|
+
private readonly fps;
|
|
67
|
+
private readonly errors;
|
|
68
|
+
private readonly loads;
|
|
69
|
+
private readonly warnings;
|
|
70
|
+
private readonly timeline;
|
|
78
71
|
readonly versions: DatasetVersions;
|
|
79
|
-
private bump;
|
|
80
|
-
private timeline;
|
|
81
|
-
/** Parallel to `timeline`: JSON size and source epoch (app page load) of each entry. */
|
|
82
|
-
private timelineSizes;
|
|
83
|
-
private timelineEpochs;
|
|
84
|
-
private timelineBytes;
|
|
85
|
-
/** Newest seq issued by this collector (= the current cursor). */
|
|
86
|
-
private timelineSeq;
|
|
87
|
-
/** Cursor value at the last removal; older cursors must start over. */
|
|
88
|
-
private timelineResetAt;
|
|
89
|
-
/** Seq of the newest entry trimmed by the caps; cursors below it missed entries. */
|
|
90
|
-
private timelineTrimmedAt;
|
|
91
|
-
private lastPull;
|
|
92
|
-
private inflight;
|
|
93
72
|
private pulls;
|
|
94
73
|
private pullCache;
|
|
95
74
|
private pullInflight;
|
|
96
75
|
private requestSeq;
|
|
97
76
|
/** The most recent graph reply, for capture info. */
|
|
98
77
|
private lastGraph;
|
|
99
|
-
private
|
|
100
|
-
|
|
101
|
-
private
|
|
102
|
-
private timelineTooLarge;
|
|
103
|
-
private received;
|
|
78
|
+
private lastTimelinePull;
|
|
79
|
+
private timelineInflight;
|
|
80
|
+
private timelineResolvers;
|
|
104
81
|
private hot;
|
|
105
82
|
private detachHot;
|
|
106
83
|
private leases;
|
|
107
84
|
private snapshotWaiters;
|
|
108
85
|
private active;
|
|
109
86
|
private sweepTimer;
|
|
110
|
-
private
|
|
87
|
+
private readonly hooks;
|
|
111
88
|
constructor(hooks?: CollectorHooks);
|
|
89
|
+
private bump;
|
|
112
90
|
/**
|
|
113
91
|
* Subscribe to the runtime's hot-channel events. Re-attaching (dev server
|
|
114
92
|
* restart) detaches the previous channel first so listeners never pile up.
|
|
@@ -120,8 +98,12 @@ export declare class Collector {
|
|
|
120
98
|
active: boolean;
|
|
121
99
|
componentDeltas: true;
|
|
122
100
|
};
|
|
123
|
-
|
|
124
|
-
|
|
101
|
+
get fpsSamples(): FpsSample[];
|
|
102
|
+
get runtimeErrors(): RuntimeError[];
|
|
103
|
+
get loadProfiles(): LoadProfile[];
|
|
104
|
+
get compilerWarnings(): CompilerWarning[];
|
|
105
|
+
/** The server-side timeline (all tracked epochs, oldest first). */
|
|
106
|
+
get stateTimeline(): StateTimelineEntry[];
|
|
125
107
|
/** Components of the served epoch, parents first, capped at {@link LIMITS.liveComponents}. */
|
|
126
108
|
get liveComponents(): ComponentInstance[];
|
|
127
109
|
/**
|
|
@@ -155,9 +137,10 @@ export declare class Collector {
|
|
|
155
137
|
/**
|
|
156
138
|
* Mark `id` as watching for `ttl` ms (renewed by heartbeats). The first
|
|
157
139
|
* lease activates the runtime's polling/FPS sampling, the last expiry or
|
|
158
|
-
* release pauses it.
|
|
140
|
+
* release pauses it. Returns whether this call activated it.
|
|
159
141
|
*/
|
|
160
142
|
lease(id: string, ttl?: number): boolean;
|
|
143
|
+
release(id: string): void;
|
|
161
144
|
/**
|
|
162
145
|
* Resolve once the runtime has sent its activation snapshot (components,
|
|
163
146
|
* profiles, then a `reset: true` timeline — the last part) or after
|
|
@@ -165,7 +148,6 @@ export declare class Collector {
|
|
|
165
148
|
* the stale pre-activation state.
|
|
166
149
|
*/
|
|
167
150
|
waitForSnapshot(timeout: number): Promise<void>;
|
|
168
|
-
release(id: string): void;
|
|
169
151
|
private updateSubscription;
|
|
170
152
|
/**
|
|
171
153
|
* Full form `{ epoch?, reset?, components }` replaces the epoch's tree;
|
|
@@ -175,56 +157,30 @@ export declare class Collector {
|
|
|
175
157
|
* resync. Entries stay in registration order (parents first); an instance
|
|
176
158
|
* is stored only while its parent is and the cap allows, otherwise only its
|
|
177
159
|
* id is tracked, so the stored part is always a rooted, orphan-free tree.
|
|
160
|
+
* Entries that are not objects with a numeric `id` are ignored.
|
|
178
161
|
*/
|
|
179
|
-
ingestComponents(data:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
162
|
+
ingestComponents(data: Payload | undefined, client?: HotClient): void;
|
|
163
|
+
ingestProfiles(data?: Payload): void;
|
|
164
|
+
ingestStateTimeline(data: TimelinePush | undefined): void;
|
|
165
|
+
ingestFps(sample: FpsSample): void;
|
|
166
|
+
ingestRuntimeError(error: RuntimeError): void;
|
|
167
|
+
recordLoadProfile(profile: LoadProfile): void;
|
|
168
|
+
/**
|
|
169
|
+
* A warning identical to one held is not recorded again: a component is
|
|
170
|
+
* compiled once per environment (client and SSR), each time warning anew.
|
|
171
|
+
*/
|
|
172
|
+
recordCompilerWarning(warning: CompilerWarning): void;
|
|
173
|
+
clearLoadProfiles(): void;
|
|
174
|
+
clearErrors(): void;
|
|
175
|
+
clearFps(): void;
|
|
176
|
+
clearStateTimeline(): void;
|
|
177
|
+
/** Changes after `since` (a previous `cursor`), or the whole buffer when the cursor is stale. */
|
|
178
|
+
getStateTimelineDelta(since?: number): StateTimelineDelta;
|
|
190
179
|
/**
|
|
191
180
|
* What the server holds versus what was reported, per dataset (§6.7 B).
|
|
192
181
|
* `total: null` means unknown; nothing is estimated.
|
|
193
182
|
*/
|
|
194
183
|
getCaptureInfo(): CaptureInfoMap;
|
|
195
|
-
/** The server-side timeline (all tracked epochs, oldest first). */
|
|
196
|
-
get stateTimeline(): StateTimelineEntry[];
|
|
197
|
-
/**
|
|
198
|
-
* Two payload shapes (docs/devframe-migration.md §6.4):
|
|
199
|
-
* - delta: `{ epoch, changes, reset? }` — `changes` are new since the
|
|
200
|
-
* previous push from that page load (`epoch`); `reset` replaces that
|
|
201
|
-
* epoch's entries. Entries are kept per epoch, so several app tabs (or a
|
|
202
|
-
* reload) interleave instead of wiping each other.
|
|
203
|
-
* - legacy full snapshot: `{ changes }` — we append only the entries after
|
|
204
|
-
* the newest one we already hold, so clients still get deltas.
|
|
205
|
-
*/
|
|
206
|
-
ingestStateTimeline(data: {
|
|
207
|
-
changes?: unknown;
|
|
208
|
-
epoch?: unknown;
|
|
209
|
-
reset?: unknown;
|
|
210
|
-
dropped?: unknown;
|
|
211
|
-
valueTooLarge?: unknown;
|
|
212
|
-
baseline?: unknown;
|
|
213
|
-
} | undefined): void;
|
|
214
|
-
/**
|
|
215
|
-
* Add the runtime's own losses (unsent entries it evicted, §6.7 C) and
|
|
216
|
-
* too-large values to the epoch's counters. Only runtime reasons are
|
|
217
|
-
* accepted from the runtime; server reasons are counted here.
|
|
218
|
-
*/
|
|
219
|
-
private countRuntimeLosses;
|
|
220
|
-
private addDrop;
|
|
221
|
-
/** Changes after `since` (a previous `cursor`), or the whole buffer when the cursor is stale. */
|
|
222
|
-
getStateTimelineDelta(since?: number): StateTimelineDelta;
|
|
223
|
-
/** Invalidate every cursor issued so far (entries were removed, not just appended). */
|
|
224
|
-
private markTimelineReset;
|
|
225
|
-
private dropEpoch;
|
|
226
|
-
private appendTimeline;
|
|
227
|
-
private resolveSnapshotWaiters;
|
|
228
184
|
/**
|
|
229
185
|
* A graph reply. With a `requestId` (§6.7 A) it resolves only that request,
|
|
230
186
|
* and only if its epoch matches the one asked for; a reply nobody waits for
|
|
@@ -232,27 +188,11 @@ export declare class Collector {
|
|
|
232
188
|
* is a whole-app graph and answers every pending graph pull, scoped ones by
|
|
233
189
|
* filtering here.
|
|
234
190
|
*/
|
|
235
|
-
ingestReactiveGraph(data:
|
|
236
|
-
/**
|
|
237
|
-
* Shape a runtime reply into a {@link ReactiveGraphResult}: apply the
|
|
238
|
-
* collector caps (nodes, then only edges between kept nodes, then the edge
|
|
239
|
-
* cap) and report what was left out. Totals come from the runtime; an older
|
|
240
|
-
* runtime's are the counts it sent (`nodesKind: 'sent'`), or unknown when
|
|
241
|
-
* the server had to scope its whole-app graph.
|
|
242
|
-
*/
|
|
243
|
-
private normalizeGraph;
|
|
244
|
-
private storeGraph;
|
|
191
|
+
ingestReactiveGraph(data: Payload | undefined): void;
|
|
245
192
|
/** A summary reply (§6.7 I): resolves only the matching request. */
|
|
246
|
-
ingestReactiveSummary(data:
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
ingestRuntimeError(error: RuntimeError): void;
|
|
250
|
-
recordLoadProfile(profile: LoadProfile): void;
|
|
251
|
-
recordCompilerWarning(warning: CompilerWarning): void;
|
|
252
|
-
clearLoadProfiles(): void;
|
|
253
|
-
clearErrors(): void;
|
|
254
|
-
clearFps(): void;
|
|
255
|
-
clearStateTimeline(): void;
|
|
193
|
+
ingestReactiveSummary(data: Payload | undefined): void;
|
|
194
|
+
/** The pending pull `requestId` names, if the reply is of its kind and from its epoch. */
|
|
195
|
+
private matchingPull;
|
|
256
196
|
/**
|
|
257
197
|
* Ask the browser runtime for the graph of one component instance (or the
|
|
258
198
|
* whole app), built by the runtime within the caps (§6.7 A). Falls back to
|
|
@@ -268,17 +208,17 @@ export declare class Collector {
|
|
|
268
208
|
* last result for the same key is returned with `stale: true`.
|
|
269
209
|
*/
|
|
270
210
|
private keyedPull;
|
|
271
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
* Resolve a pending pull: with a fresh result (cached under its key), or
|
|
213
|
+
* with its fallback when the runtime did not answer.
|
|
214
|
+
*/
|
|
272
215
|
private settle;
|
|
273
|
-
/** Answer every pending keyed pull from its cache (or empty), marked stale. */
|
|
274
|
-
private flushPulls;
|
|
275
|
-
/** Ask the browser runtime for a fresh state timeline; falls back to the last one. */
|
|
276
|
-
requestStateTimeline(): Promise<StateChange[]>;
|
|
277
216
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
217
|
+
* Ask the browser runtime for a fresh state timeline; falls back to the
|
|
218
|
+
* last one. Concurrent callers share one in-flight pull, and a result
|
|
219
|
+
* younger than {@link PULL_FRESHNESS} is reused, so several polling clients
|
|
220
|
+
* never make the user's app rebuild the same data more than once a second.
|
|
281
221
|
*/
|
|
282
|
-
|
|
222
|
+
requestStateTimeline(): Promise<StateChange[]>;
|
|
283
223
|
private flushStateTimeline;
|
|
284
224
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { CompilerWarning } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Report every Svelte compiler warning of the app to `record`, as the
|
|
5
|
+
* compiler's structured warning (vite-plugin-svelte prints dev warnings with
|
|
6
|
+
* `console.log`, past Vite's logger). The user's `onwarn` (or the default
|
|
7
|
+
* handler) still runs, so console output is unchanged. Dependencies'
|
|
8
|
+
* warnings are skipped, as vite-plugin-svelte does in dev.
|
|
9
|
+
*
|
|
10
|
+
* Must run after vite-plugin-svelte's own `configResolved`, which creates
|
|
11
|
+
* the options (a restart creates new ones, so wrappers never stack).
|
|
12
|
+
*/
|
|
13
|
+
export declare function captureCompilerWarnings(plugins: readonly Plugin[], record: (warning: CompilerWarning) => void): void;
|