nuxt-devtools-observatory 0.1.26 → 0.1.30
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 +50 -11
- package/client/dist/assets/index-BCaKoHBH.js +17 -0
- package/client/dist/assets/index-BmGW_M3W.css +1 -0
- package/client/dist/index.html +2 -2
- package/client/src/App.vue +2 -6
- package/client/src/composables/useResizablePane.ts +65 -0
- package/client/src/stores/observatory.ts +162 -218
- package/client/src/style.css +203 -28
- package/client/src/views/ComposableTracker.vue +327 -294
- package/client/src/views/FetchDashboard.vue +104 -132
- package/client/src/views/ProvideInjectGraph.vue +101 -118
- package/client/src/views/RenderHeatmap.vue +192 -157
- package/client/src/views/TransitionTimeline.vue +166 -130
- package/client/tsconfig.json +3 -1
- package/client/vite.config.ts +12 -1
- package/dist/module.d.mts +6 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +238 -186
- package/dist/runtime/composables/fetch-registry.js +3 -0
- package/dist/runtime/plugin.js +89 -66
- package/package.json +12 -3
- package/client/dist/assets/index-1-H6UMCK.css +0 -1
- package/client/dist/assets/index-eSUuhYQ0.js +0 -17
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addServerPlugin } from '@nuxt/kit';
|
|
2
|
+
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
3
|
+
import sirv from 'sirv';
|
|
2
4
|
import { parse } from '@babel/parser';
|
|
3
5
|
import _traverse from '@babel/traverse';
|
|
4
6
|
import _generate from '@babel/generator';
|
|
@@ -22,6 +24,156 @@ function extractScriptBlock(code) {
|
|
|
22
24
|
|
|
23
25
|
const traverse$2 = _traverse.default ?? _traverse;
|
|
24
26
|
const generate$2 = _generate.default ?? _generate;
|
|
27
|
+
const COMPOSABLE_RE = /\buse[A-Z]/;
|
|
28
|
+
const SKIP_LIST = /* @__PURE__ */ new Set([
|
|
29
|
+
// useFetch family — tracked by the fetch dashboard
|
|
30
|
+
"useFetch",
|
|
31
|
+
"useAsyncData",
|
|
32
|
+
"useLazyFetch",
|
|
33
|
+
"useLazyAsyncData",
|
|
34
|
+
// Nuxt auto-imports
|
|
35
|
+
"useCookie",
|
|
36
|
+
"useRequestEvent",
|
|
37
|
+
"useRequestHeaders",
|
|
38
|
+
"useRequestURL",
|
|
39
|
+
"useResponseHeader",
|
|
40
|
+
"useNuxtApp",
|
|
41
|
+
"useRuntimeConfig",
|
|
42
|
+
"useRoute",
|
|
43
|
+
"useRouter",
|
|
44
|
+
"useNuxtData",
|
|
45
|
+
"useError",
|
|
46
|
+
"useState",
|
|
47
|
+
"useAppConfig",
|
|
48
|
+
// Nuxt head
|
|
49
|
+
"useHead",
|
|
50
|
+
"useSeoMeta",
|
|
51
|
+
"useServerSeoMeta",
|
|
52
|
+
"useHeadSafe",
|
|
53
|
+
// Nuxt i18n (common plugin)
|
|
54
|
+
"useI18n",
|
|
55
|
+
"useLocalePath",
|
|
56
|
+
"useLocaleRoute",
|
|
57
|
+
// Vue built-ins
|
|
58
|
+
"useSlots",
|
|
59
|
+
"useAttrs",
|
|
60
|
+
"useModel",
|
|
61
|
+
"useTemplateRef",
|
|
62
|
+
"useId",
|
|
63
|
+
"useCssModule",
|
|
64
|
+
"useCssVars"
|
|
65
|
+
]);
|
|
66
|
+
function composableTrackerPlugin() {
|
|
67
|
+
return {
|
|
68
|
+
name: "vite-plugin-observatory-composables",
|
|
69
|
+
enforce: "pre",
|
|
70
|
+
transform(code, id) {
|
|
71
|
+
const isVue = id.endsWith(".vue");
|
|
72
|
+
if (!isVue && !id.endsWith(".ts") && !id.endsWith(".js")) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (id.includes("node_modules") || id.includes("composable-registry") || id.includes("provide-inject-registry") || id.includes("fetch-registry")) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
let scriptCode = code;
|
|
79
|
+
let scriptStart = 0;
|
|
80
|
+
if (isVue) {
|
|
81
|
+
const block = extractScriptBlock(code);
|
|
82
|
+
if (!block) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
scriptCode = block.content;
|
|
86
|
+
scriptStart = block.start;
|
|
87
|
+
}
|
|
88
|
+
if (!COMPOSABLE_RE.test(scriptCode)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const ast = parse(scriptCode, {
|
|
93
|
+
sourceType: "module",
|
|
94
|
+
plugins: ["typescript"]
|
|
95
|
+
});
|
|
96
|
+
let modified = false;
|
|
97
|
+
traverse$2(ast, {
|
|
98
|
+
CallExpression(path) {
|
|
99
|
+
const callee = path.node.callee;
|
|
100
|
+
if (!t.isIdentifier(callee)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const name = callee.name;
|
|
104
|
+
if (!COMPOSABLE_RE.test(name)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (SKIP_LIST.has(name)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const binding = path.scope.getBinding(name);
|
|
111
|
+
if (binding?.path.isImportSpecifier() || binding?.path.isImportDefaultSpecifier()) {
|
|
112
|
+
const importDecl = binding.path.parentPath?.node;
|
|
113
|
+
const source = importDecl?.source?.value ?? "";
|
|
114
|
+
if (source && !source.startsWith(".") && !source.startsWith("/")) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
let parent = path.parentPath;
|
|
119
|
+
let isWrapped = false;
|
|
120
|
+
while (parent) {
|
|
121
|
+
if (t.isCallExpression(parent.node) && t.isIdentifier(parent.node.callee) && parent.node.callee.name === "__trackComposable") {
|
|
122
|
+
isWrapped = true;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
parent = parent.parentPath ?? null;
|
|
126
|
+
}
|
|
127
|
+
if (isWrapped) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const comments = (path.node.leadingComments ?? []).concat(path.parentPath?.node?.leadingComments ?? []);
|
|
131
|
+
const ignored = comments.some((c) => c.value.includes("@devtools-ignore"));
|
|
132
|
+
if (ignored) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const args = path.node.arguments;
|
|
136
|
+
const loc = path.node.loc;
|
|
137
|
+
const fileName = id.split(/[\\/]/).pop() || id;
|
|
138
|
+
const meta = t.objectExpression([
|
|
139
|
+
t.objectProperty(t.identifier("file"), t.stringLiteral(fileName)),
|
|
140
|
+
t.objectProperty(t.identifier("line"), t.numericLiteral(loc?.start.line ?? 0))
|
|
141
|
+
]);
|
|
142
|
+
path.replaceWith(
|
|
143
|
+
t.callExpression(t.identifier("__trackComposable"), [
|
|
144
|
+
t.stringLiteral(name),
|
|
145
|
+
t.arrowFunctionExpression([], t.callExpression(t.identifier(name), args)),
|
|
146
|
+
meta
|
|
147
|
+
])
|
|
148
|
+
);
|
|
149
|
+
modified = true;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
if (!modified) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
const importLine = `import { __trackComposable } from 'nuxt-devtools-observatory/runtime/composable-registry';
|
|
156
|
+
`;
|
|
157
|
+
const output = generate$2(ast, { retainLines: true }, scriptCode);
|
|
158
|
+
const alreadyImported = output.code.includes("nuxt-devtools-observatory/runtime/composable-registry");
|
|
159
|
+
const prefix = alreadyImported ? "" : importLine;
|
|
160
|
+
let finalCode;
|
|
161
|
+
if (isVue) {
|
|
162
|
+
finalCode = code.slice(0, scriptStart) + prefix + output.code + code.slice(scriptStart + scriptCode.length);
|
|
163
|
+
} else {
|
|
164
|
+
finalCode = prefix + output.code;
|
|
165
|
+
}
|
|
166
|
+
return { code: finalCode, map: output.map };
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.warn("[observatory] composable transform error:", err);
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const traverse$1 = _traverse.default ?? _traverse;
|
|
176
|
+
const generate$1 = _generate.default ?? _generate;
|
|
25
177
|
const FETCH_FNS = /* @__PURE__ */ new Set(["useFetch", "useAsyncData", "useLazyFetch", "useLazyAsyncData"]);
|
|
26
178
|
function isHandlerExpression(node) {
|
|
27
179
|
return Boolean(node && (t.isIdentifier(node) || t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)));
|
|
@@ -61,7 +213,7 @@ function fetchInstrumentPlugin() {
|
|
|
61
213
|
let needsFetchHandlerHelper = false;
|
|
62
214
|
const hasFetchCallImport = scriptCode.includes("__devFetchCall");
|
|
63
215
|
const hasFetchHandlerImport = scriptCode.includes("__devFetchHandler");
|
|
64
|
-
traverse$
|
|
216
|
+
traverse$1(ast, {
|
|
65
217
|
CallExpression(path) {
|
|
66
218
|
if (path.node.__observatoryTransformed) {
|
|
67
219
|
return;
|
|
@@ -179,7 +331,7 @@ function fetchInstrumentPlugin() {
|
|
|
179
331
|
].filter(Boolean);
|
|
180
332
|
const importStatement = importNames.length ? `import { ${importNames.join(", ")} } from 'nuxt-devtools-observatory/runtime/fetch-registry';
|
|
181
333
|
` : "";
|
|
182
|
-
const output = generate$
|
|
334
|
+
const output = generate$1(ast, { retainLines: true }, scriptCode);
|
|
183
335
|
let finalCode;
|
|
184
336
|
if (isVue) {
|
|
185
337
|
finalCode = code.slice(0, scriptStart) + importStatement + output.code + code.slice(scriptStart + scriptCode.length);
|
|
@@ -198,8 +350,8 @@ function fetchInstrumentPlugin() {
|
|
|
198
350
|
};
|
|
199
351
|
}
|
|
200
352
|
|
|
201
|
-
const traverse
|
|
202
|
-
const generate
|
|
353
|
+
const traverse = _traverse.default ?? _traverse;
|
|
354
|
+
const generate = _generate.default ?? _generate;
|
|
203
355
|
function provideInjectPlugin() {
|
|
204
356
|
return {
|
|
205
357
|
name: "vite-plugin-observatory-provide-inject",
|
|
@@ -231,7 +383,7 @@ function provideInjectPlugin() {
|
|
|
231
383
|
plugins: ["typescript"]
|
|
232
384
|
});
|
|
233
385
|
let modified = false;
|
|
234
|
-
traverse
|
|
386
|
+
traverse(ast, {
|
|
235
387
|
CallExpression(path) {
|
|
236
388
|
const callee = path.node.callee;
|
|
237
389
|
if (!t.isIdentifier(callee)) {
|
|
@@ -265,7 +417,7 @@ function provideInjectPlugin() {
|
|
|
265
417
|
}
|
|
266
418
|
const importLine = `import { __devProvide, __devInject } from 'nuxt-devtools-observatory/runtime/provide-inject-registry';
|
|
267
419
|
`;
|
|
268
|
-
const output = generate
|
|
420
|
+
const output = generate(ast, { retainLines: true }, scriptCode);
|
|
269
421
|
let finalCode;
|
|
270
422
|
if (isVue) {
|
|
271
423
|
finalCode = code.slice(0, scriptStart) + (scriptCode.includes("__devProvide") ? "" : importLine) + output.code + code.slice(scriptStart + scriptCode.length);
|
|
@@ -281,156 +433,6 @@ function provideInjectPlugin() {
|
|
|
281
433
|
};
|
|
282
434
|
}
|
|
283
435
|
|
|
284
|
-
const traverse = _traverse.default ?? _traverse;
|
|
285
|
-
const generate = _generate.default ?? _generate;
|
|
286
|
-
const COMPOSABLE_RE = /\buse[A-Z]/;
|
|
287
|
-
const SKIP_LIST = /* @__PURE__ */ new Set([
|
|
288
|
-
// useFetch family — tracked by the fetch dashboard
|
|
289
|
-
"useFetch",
|
|
290
|
-
"useAsyncData",
|
|
291
|
-
"useLazyFetch",
|
|
292
|
-
"useLazyAsyncData",
|
|
293
|
-
// Nuxt auto-imports
|
|
294
|
-
"useCookie",
|
|
295
|
-
"useRequestEvent",
|
|
296
|
-
"useRequestHeaders",
|
|
297
|
-
"useRequestURL",
|
|
298
|
-
"useResponseHeader",
|
|
299
|
-
"useNuxtApp",
|
|
300
|
-
"useRuntimeConfig",
|
|
301
|
-
"useRoute",
|
|
302
|
-
"useRouter",
|
|
303
|
-
"useNuxtData",
|
|
304
|
-
"useError",
|
|
305
|
-
"useState",
|
|
306
|
-
"useAppConfig",
|
|
307
|
-
// Nuxt head
|
|
308
|
-
"useHead",
|
|
309
|
-
"useSeoMeta",
|
|
310
|
-
"useServerSeoMeta",
|
|
311
|
-
"useHeadSafe",
|
|
312
|
-
// Nuxt i18n (common plugin)
|
|
313
|
-
"useI18n",
|
|
314
|
-
"useLocalePath",
|
|
315
|
-
"useLocaleRoute",
|
|
316
|
-
// Vue built-ins
|
|
317
|
-
"useSlots",
|
|
318
|
-
"useAttrs",
|
|
319
|
-
"useModel",
|
|
320
|
-
"useTemplateRef",
|
|
321
|
-
"useId",
|
|
322
|
-
"useCssModule",
|
|
323
|
-
"useCssVars"
|
|
324
|
-
]);
|
|
325
|
-
function composableTrackerPlugin() {
|
|
326
|
-
return {
|
|
327
|
-
name: "vite-plugin-observatory-composables",
|
|
328
|
-
enforce: "pre",
|
|
329
|
-
transform(code, id) {
|
|
330
|
-
const isVue = id.endsWith(".vue");
|
|
331
|
-
if (!isVue && !id.endsWith(".ts") && !id.endsWith(".js")) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
if (id.includes("node_modules") || id.includes("composable-registry") || id.includes("provide-inject-registry") || id.includes("fetch-registry")) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
let scriptCode = code;
|
|
338
|
-
let scriptStart = 0;
|
|
339
|
-
if (isVue) {
|
|
340
|
-
const block = extractScriptBlock(code);
|
|
341
|
-
if (!block) {
|
|
342
|
-
return null;
|
|
343
|
-
}
|
|
344
|
-
scriptCode = block.content;
|
|
345
|
-
scriptStart = block.start;
|
|
346
|
-
}
|
|
347
|
-
if (!COMPOSABLE_RE.test(scriptCode)) {
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
try {
|
|
351
|
-
const ast = parse(scriptCode, {
|
|
352
|
-
sourceType: "module",
|
|
353
|
-
plugins: ["typescript"]
|
|
354
|
-
});
|
|
355
|
-
let modified = false;
|
|
356
|
-
traverse(ast, {
|
|
357
|
-
CallExpression(path) {
|
|
358
|
-
const callee = path.node.callee;
|
|
359
|
-
if (!t.isIdentifier(callee)) {
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
const name = callee.name;
|
|
363
|
-
if (!COMPOSABLE_RE.test(name)) {
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
if (SKIP_LIST.has(name)) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
const binding = path.scope.getBinding(name);
|
|
370
|
-
if (binding?.path.isImportSpecifier() || binding?.path.isImportDefaultSpecifier()) {
|
|
371
|
-
const importDecl = binding.path.parentPath?.node;
|
|
372
|
-
const source = importDecl?.source?.value ?? "";
|
|
373
|
-
if (source && !source.startsWith(".") && !source.startsWith("/")) {
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
let parent = path.parentPath;
|
|
378
|
-
let isWrapped = false;
|
|
379
|
-
while (parent) {
|
|
380
|
-
if (t.isCallExpression(parent.node) && t.isIdentifier(parent.node.callee) && parent.node.callee.name === "__trackComposable") {
|
|
381
|
-
isWrapped = true;
|
|
382
|
-
break;
|
|
383
|
-
}
|
|
384
|
-
parent = parent.parentPath ?? null;
|
|
385
|
-
}
|
|
386
|
-
if (isWrapped) {
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
const comments = (path.node.leadingComments ?? []).concat(path.parentPath?.node?.leadingComments ?? []);
|
|
390
|
-
const ignored = comments.some((c) => c.value.includes("@devtools-ignore"));
|
|
391
|
-
if (ignored) {
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
const args = path.node.arguments;
|
|
395
|
-
const loc = path.node.loc;
|
|
396
|
-
const fileName = id.split(/[\\/]/).pop() || id;
|
|
397
|
-
const meta = t.objectExpression([
|
|
398
|
-
t.objectProperty(t.identifier("file"), t.stringLiteral(fileName)),
|
|
399
|
-
t.objectProperty(t.identifier("line"), t.numericLiteral(loc?.start.line ?? 0))
|
|
400
|
-
]);
|
|
401
|
-
path.replaceWith(
|
|
402
|
-
t.callExpression(t.identifier("__trackComposable"), [
|
|
403
|
-
t.stringLiteral(name),
|
|
404
|
-
t.arrowFunctionExpression([], t.callExpression(t.identifier(name), args)),
|
|
405
|
-
meta
|
|
406
|
-
])
|
|
407
|
-
);
|
|
408
|
-
modified = true;
|
|
409
|
-
}
|
|
410
|
-
});
|
|
411
|
-
if (!modified) {
|
|
412
|
-
return null;
|
|
413
|
-
}
|
|
414
|
-
const importLine = `import { __trackComposable } from 'nuxt-devtools-observatory/runtime/composable-registry';
|
|
415
|
-
`;
|
|
416
|
-
const output = generate(ast, { retainLines: true }, scriptCode);
|
|
417
|
-
const alreadyImported = output.code.includes("nuxt-devtools-observatory/runtime/composable-registry");
|
|
418
|
-
const prefix = alreadyImported ? "" : importLine;
|
|
419
|
-
let finalCode;
|
|
420
|
-
if (isVue) {
|
|
421
|
-
finalCode = code.slice(0, scriptStart) + prefix + output.code + code.slice(scriptStart + scriptCode.length);
|
|
422
|
-
} else {
|
|
423
|
-
finalCode = prefix + output.code;
|
|
424
|
-
}
|
|
425
|
-
return { code: finalCode, map: output.map };
|
|
426
|
-
} catch (err) {
|
|
427
|
-
console.warn("[observatory] composable transform error:", err);
|
|
428
|
-
return null;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
|
|
434
436
|
const VIRTUAL_ID = "\0obs:vue-proxy";
|
|
435
437
|
const PROXY_MODULE = `
|
|
436
438
|
import {
|
|
@@ -544,6 +546,8 @@ function transitionTrackerPlugin() {
|
|
|
544
546
|
}
|
|
545
547
|
|
|
546
548
|
const defaults = {
|
|
549
|
+
// Auto-enable server instrumentation for SSR projects unless explicitly overridden.
|
|
550
|
+
// This ensures initial SSR snapshots include server-side composables/fetch events.
|
|
547
551
|
instrumentServer: process.env.OBSERVATORY_INSTRUMENT_SERVER === "true",
|
|
548
552
|
fetchDashboard: process.env.OBSERVATORY_FETCH_DASHBOARD === "true",
|
|
549
553
|
provideInjectGraph: process.env.OBSERVATORY_PROVIDE_INJECT_GRAPH === "true",
|
|
@@ -559,7 +563,8 @@ const defaults = {
|
|
|
559
563
|
maxComposableEntries: process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES) : 300,
|
|
560
564
|
maxRenderTimeline: process.env.OBSERVATORY_MAX_RENDER_TIMELINE ? Number(process.env.OBSERVATORY_MAX_RENDER_TIMELINE) : 100,
|
|
561
565
|
composableNavigationMode: process.env.OBSERVATORY_COMPOSABLE_NAVIGATION_MODE === "session" ? "session" : "route",
|
|
562
|
-
heatmapHideInternals: process.env.OBSERVATORY_HEATMAP_HIDE_INTERNALS === "true"
|
|
566
|
+
heatmapHideInternals: process.env.OBSERVATORY_HEATMAP_HIDE_INTERNALS === "true",
|
|
567
|
+
debugRpc: process.env.OBSERVATORY_DEBUG_RPC === "true"
|
|
563
568
|
};
|
|
564
569
|
const module$1 = defineNuxtModule({
|
|
565
570
|
meta: {
|
|
@@ -586,7 +591,7 @@ const module$1 = defineNuxtModule({
|
|
|
586
591
|
composableTracker: options.composableTracker ?? (process.env.OBSERVATORY_COMPOSABLE_TRACKER ? process.env.OBSERVATORY_COMPOSABLE_TRACKER === "true" : true),
|
|
587
592
|
renderHeatmap: options.renderHeatmap ?? (process.env.OBSERVATORY_RENDER_HEATMAP ? process.env.OBSERVATORY_RENDER_HEATMAP === "true" : true),
|
|
588
593
|
transitionTracker: options.transitionTracker ?? (process.env.OBSERVATORY_TRANSITION_TRACKER ? process.env.OBSERVATORY_TRANSITION_TRACKER === "true" : true),
|
|
589
|
-
instrumentServer: options.instrumentServer ?? (process.env.OBSERVATORY_INSTRUMENT_SERVER ? process.env.OBSERVATORY_INSTRUMENT_SERVER === "true" : false),
|
|
594
|
+
instrumentServer: options.instrumentServer ?? (process.env.OBSERVATORY_INSTRUMENT_SERVER ? process.env.OBSERVATORY_INSTRUMENT_SERVER === "true" : nuxt.options.ssr !== false),
|
|
590
595
|
heatmapThresholdCount: options.heatmapThresholdCount ?? (process.env.OBSERVATORY_HEATMAP_THRESHOLD_COUNT ? Number(process.env.OBSERVATORY_HEATMAP_THRESHOLD_COUNT) : 3),
|
|
591
596
|
heatmapThresholdTime: options.heatmapThresholdTime ?? (process.env.OBSERVATORY_HEATMAP_THRESHOLD_TIME ? Number(process.env.OBSERVATORY_HEATMAP_THRESHOLD_TIME) : 1600),
|
|
592
597
|
maxFetchEntries: options.maxFetchEntries ?? (process.env.OBSERVATORY_MAX_FETCH_ENTRIES ? Number(process.env.OBSERVATORY_MAX_FETCH_ENTRIES) : 200),
|
|
@@ -595,7 +600,8 @@ const module$1 = defineNuxtModule({
|
|
|
595
600
|
maxComposableHistory: options.maxComposableHistory ?? (process.env.OBSERVATORY_MAX_COMPOSABLE_HISTORY ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_HISTORY) : 50),
|
|
596
601
|
maxComposableEntries: options.maxComposableEntries ?? (process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES) : 300),
|
|
597
602
|
maxRenderTimeline: options.maxRenderTimeline ?? (process.env.OBSERVATORY_MAX_RENDER_TIMELINE ? Number(process.env.OBSERVATORY_MAX_RENDER_TIMELINE) : 100),
|
|
598
|
-
composableNavigationMode: options.composableNavigationMode ?? (process.env.OBSERVATORY_COMPOSABLE_NAVIGATION_MODE === "session" ? "session" : "route")
|
|
603
|
+
composableNavigationMode: options.composableNavigationMode ?? (process.env.OBSERVATORY_COMPOSABLE_NAVIGATION_MODE === "session" ? "session" : "route"),
|
|
604
|
+
debugRpc: options.debugRpc ?? (process.env.OBSERVATORY_DEBUG_RPC ? process.env.OBSERVATORY_DEBUG_RPC === "true" : false)
|
|
599
605
|
};
|
|
600
606
|
nuxt.hook("vite:extendConfig", (config) => {
|
|
601
607
|
const alias = config.resolve?.alias;
|
|
@@ -626,34 +632,80 @@ const module$1 = defineNuxtModule({
|
|
|
626
632
|
if (resolved.fetchDashboard) {
|
|
627
633
|
addServerPlugin(resolver.resolve("./runtime/nitro/fetch-capture"));
|
|
628
634
|
}
|
|
629
|
-
const
|
|
630
|
-
const
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
return;
|
|
635
|
+
const base = "/__observatory";
|
|
636
|
+
const debugRpc = resolved.debugRpc === true;
|
|
637
|
+
const debugLog = (...args) => {
|
|
638
|
+
if (debugRpc) {
|
|
639
|
+
console.info("[observatory][rpc][server]", ...args);
|
|
635
640
|
}
|
|
636
|
-
|
|
641
|
+
};
|
|
642
|
+
let latestSnapshot = {
|
|
643
|
+
fetch: [],
|
|
644
|
+
provideInject: { provides: [], injects: [] },
|
|
645
|
+
composables: [],
|
|
646
|
+
renders: [],
|
|
647
|
+
transitions: [],
|
|
648
|
+
features: {
|
|
649
|
+
fetchDashboard: !!resolved.fetchDashboard,
|
|
650
|
+
provideInjectGraph: !!resolved.provideInjectGraph,
|
|
651
|
+
composableTracker: !!resolved.composableTracker,
|
|
652
|
+
composableNavigationMode: resolved.composableNavigationMode,
|
|
653
|
+
renderHeatmap: !!resolved.renderHeatmap,
|
|
654
|
+
transitionTracker: !!resolved.transitionTracker
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
let rpc = null;
|
|
658
|
+
let viteServer = null;
|
|
659
|
+
const emitCommand = (command) => {
|
|
660
|
+
if (!viteServer) {
|
|
661
|
+
console.warn("[observatory][rpc][server] command dropped (vite ws not ready)", command);
|
|
637
662
|
return;
|
|
638
663
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
664
|
+
debugLog("send command", command);
|
|
665
|
+
viteServer.ws.send("observatory:command", command);
|
|
666
|
+
};
|
|
667
|
+
addVitePlugin({
|
|
668
|
+
name: "nuxt-devtools-observatory:sirv-client",
|
|
669
|
+
configureServer(server) {
|
|
670
|
+
viteServer = server;
|
|
671
|
+
const clientDist = resolver.resolve("../client/dist");
|
|
672
|
+
server.middlewares.use(base, sirv(clientDist, { dev: true, single: true }));
|
|
673
|
+
server.ws.on("observatory:snapshot", (snapshot) => {
|
|
674
|
+
latestSnapshot = snapshot;
|
|
675
|
+
debugLog("received host snapshot", {
|
|
676
|
+
fetch: Array.isArray(snapshot.fetch) ? snapshot.fetch.length : 0,
|
|
677
|
+
composables: Array.isArray(snapshot.composables) ? snapshot.composables.length : 0,
|
|
678
|
+
renders: Array.isArray(snapshot.renders) ? snapshot.renders.length : 0,
|
|
679
|
+
transitions: Array.isArray(snapshot.transitions) ? snapshot.transitions.length : 0
|
|
680
|
+
});
|
|
681
|
+
rpc?.broadcast.onSnapshot.asEvent(snapshot);
|
|
682
|
+
});
|
|
683
|
+
}
|
|
655
684
|
});
|
|
656
|
-
|
|
685
|
+
onDevToolsInitialized(() => {
|
|
686
|
+
rpc = extendServerRpc(
|
|
687
|
+
"observatory",
|
|
688
|
+
{
|
|
689
|
+
async getSnapshot() {
|
|
690
|
+
return latestSnapshot;
|
|
691
|
+
},
|
|
692
|
+
async requestSnapshot() {
|
|
693
|
+
emitCommand({ cmd: "request-snapshot" });
|
|
694
|
+
},
|
|
695
|
+
async clearComposables() {
|
|
696
|
+
emitCommand({ cmd: "clear-composables" });
|
|
697
|
+
},
|
|
698
|
+
async setComposableMode(mode) {
|
|
699
|
+
emitCommand({ cmd: "set-mode", mode });
|
|
700
|
+
},
|
|
701
|
+
async editComposableValue(id, key, value) {
|
|
702
|
+
emitCommand({ cmd: "edit-composable", id, key, value });
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
nuxt
|
|
706
|
+
);
|
|
707
|
+
rpc.broadcast.onSnapshot.asEvent(latestSnapshot);
|
|
708
|
+
}, nuxt);
|
|
657
709
|
nuxt.hook("render:response", (response, { url }) => {
|
|
658
710
|
if (url.startsWith("/trackers") || url === "/" || url.startsWith("/index.html")) {
|
|
659
711
|
const configScript = `<script>window.__observatoryConfig = ${JSON.stringify(nuxt.options.runtimeConfig.public.observatory)};<\/script>`;
|
|
@@ -667,13 +719,12 @@ ${configScript}`);
|
|
|
667
719
|
name: "observatory-trackers",
|
|
668
720
|
title: "Observatory Trackers",
|
|
669
721
|
icon: "carbon:heat-map",
|
|
670
|
-
view: { type: "iframe", src: `${base}/trackers` }
|
|
722
|
+
view: { type: "iframe", src: `${base}/trackers${resolved.debugRpc ? "?debugRpc=1" : ""}` }
|
|
671
723
|
});
|
|
672
724
|
}
|
|
673
725
|
});
|
|
674
726
|
nuxt.options.runtimeConfig.public.observatory = {
|
|
675
727
|
instrumentServer: resolved.instrumentServer,
|
|
676
|
-
clientOrigin,
|
|
677
728
|
fetchDashboard: resolved.fetchDashboard,
|
|
678
729
|
provideInjectGraph: resolved.provideInjectGraph,
|
|
679
730
|
composableTracker: resolved.composableTracker,
|
|
@@ -688,7 +739,8 @@ ${configScript}`);
|
|
|
688
739
|
composableNavigationMode: resolved.composableNavigationMode,
|
|
689
740
|
heatmapHideInternals: resolved.heatmapHideInternals,
|
|
690
741
|
heatmapThresholdCount: resolved.heatmapThresholdCount,
|
|
691
|
-
heatmapThresholdTime: resolved.heatmapThresholdTime
|
|
742
|
+
heatmapThresholdTime: resolved.heatmapThresholdTime,
|
|
743
|
+
debugRpc: resolved.debugRpc
|
|
692
744
|
};
|
|
693
745
|
}
|
|
694
746
|
});
|
|
@@ -218,6 +218,9 @@ export function __devFetchCall(originalFn, url, opts, meta) {
|
|
|
218
218
|
}
|
|
219
219
|
},
|
|
220
220
|
onResponseError({ response }) {
|
|
221
|
+
const endTime = performance.now();
|
|
222
|
+
const ms = Math.round(endTime - lastCallStart);
|
|
223
|
+
registry.update(id, { status: "error", endTime, ms });
|
|
221
224
|
if (typeof opts.onResponseError === "function") {
|
|
222
225
|
opts.onResponseError({ response });
|
|
223
226
|
}
|