@alloy-js/core 0.23.0-dev.0 → 0.23.0-dev.8
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/CHANGELOG.md +0 -22
- package/dist/devtools/index.html +68 -0
- package/dist/src/binder.d.ts +2 -0
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +55 -12
- package/dist/src/binder.js.map +1 -1
- package/dist/src/components/AppendFile.d.ts.map +1 -1
- package/dist/src/components/AppendFile.js +14 -3
- package/dist/src/components/AppendFile.js.map +1 -1
- package/dist/src/components/Block.js +1 -1
- package/dist/src/components/Block.js.map +1 -1
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +2 -1
- package/dist/src/components/Declaration.js.map +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +4 -1
- package/dist/src/components/Scope.js.map +1 -1
- package/dist/src/components/TemplateFile.d.ts.map +1 -1
- package/dist/src/components/TemplateFile.js +18 -3
- package/dist/src/components/TemplateFile.js.map +1 -1
- package/dist/src/content-slot.d.ts.map +1 -1
- package/dist/src/content-slot.js +6 -5
- package/dist/src/content-slot.js.map +1 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +8 -1
- package/dist/src/context.js.map +1 -1
- package/dist/src/debug/cli.d.ts +6 -0
- package/dist/src/debug/cli.d.ts.map +1 -0
- package/dist/src/{debug.js → debug/cli.js} +78 -84
- package/dist/src/debug/cli.js.map +1 -0
- package/dist/src/debug/diagnostics.test.d.ts +2 -0
- package/dist/src/debug/diagnostics.test.d.ts.map +1 -0
- package/dist/src/debug/diagnostics.test.js +45 -0
- package/dist/src/debug/diagnostics.test.js.map +1 -0
- package/dist/src/debug/effects.d.ts +69 -0
- package/dist/src/debug/effects.d.ts.map +1 -0
- package/dist/src/debug/effects.js +228 -0
- package/dist/src/debug/effects.js.map +1 -0
- package/dist/src/debug/effects.test.d.ts +2 -0
- package/dist/src/debug/effects.test.d.ts.map +1 -0
- package/dist/src/debug/effects.test.js +86 -0
- package/dist/src/debug/effects.test.js.map +1 -0
- package/dist/src/debug/files.d.ts +14 -0
- package/dist/src/debug/files.d.ts.map +1 -0
- package/dist/src/debug/files.js +40 -0
- package/dist/src/debug/files.js.map +1 -0
- package/dist/src/debug/files.test.d.ts +2 -0
- package/dist/src/debug/files.test.d.ts.map +1 -0
- package/dist/src/debug/files.test.js +89 -0
- package/dist/src/debug/files.test.js.map +1 -0
- package/dist/src/debug/index.d.ts +60 -0
- package/dist/src/debug/index.d.ts.map +1 -0
- package/dist/src/debug/index.js +68 -0
- package/dist/src/debug/index.js.map +1 -0
- package/dist/src/debug/render.d.ts +57 -0
- package/dist/src/debug/render.d.ts.map +1 -0
- package/dist/src/debug/render.js +519 -0
- package/dist/src/debug/render.js.map +1 -0
- package/dist/src/debug/render.test.d.ts +2 -0
- package/dist/src/debug/render.test.d.ts.map +1 -0
- package/dist/src/debug/render.test.js +328 -0
- package/dist/src/debug/render.test.js.map +1 -0
- package/dist/src/debug/serialize.d.ts +9 -0
- package/dist/src/debug/serialize.d.ts.map +1 -0
- package/dist/src/debug/serialize.js +70 -0
- package/dist/src/debug/serialize.js.map +1 -0
- package/dist/src/debug/symbols.d.ts +9 -0
- package/dist/src/debug/symbols.d.ts.map +1 -0
- package/dist/src/debug/symbols.js +164 -0
- package/dist/src/debug/symbols.js.map +1 -0
- package/dist/src/debug/symbols.test.d.ts +2 -0
- package/dist/src/debug/symbols.test.d.ts.map +1 -0
- package/dist/src/debug/symbols.test.js +104 -0
- package/dist/src/debug/symbols.test.js.map +1 -0
- package/dist/src/debug/trace.d.ts +342 -0
- package/dist/src/debug/trace.d.ts.map +1 -0
- package/dist/src/debug/trace.js +443 -0
- package/dist/src/debug/trace.js.map +1 -0
- package/dist/src/devtools/devtools-protocol.d.ts +232 -0
- package/dist/src/devtools/devtools-protocol.d.ts.map +1 -0
- package/dist/src/devtools/devtools-protocol.js +2 -0
- package/dist/src/devtools/devtools-protocol.js.map +1 -0
- package/dist/src/devtools/devtools-server.browser.d.ts +28 -0
- package/dist/src/devtools/devtools-server.browser.d.ts.map +1 -0
- package/dist/src/devtools/devtools-server.browser.js +36 -0
- package/dist/src/devtools/devtools-server.browser.js.map +1 -0
- package/dist/src/devtools/devtools-server.d.ts +72 -0
- package/dist/src/devtools/devtools-server.d.ts.map +1 -0
- package/dist/src/devtools/devtools-server.js +256 -0
- package/dist/src/devtools/devtools-server.js.map +1 -0
- package/dist/src/devtools/devtools-transport.d.ts +23 -0
- package/dist/src/devtools/devtools-transport.d.ts.map +1 -0
- package/dist/src/devtools/devtools-transport.js +114 -0
- package/dist/src/devtools/devtools-transport.js.map +1 -0
- package/dist/src/devtools-entry.browser.d.ts +4 -0
- package/dist/src/devtools-entry.browser.d.ts.map +1 -0
- package/dist/src/devtools-entry.browser.js +2 -0
- package/dist/src/devtools-entry.browser.js.map +1 -0
- package/dist/src/devtools-entry.d.ts +4 -0
- package/dist/src/devtools-entry.d.ts.map +1 -0
- package/dist/src/devtools-entry.js +2 -0
- package/dist/src/devtools-entry.js.map +1 -0
- package/dist/src/diagnostics.d.ts +34 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +89 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/print-hook.d.ts +14 -0
- package/dist/src/print-hook.d.ts.map +1 -0
- package/dist/src/print-hook.js +10 -0
- package/dist/src/print-hook.js.map +1 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -1
- package/dist/src/reactive-union-set.js +15 -0
- package/dist/src/reactive-union-set.js.map +1 -1
- package/dist/src/reactivity.d.ts +17 -3
- package/dist/src/reactivity.d.ts.map +1 -1
- package/dist/src/reactivity.js +162 -14
- package/dist/src/reactivity.js.map +1 -1
- package/dist/src/render-stack.d.ts +29 -0
- package/dist/src/render-stack.d.ts.map +1 -0
- package/dist/src/render-stack.js +247 -0
- package/dist/src/render-stack.js.map +1 -0
- package/dist/src/render.d.ts +9 -19
- package/dist/src/render.d.ts.map +1 -1
- package/dist/src/render.js +363 -153
- package/dist/src/render.js.map +1 -1
- package/dist/src/resource.d.ts.map +1 -1
- package/dist/src/resource.js +5 -0
- package/dist/src/resource.js.map +1 -1
- package/dist/src/runtime/component.d.ts +7 -1
- package/dist/src/runtime/component.d.ts.map +1 -1
- package/dist/src/runtime/component.js +4 -1
- package/dist/src/runtime/component.js.map +1 -1
- package/dist/src/scheduler.d.ts +3 -0
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +45 -2
- package/dist/src/scheduler.js.map +1 -1
- package/dist/src/symbols/basic-symbol.d.ts.map +1 -1
- package/dist/src/symbols/basic-symbol.js +6 -1
- package/dist/src/symbols/basic-symbol.js.map +1 -1
- package/dist/src/symbols/decl.d.ts.map +1 -1
- package/dist/src/symbols/decl.js +5 -1
- package/dist/src/symbols/decl.js.map +1 -1
- package/dist/src/symbols/output-scope.d.ts +2 -1
- package/dist/src/symbols/output-scope.d.ts.map +1 -1
- package/dist/src/symbols/output-scope.js +13 -8
- package/dist/src/symbols/output-scope.js.map +1 -1
- package/dist/src/symbols/output-symbol.d.ts +1 -0
- package/dist/src/symbols/output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/output-symbol.js +23 -6
- package/dist/src/symbols/output-symbol.js.map +1 -1
- package/dist/src/symbols/symbol-flow.d.ts.map +1 -1
- package/dist/src/symbols/symbol-flow.js +22 -6
- package/dist/src/symbols/symbol-flow.js.map +1 -1
- package/dist/src/symbols/symbol-slot.d.ts.map +1 -1
- package/dist/src/symbols/symbol-slot.js +15 -0
- package/dist/src/symbols/symbol-slot.js.map +1 -1
- package/dist/src/symbols/symbol-slot.test.d.ts +2 -0
- package/dist/src/symbols/symbol-slot.test.d.ts.map +1 -0
- package/dist/src/symbols/symbol-slot.test.js +35 -0
- package/dist/src/symbols/symbol-slot.test.js.map +1 -0
- package/dist/src/symbols/symbol-table.d.ts.map +1 -1
- package/dist/src/symbols/symbol-table.js +6 -5
- package/dist/src/symbols/symbol-table.js.map +1 -1
- package/dist/src/trace.d.ts +2 -0
- package/dist/src/trace.d.ts.map +1 -0
- package/dist/src/trace.js +2 -0
- package/dist/src/trace.js.map +1 -0
- package/dist/src/tracer.d.ts +2 -228
- package/dist/src/tracer.d.ts.map +1 -1
- package/dist/src/tracer.js +5 -298
- package/dist/src/tracer.js.map +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +5 -0
- package/dist/src/utils.js.map +1 -1
- package/dist/test/components/append-file.test.d.ts.map +1 -1
- package/dist/test/components/append-file.test.js +18 -10
- package/dist/test/components/append-file.test.js.map +1 -1
- package/dist/test/components/template-file.test.d.ts.map +1 -1
- package/dist/test/components/template-file.test.js +6 -4
- package/dist/test/components/template-file.test.js.map +1 -1
- package/dist/test/rendering/basic.test.js +3 -0
- package/dist/test/rendering/basic.test.js.map +1 -1
- package/dist/test/rendering/print-render-stack.test.d.ts +2 -0
- package/dist/test/rendering/print-render-stack.test.d.ts.map +1 -0
- package/dist/test/rendering/print-render-stack.test.js +207 -0
- package/dist/test/rendering/print-render-stack.test.js.map +1 -0
- package/dist/testing/create-test-wrapper.d.ts +1 -1
- package/dist/testing/create-test-wrapper.d.ts.map +1 -1
- package/dist/testing/create-test-wrapper.js +1 -1
- package/dist/testing/create-test-wrapper.js.map +1 -1
- package/dist/testing/devtools-utils.d.ts +26 -0
- package/dist/testing/devtools-utils.d.ts.map +1 -0
- package/dist/testing/devtools-utils.js +140 -0
- package/dist/testing/devtools-utils.js.map +1 -0
- package/dist/testing/extend-expect.d.ts.map +1 -1
- package/dist/testing/extend-expect.js +63 -1
- package/dist/testing/extend-expect.js.map +1 -1
- package/dist/testing/render.d.ts +2 -2
- package/dist/testing/render.d.ts.map +1 -1
- package/dist/testing/render.js +2 -2
- package/dist/testing/render.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -7
- package/scripts/copy-devtools-ui.mjs +26 -0
- package/src/binder.ts +71 -16
- package/src/components/AppendFile.tsx +14 -9
- package/src/components/Block.tsx +1 -1
- package/src/components/Declaration.tsx +2 -1
- package/src/components/Scope.tsx +4 -1
- package/src/components/TemplateFile.tsx +18 -9
- package/src/content-slot.tsx +6 -6
- package/src/context.ts +15 -4
- package/src/{debug.ts → debug/cli.ts} +112 -127
- package/src/debug/diagnostics.test.tsx +55 -0
- package/src/debug/effects.test.tsx +96 -0
- package/src/debug/effects.ts +313 -0
- package/src/debug/files.test.tsx +96 -0
- package/src/debug/files.ts +40 -0
- package/src/debug/index.ts +126 -0
- package/src/debug/render.test.tsx +379 -0
- package/src/debug/render.ts +639 -0
- package/src/debug/serialize.ts +85 -0
- package/src/debug/symbols.test.tsx +106 -0
- package/src/debug/symbols.ts +230 -0
- package/src/debug/trace.ts +312 -0
- package/src/devtools/devtools-protocol.ts +312 -0
- package/src/devtools/devtools-server.browser.ts +71 -0
- package/src/devtools/devtools-server.ts +290 -0
- package/src/devtools/devtools-transport.ts +154 -0
- package/src/devtools-entry.browser.ts +52 -0
- package/src/devtools-entry.ts +54 -0
- package/src/diagnostics.ts +141 -0
- package/src/index.ts +2 -6
- package/src/print-hook.ts +22 -0
- package/src/reactive-union-set.ts +71 -41
- package/src/reactivity.ts +206 -23
- package/src/render-stack.ts +289 -0
- package/src/render.ts +464 -212
- package/src/resource.ts +28 -19
- package/src/runtime/component.ts +11 -0
- package/src/scheduler.ts +55 -3
- package/src/symbols/basic-symbol.ts +6 -1
- package/src/symbols/decl.ts +5 -1
- package/src/symbols/output-scope.ts +21 -12
- package/src/symbols/output-symbol.ts +33 -12
- package/src/symbols/symbol-flow.ts +68 -37
- package/src/symbols/symbol-slot.test.tsx +41 -0
- package/src/symbols/symbol-slot.tsx +47 -20
- package/src/symbols/symbol-table.ts +6 -10
- package/src/trace.ts +1 -0
- package/src/tracer.ts +13 -242
- package/src/utils.tsx +22 -13
- package/temp/api.json +1811 -277
- package/test/components/append-file.test.tsx +36 -29
- package/test/components/template-file.test.tsx +11 -11
- package/test/rendering/basic.test.tsx +4 -0
- package/test/rendering/print-render-stack.test.tsx +244 -0
- package/testing/create-test-wrapper.tsx +1 -1
- package/testing/devtools-utils.ts +203 -0
- package/testing/extend-expect.ts +89 -0
- package/testing/render.ts +2 -2
- package/testing/vitest.d.ts +9 -0
- package/dist/src/debug.d.ts +0 -15
- package/dist/src/debug.d.ts.map +0 -1
- package/dist/src/debug.js.map +0 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket transport for the Alloy devtools server.
|
|
3
|
+
*
|
|
4
|
+
* Handles HTTP serving of the devtools UI and WebSocket connection management.
|
|
5
|
+
* This module is concerned only with the transport layer — session lifecycle
|
|
6
|
+
* is managed by devtools-server.ts.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import {
|
|
10
|
+
createServer as createHttpServer,
|
|
11
|
+
type IncomingMessage,
|
|
12
|
+
type ServerResponse,
|
|
13
|
+
} from "node:http";
|
|
14
|
+
|
|
15
|
+
export interface DevtoolsTransportState {
|
|
16
|
+
port: number;
|
|
17
|
+
connected: boolean;
|
|
18
|
+
clients: Set<any>;
|
|
19
|
+
httpServer: ReturnType<typeof createHttpServer>;
|
|
20
|
+
ready: Promise<void>;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let cachedAlloyVersion: string | null = null;
|
|
25
|
+
|
|
26
|
+
/** Read the @alloy-js/core package version, cached after first call. */
|
|
27
|
+
export function getAlloyVersion(): string {
|
|
28
|
+
if (cachedAlloyVersion) return cachedAlloyVersion;
|
|
29
|
+
try {
|
|
30
|
+
const pkgUrl = new URL("../../../package.json", import.meta.url);
|
|
31
|
+
const pkg = JSON.parse(readFileSync(pkgUrl, "utf-8")) as {
|
|
32
|
+
version?: string;
|
|
33
|
+
};
|
|
34
|
+
cachedAlloyVersion = pkg.version ?? "0.0.0";
|
|
35
|
+
} catch {
|
|
36
|
+
cachedAlloyVersion = "0.0.0";
|
|
37
|
+
}
|
|
38
|
+
return cachedAlloyVersion;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Attempt to load the devtools UI HTML from known candidate paths. */
|
|
42
|
+
function loadDevtoolsUiHtml(): string | null {
|
|
43
|
+
const candidates = [
|
|
44
|
+
new URL("../../dist/devtools/index.html", import.meta.url),
|
|
45
|
+
new URL("../../devtools/index.html", import.meta.url),
|
|
46
|
+
new URL("../../../devtools/dist/index.html", import.meta.url),
|
|
47
|
+
];
|
|
48
|
+
for (const candidate of candidates) {
|
|
49
|
+
try {
|
|
50
|
+
return readFileSync(candidate, "utf-8");
|
|
51
|
+
} catch {
|
|
52
|
+
// try next
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface CreateTransportOptions {
|
|
59
|
+
port: number;
|
|
60
|
+
onConnection(socket: any): void;
|
|
61
|
+
onMessage(message: unknown): void;
|
|
62
|
+
onDisconnect(): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Create the HTTP + WebSocket transport. Returns when the server is listening.
|
|
67
|
+
* Only accepts one concurrent WebSocket connection.
|
|
68
|
+
*/
|
|
69
|
+
export async function createTransport(
|
|
70
|
+
options: CreateTransportOptions,
|
|
71
|
+
): Promise<DevtoolsTransportState> {
|
|
72
|
+
const { WebSocketServer } = await import("ws");
|
|
73
|
+
const devtoolsUiHtml = loadDevtoolsUiHtml();
|
|
74
|
+
|
|
75
|
+
const httpServer = createHttpServer(
|
|
76
|
+
(req: IncomingMessage, res: ServerResponse) => {
|
|
77
|
+
const url = req.url ?? "/";
|
|
78
|
+
if (url !== "/" && url !== "/index.html") {
|
|
79
|
+
res.statusCode = 404;
|
|
80
|
+
res.end("Not Found");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!devtoolsUiHtml) {
|
|
84
|
+
res.statusCode = 404;
|
|
85
|
+
res.end("Not Found");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
res.statusCode = 200;
|
|
89
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
90
|
+
res.end(devtoolsUiHtml);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
const wss = new WebSocketServer({ server: httpServer });
|
|
94
|
+
|
|
95
|
+
await new Promise<void>((resolve, reject) => {
|
|
96
|
+
httpServer.once("listening", resolve);
|
|
97
|
+
httpServer.once("error", reject);
|
|
98
|
+
httpServer.listen(options.port);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const address = httpServer.address();
|
|
102
|
+
const actualPort =
|
|
103
|
+
typeof address === "object" && address !== null ?
|
|
104
|
+
address.port
|
|
105
|
+
: options.port;
|
|
106
|
+
|
|
107
|
+
let resolveReady: (() => void) | undefined;
|
|
108
|
+
const ready = new Promise<void>((resolve) => {
|
|
109
|
+
resolveReady = resolve;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const clients = new Set<any>();
|
|
113
|
+
const state: DevtoolsTransportState = {
|
|
114
|
+
port: actualPort,
|
|
115
|
+
connected: false,
|
|
116
|
+
clients,
|
|
117
|
+
httpServer,
|
|
118
|
+
ready,
|
|
119
|
+
close: async () => {
|
|
120
|
+
await new Promise<void>((resolve) => wss.close(() => resolve()));
|
|
121
|
+
await new Promise<void>((resolve) => httpServer.close(() => resolve()));
|
|
122
|
+
clients.clear();
|
|
123
|
+
state.connected = false;
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
wss.on("connection", (socket) => {
|
|
128
|
+
if (state.connected) {
|
|
129
|
+
socket.close(1000, "Another devtools client is already connected");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
clients.add(socket);
|
|
134
|
+
state.connected = true;
|
|
135
|
+
resolveReady?.();
|
|
136
|
+
options.onConnection(socket);
|
|
137
|
+
|
|
138
|
+
socket.on("message", (data) => {
|
|
139
|
+
try {
|
|
140
|
+
options.onMessage(JSON.parse(String(data)));
|
|
141
|
+
} catch {
|
|
142
|
+
// ignore malformed messages
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
socket.on("close", () => {
|
|
147
|
+
clients.delete(socket);
|
|
148
|
+
state.connected = clients.size > 0;
|
|
149
|
+
options.onDisconnect();
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return state;
|
|
154
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
BatchMessage,
|
|
3
|
+
ClientToServerMessage,
|
|
4
|
+
DebuggerInfoMessage,
|
|
5
|
+
DiagnosticInfo,
|
|
6
|
+
DiagnosticsReportMessage,
|
|
7
|
+
DirectoryAddedMessage,
|
|
8
|
+
DirectoryRemovedMessage,
|
|
9
|
+
EffectAddedMessage,
|
|
10
|
+
EffectEdgeInfo,
|
|
11
|
+
EffectEdgeUpdatedMessage,
|
|
12
|
+
EffectInfo,
|
|
13
|
+
EffectTrackMessage,
|
|
14
|
+
EffectTriggerMessage,
|
|
15
|
+
EffectUpdatedMessage,
|
|
16
|
+
FileAddedMessage,
|
|
17
|
+
FileRemovedMessage,
|
|
18
|
+
FileUpdatedMessage,
|
|
19
|
+
FlushJobsCompleteMessage,
|
|
20
|
+
RefAddedMessage,
|
|
21
|
+
RefInfo,
|
|
22
|
+
RenderCompleteMessage,
|
|
23
|
+
RenderErrorMessage,
|
|
24
|
+
RenderErrorStackEntry,
|
|
25
|
+
RenderNodeAddedMessage,
|
|
26
|
+
RenderNodeRemovedMessage,
|
|
27
|
+
RenderNodeUpdatedMessage,
|
|
28
|
+
RenderResetMessage,
|
|
29
|
+
RenderTreeNode,
|
|
30
|
+
RerenderBreakRequestMessage,
|
|
31
|
+
RerenderRequestMessage,
|
|
32
|
+
ScopeCreateMessage,
|
|
33
|
+
ScopeDeleteMessage,
|
|
34
|
+
ScopeInfo,
|
|
35
|
+
ScopeUpdateMessage,
|
|
36
|
+
ServerToClientMessage,
|
|
37
|
+
SourceLocation,
|
|
38
|
+
SymbolCreateMessage,
|
|
39
|
+
SymbolDeleteMessage,
|
|
40
|
+
SymbolInfo,
|
|
41
|
+
SymbolUpdateMessage,
|
|
42
|
+
} from "./devtools/devtools-protocol.js";
|
|
43
|
+
export {
|
|
44
|
+
enableDevtools,
|
|
45
|
+
enableDevtoolsAndConnect,
|
|
46
|
+
resetDevtoolsServerForTests,
|
|
47
|
+
waitForDevtoolsConnection,
|
|
48
|
+
} from "./devtools/devtools-server.browser.js";
|
|
49
|
+
export type {
|
|
50
|
+
DevtoolsServerInfo,
|
|
51
|
+
EnableDevtoolsOptions,
|
|
52
|
+
} from "./devtools/devtools-server.browser.js";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
// Individual server→client message types
|
|
3
|
+
BatchMessage,
|
|
4
|
+
ClientToServerMessage,
|
|
5
|
+
DebuggerInfoMessage,
|
|
6
|
+
DiagnosticInfo,
|
|
7
|
+
DiagnosticsReportMessage,
|
|
8
|
+
DirectoryAddedMessage,
|
|
9
|
+
DirectoryRemovedMessage,
|
|
10
|
+
EffectAddedMessage,
|
|
11
|
+
EffectEdgeInfo,
|
|
12
|
+
EffectEdgeUpdatedMessage,
|
|
13
|
+
EffectInfo,
|
|
14
|
+
EffectTrackMessage,
|
|
15
|
+
EffectTriggerMessage,
|
|
16
|
+
EffectUpdatedMessage,
|
|
17
|
+
FileAddedMessage,
|
|
18
|
+
FileRemovedMessage,
|
|
19
|
+
FileUpdatedMessage,
|
|
20
|
+
FlushJobsCompleteMessage,
|
|
21
|
+
RefAddedMessage,
|
|
22
|
+
RefInfo,
|
|
23
|
+
RenderCompleteMessage,
|
|
24
|
+
RenderErrorMessage,
|
|
25
|
+
RenderErrorStackEntry,
|
|
26
|
+
RenderNodeAddedMessage,
|
|
27
|
+
RenderNodeRemovedMessage,
|
|
28
|
+
RenderNodeUpdatedMessage,
|
|
29
|
+
RenderResetMessage,
|
|
30
|
+
RenderTreeNode,
|
|
31
|
+
// Individual client→server message types
|
|
32
|
+
RerenderBreakRequestMessage,
|
|
33
|
+
RerenderRequestMessage,
|
|
34
|
+
ScopeCreateMessage,
|
|
35
|
+
ScopeDeleteMessage,
|
|
36
|
+
ScopeInfo,
|
|
37
|
+
ScopeUpdateMessage,
|
|
38
|
+
ServerToClientMessage,
|
|
39
|
+
SourceLocation,
|
|
40
|
+
SymbolCreateMessage,
|
|
41
|
+
SymbolDeleteMessage,
|
|
42
|
+
SymbolInfo,
|
|
43
|
+
SymbolUpdateMessage,
|
|
44
|
+
} from "./devtools/devtools-protocol.js";
|
|
45
|
+
export {
|
|
46
|
+
enableDevtools,
|
|
47
|
+
enableDevtoolsAndConnect,
|
|
48
|
+
resetDevtoolsServerForTests,
|
|
49
|
+
waitForDevtoolsConnection,
|
|
50
|
+
} from "./devtools/devtools-server.js";
|
|
51
|
+
export type {
|
|
52
|
+
DevtoolsServerInfo,
|
|
53
|
+
EnableDevtoolsOptions,
|
|
54
|
+
} from "./devtools/devtools-server.js";
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { getRenderNodeId } from "./debug/index.js";
|
|
2
|
+
import { broadcastDevtoolsMessage } from "./devtools/devtools-server.js";
|
|
3
|
+
import { getContext } from "./reactivity.js";
|
|
4
|
+
import { getRenderStackSnapshot } from "./render-stack.js";
|
|
5
|
+
import type { SourceLocation } from "./runtime/component.js";
|
|
6
|
+
|
|
7
|
+
export interface DiagnosticStackEntry {
|
|
8
|
+
name: string;
|
|
9
|
+
renderNodeId?: number;
|
|
10
|
+
source?: SourceLocation;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type DiagnosticSeverity = "info" | "warning" | "error";
|
|
14
|
+
|
|
15
|
+
export interface Diagnostic {
|
|
16
|
+
id: string;
|
|
17
|
+
message: string;
|
|
18
|
+
severity: DiagnosticSeverity;
|
|
19
|
+
source?: SourceLocation;
|
|
20
|
+
componentStack?: DiagnosticStackEntry[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface DiagnosticInput {
|
|
24
|
+
message: string;
|
|
25
|
+
severity?: DiagnosticSeverity;
|
|
26
|
+
source?: SourceLocation;
|
|
27
|
+
componentStack?: DiagnosticStackEntry[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DiagnosticHandle {
|
|
31
|
+
dismiss(): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class DiagnosticsCollector {
|
|
35
|
+
private entries = new Map<string, Diagnostic>();
|
|
36
|
+
private order: string[] = [];
|
|
37
|
+
|
|
38
|
+
emit(input: DiagnosticInput): DiagnosticHandle {
|
|
39
|
+
const componentStack =
|
|
40
|
+
input.componentStack ??
|
|
41
|
+
getRenderStackSnapshot().map((entry) => ({
|
|
42
|
+
name: entry.displayName,
|
|
43
|
+
renderNodeId:
|
|
44
|
+
entry.context?.meta?.renderNode ?
|
|
45
|
+
getRenderNodeId(entry.context.meta.renderNode)
|
|
46
|
+
: undefined,
|
|
47
|
+
source: entry.source,
|
|
48
|
+
}));
|
|
49
|
+
const source = input.source ?? componentStack.at(-1)?.source ?? undefined;
|
|
50
|
+
const id = `diag-${this.order.length + 1}-${Date.now()}`;
|
|
51
|
+
const diagnostic: Diagnostic = {
|
|
52
|
+
id,
|
|
53
|
+
message: input.message,
|
|
54
|
+
severity: input.severity ?? "warning",
|
|
55
|
+
source,
|
|
56
|
+
componentStack,
|
|
57
|
+
};
|
|
58
|
+
this.entries.set(id, diagnostic);
|
|
59
|
+
this.order.push(id);
|
|
60
|
+
|
|
61
|
+
// Broadcast updated diagnostics
|
|
62
|
+
this.broadcast();
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
dismiss: () => {
|
|
66
|
+
this.entries.delete(id);
|
|
67
|
+
// Broadcast updated diagnostics after dismissal
|
|
68
|
+
this.broadcast();
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getDiagnostics() {
|
|
74
|
+
return this.order
|
|
75
|
+
.map((id) => this.entries.get(id))
|
|
76
|
+
.filter((entry): entry is Diagnostic => Boolean(entry));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private broadcast() {
|
|
80
|
+
broadcastDevtoolsMessage({
|
|
81
|
+
type: "diagnostics:report",
|
|
82
|
+
diagnostics: this.getDiagnostics(),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const DIAGNOSTICS_META_KEY = "diagnostics";
|
|
88
|
+
|
|
89
|
+
export function attachDiagnosticsCollector(collector: DiagnosticsCollector) {
|
|
90
|
+
const context = getContext();
|
|
91
|
+
if (!context) return;
|
|
92
|
+
context.meta ??= {};
|
|
93
|
+
context.meta[DIAGNOSTICS_META_KEY] = collector;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getDiagnosticsCollectorFromContext():
|
|
97
|
+
| DiagnosticsCollector
|
|
98
|
+
| undefined {
|
|
99
|
+
let context = getContext();
|
|
100
|
+
while (context) {
|
|
101
|
+
const collector = context.meta?.[DIAGNOSTICS_META_KEY] as
|
|
102
|
+
| DiagnosticsCollector
|
|
103
|
+
| undefined;
|
|
104
|
+
if (collector) return collector;
|
|
105
|
+
context = context.owner;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function emitDiagnostic(input: DiagnosticInput): DiagnosticHandle {
|
|
111
|
+
const collector = getDiagnosticsCollectorFromContext();
|
|
112
|
+
if (!collector) {
|
|
113
|
+
return {
|
|
114
|
+
dismiss: () => undefined,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return collector.emit(input);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function reportDiagnostics(collector: DiagnosticsCollector) {
|
|
121
|
+
const diagnostics = collector.getDiagnostics();
|
|
122
|
+
if (diagnostics.length === 0) return;
|
|
123
|
+
|
|
124
|
+
for (const diagnostic of diagnostics) {
|
|
125
|
+
const location =
|
|
126
|
+
diagnostic.source ?
|
|
127
|
+
` (${diagnostic.source.fileName}:${diagnostic.source.lineNumber}:${diagnostic.source.columnNumber})`
|
|
128
|
+
: "";
|
|
129
|
+
const line = `${diagnostic.message}${location}`;
|
|
130
|
+
if (diagnostic.severity === "error") {
|
|
131
|
+
// eslint-disable-next-line no-console
|
|
132
|
+
console.error(line);
|
|
133
|
+
} else if (diagnostic.severity === "warning") {
|
|
134
|
+
// eslint-disable-next-line no-console
|
|
135
|
+
console.warn(line);
|
|
136
|
+
} else {
|
|
137
|
+
// eslint-disable-next-line no-console
|
|
138
|
+
console.log(line);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
export {
|
|
2
2
|
TrackOpTypes,
|
|
3
3
|
TriggerOpTypes,
|
|
4
|
-
computed,
|
|
5
4
|
isProxy,
|
|
6
5
|
isReactive,
|
|
7
6
|
isRef,
|
|
8
7
|
reactive,
|
|
9
|
-
ref,
|
|
10
8
|
shallowReactive,
|
|
11
|
-
shallowRef,
|
|
12
9
|
toRaw,
|
|
13
|
-
toRef,
|
|
14
|
-
toRefs,
|
|
15
10
|
track,
|
|
16
11
|
trigger,
|
|
17
12
|
watch,
|
|
@@ -28,6 +23,7 @@ export * from "./components/index.js";
|
|
|
28
23
|
export * from "./content-slot.js";
|
|
29
24
|
export * from "./context.js";
|
|
30
25
|
export * from "./context/index.js";
|
|
26
|
+
export * from "./diagnostics.js";
|
|
31
27
|
export * from "./library-symbol-reference.js";
|
|
32
28
|
export * from "./name-policy.js";
|
|
33
29
|
export * from "./props-combinators.js";
|
|
@@ -45,4 +41,4 @@ export * from "./symbols/symbol-flow.js";
|
|
|
45
41
|
export * from "./tap.js";
|
|
46
42
|
export * from "./utils.js";
|
|
47
43
|
export * from "./write-output.js";
|
|
48
|
-
import "./debug.js";
|
|
44
|
+
import "./debug/index.js";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Print hook types and utilities.
|
|
3
|
+
* This is a separate file to avoid circular dependencies between render.ts and debug/render.ts.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const printHookTag = Symbol();
|
|
7
|
+
|
|
8
|
+
export interface PrintHook {
|
|
9
|
+
[printHookTag]: true;
|
|
10
|
+
transform?(tree: RenderedTextTree): RenderedTextTree;
|
|
11
|
+
print?(
|
|
12
|
+
tree: RenderedTextTree,
|
|
13
|
+
print: (subtree: RenderedTextTree) => import("prettier").Doc,
|
|
14
|
+
): import("prettier").Doc;
|
|
15
|
+
subtree: RenderedTextTree;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function isPrintHook(type: unknown): type is PrintHook {
|
|
19
|
+
return typeof type === "object" && type !== null && printHookTag in type;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type RenderedTextTree = (string | RenderedTextTree | PrintHook)[];
|
|
@@ -130,27 +130,36 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
130
130
|
*/
|
|
131
131
|
const prevValues = new Map<T, T>();
|
|
132
132
|
|
|
133
|
-
effect(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
effect(
|
|
134
|
+
() => {
|
|
135
|
+
for (const [prevSourceValue, prevTargetValue] of prevValues) {
|
|
136
|
+
if (!subset.has(prevSourceValue)) {
|
|
137
|
+
untrack(() => onDelete?.(prevSourceValue));
|
|
138
|
+
prevValues.delete(prevSourceValue);
|
|
139
|
+
this.delete(prevTargetValue);
|
|
140
|
+
}
|
|
139
141
|
}
|
|
140
|
-
}
|
|
141
142
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
for (const value of subset) {
|
|
144
|
+
if (!prevValues.has(value)) {
|
|
145
|
+
if (onAdd) {
|
|
146
|
+
const added = untrack(() => onAdd(value));
|
|
147
|
+
prevValues.set(value, added);
|
|
148
|
+
} else {
|
|
149
|
+
this.add(value);
|
|
150
|
+
prevValues.set(value, value);
|
|
151
|
+
}
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
+
},
|
|
155
|
+
undefined,
|
|
156
|
+
{
|
|
157
|
+
debug: {
|
|
158
|
+
name: "reactiveUnionSet:subsetSync",
|
|
159
|
+
type: "collection",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
);
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
createDerivedSet<U>(mapper: (value: T) => U | U[]) {
|
|
@@ -184,18 +193,27 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
184
193
|
|
|
185
194
|
this._indexes.push({
|
|
186
195
|
add: (value: T) => {
|
|
187
|
-
effect(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
196
|
+
effect(
|
|
197
|
+
(prev: U[] | U | undefined) => {
|
|
198
|
+
for (const id of [prev].flat()) {
|
|
199
|
+
unref(id as any);
|
|
200
|
+
}
|
|
191
201
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
202
|
+
const mappedValue = mapper(value);
|
|
203
|
+
for (const id of [mappedValue].flat()) {
|
|
204
|
+
ref(id as any);
|
|
205
|
+
}
|
|
196
206
|
|
|
197
|
-
|
|
198
|
-
|
|
207
|
+
return mappedValue;
|
|
208
|
+
},
|
|
209
|
+
undefined,
|
|
210
|
+
{
|
|
211
|
+
debug: {
|
|
212
|
+
name: `reactiveUnionSet:derived:${mapper.name || "mapper"}`,
|
|
213
|
+
type: "collection",
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
);
|
|
199
217
|
},
|
|
200
218
|
delete: (value: T) => {
|
|
201
219
|
const mappedValue = mapper(value);
|
|
@@ -212,24 +230,36 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
212
230
|
const index = shallowReactive(new Map<U, T>());
|
|
213
231
|
this._indexes.push({
|
|
214
232
|
add: (value: T) => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
233
|
+
type MappedValue = U extends readonly (infer InnerArr)[] ? InnerArr : U;
|
|
234
|
+
effect<MappedValue[]>(
|
|
235
|
+
(oldValue) => {
|
|
236
|
+
if (oldValue) {
|
|
237
|
+
for (const id of [oldValue].flat()) {
|
|
238
|
+
index.delete(id as U);
|
|
239
|
+
}
|
|
219
240
|
}
|
|
220
|
-
}
|
|
221
241
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
242
|
+
// we filter to avoid overwriting existing values (first wins)
|
|
243
|
+
const mappedValues = [mapper(value)]
|
|
244
|
+
.flat()
|
|
245
|
+
.filter((v) =>
|
|
246
|
+
untrack(() => !index.has(v as U)),
|
|
247
|
+
) as MappedValue[];
|
|
226
248
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
249
|
+
for (const id of mappedValues) {
|
|
250
|
+
index.set(id as U, value as any);
|
|
251
|
+
}
|
|
230
252
|
|
|
231
|
-
|
|
232
|
-
|
|
253
|
+
return mappedValues;
|
|
254
|
+
},
|
|
255
|
+
undefined as MappedValue[] | undefined,
|
|
256
|
+
{
|
|
257
|
+
debug: {
|
|
258
|
+
name: `reactiveUnionSet:index:${mapper.name || "mapper"}`,
|
|
259
|
+
type: "collection",
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
);
|
|
233
263
|
},
|
|
234
264
|
delete: (value: T) => {
|
|
235
265
|
const mappedValue = mapper(value);
|