nuxt-devtools-observatory 0.1.15 → 0.1.17
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/LICENSE +17 -5
- package/README.md +3 -1
- package/client/dist/assets/index-DDPIR7nA.js +17 -0
- package/client/dist/assets/index-DzKvjd0B.css +1 -0
- package/client/dist/index.html +2 -2
- package/client/src/App.vue +15 -8
- package/client/src/stores/observatory.ts +16 -2
- package/client/src/views/FetchDashboard.vue +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +11 -3
- package/dist/runtime/composables/fetch-registry.js +30 -2
- package/dist/runtime/plugin.js +90 -44
- package/package.json +6 -2
- package/client/dist/assets/index-B1qWBxxI.js +0 -17
- package/client/dist/assets/index-XYlDyaMH.css +0 -1
package/dist/module.mjs
CHANGED
|
@@ -361,8 +361,9 @@ function composableTrackerPlugin() {
|
|
|
361
361
|
}
|
|
362
362
|
const args = path.node.arguments;
|
|
363
363
|
const loc = path.node.loc;
|
|
364
|
+
const fileName = id.split(/[\\/]/).pop() || id;
|
|
364
365
|
const meta = t.objectExpression([
|
|
365
|
-
t.objectProperty(t.identifier("file"), t.stringLiteral(
|
|
366
|
+
t.objectProperty(t.identifier("file"), t.stringLiteral(fileName)),
|
|
366
367
|
t.objectProperty(t.identifier("line"), t.numericLiteral(loc?.start.line ?? 0))
|
|
367
368
|
]);
|
|
368
369
|
path.replaceWith(
|
|
@@ -547,7 +548,9 @@ const module$1 = defineNuxtModule({
|
|
|
547
548
|
if (options.transitionTracker) {
|
|
548
549
|
addVitePlugin(transitionTrackerPlugin());
|
|
549
550
|
}
|
|
550
|
-
|
|
551
|
+
if (options.fetchDashboard || options.provideInjectGraph || options.composableTracker || options.renderHeatmap || options.transitionTracker) {
|
|
552
|
+
addPlugin(resolver.resolve("./runtime/plugin"));
|
|
553
|
+
}
|
|
551
554
|
if (options.fetchDashboard) {
|
|
552
555
|
addServerPlugin(resolver.resolve("./runtime/nitro/fetch-capture"));
|
|
553
556
|
}
|
|
@@ -616,7 +619,12 @@ const module$1 = defineNuxtModule({
|
|
|
616
619
|
});
|
|
617
620
|
nuxt.options.runtimeConfig.public.observatory = {
|
|
618
621
|
heatmapThreshold: options.heatmapThreshold ?? 5,
|
|
619
|
-
clientOrigin
|
|
622
|
+
clientOrigin,
|
|
623
|
+
fetchDashboard: options.fetchDashboard,
|
|
624
|
+
provideInjectGraph: options.provideInjectGraph,
|
|
625
|
+
composableTracker: options.composableTracker,
|
|
626
|
+
renderHeatmap: options.renderHeatmap,
|
|
627
|
+
transitionTracker: options.transitionTracker
|
|
620
628
|
};
|
|
621
629
|
}
|
|
622
630
|
});
|
|
@@ -80,15 +80,29 @@ export function __devFetchCall(originalFn, url, opts, meta) {
|
|
|
80
80
|
if (!registry) {
|
|
81
81
|
return originalFn(url, opts);
|
|
82
82
|
}
|
|
83
|
+
function resolveUrl(u) {
|
|
84
|
+
if (u && typeof u === "object" && "value" in u) {
|
|
85
|
+
return resolveUrl(u.value);
|
|
86
|
+
}
|
|
87
|
+
if (typeof u === "function") {
|
|
88
|
+
try {
|
|
89
|
+
return resolveUrl(u());
|
|
90
|
+
} catch {
|
|
91
|
+
return String(u);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return typeof u === "string" ? u : String(u);
|
|
95
|
+
}
|
|
83
96
|
const id = `${meta.key}::${Date.now()}`;
|
|
84
97
|
const startTime = performance.now();
|
|
85
98
|
const payload = window.__NUXT__?.data ?? {};
|
|
86
99
|
const fromPayload = Object.prototype.hasOwnProperty.call(payload, meta.key);
|
|
87
100
|
const origin = fromPayload ? "ssr" : "csr";
|
|
101
|
+
const resolvedUrl = resolveUrl(url);
|
|
88
102
|
registry.register({
|
|
89
103
|
id,
|
|
90
104
|
key: meta.key,
|
|
91
|
-
url:
|
|
105
|
+
url: resolvedUrl,
|
|
92
106
|
status: fromPayload ? "cached" : "pending",
|
|
93
107
|
origin,
|
|
94
108
|
startTime,
|
|
@@ -98,7 +112,21 @@ export function __devFetchCall(originalFn, url, opts, meta) {
|
|
|
98
112
|
line: meta.line
|
|
99
113
|
});
|
|
100
114
|
if (fromPayload) {
|
|
101
|
-
|
|
115
|
+
const optsWithHooks = {
|
|
116
|
+
...opts,
|
|
117
|
+
onResponse: function(ctx) {
|
|
118
|
+
const entry = registry.getAll().find((e) => e.id === id);
|
|
119
|
+
if (entry) {
|
|
120
|
+
registry.update(id, { payload: ctx.response._data });
|
|
121
|
+
}
|
|
122
|
+
if (typeof opts.onResponse === "function") {
|
|
123
|
+
opts.onResponse(ctx);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
onResponseError: typeof opts.onResponseError === "function" ? opts.onResponseError : () => {
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return originalFn(url, optsWithHooks);
|
|
102
130
|
}
|
|
103
131
|
return originalFn(url, {
|
|
104
132
|
...opts,
|
package/dist/runtime/plugin.js
CHANGED
|
@@ -44,26 +44,40 @@ export default defineNuxtPlugin(() => {
|
|
|
44
44
|
}
|
|
45
45
|
const nuxtApp = useNuxtApp();
|
|
46
46
|
const config = useRuntimeConfig().public.observatory;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
if (config.renderHeatmap) {
|
|
48
|
+
nuxtApp.vueApp.config.performance = true;
|
|
49
|
+
}
|
|
50
|
+
const registries = {};
|
|
51
|
+
let fetchRegistry;
|
|
52
|
+
let provideInjectRegistry;
|
|
53
|
+
let composableRegistry;
|
|
54
|
+
let renderRegistry;
|
|
55
|
+
let transitionRegistry;
|
|
56
|
+
if (config.fetchDashboard) {
|
|
57
|
+
fetchRegistry = setupFetchRegistry();
|
|
58
|
+
registries.fetch = fetchRegistry;
|
|
59
|
+
}
|
|
60
|
+
if (config.provideInjectGraph) {
|
|
61
|
+
provideInjectRegistry = setupProvideInjectRegistry();
|
|
62
|
+
registries.provideInject = provideInjectRegistry;
|
|
63
|
+
}
|
|
64
|
+
if (config.composableTracker) {
|
|
65
|
+
composableRegistry = setupComposableRegistry();
|
|
66
|
+
registries.composable = composableRegistry;
|
|
67
|
+
}
|
|
68
|
+
if (config.renderHeatmap) {
|
|
69
|
+
renderRegistry = setupRenderRegistry(nuxtApp, {
|
|
70
|
+
isHydrating: () => (nuxtApp.isHydrating ?? false) && nuxtApp.payload?.serverRendered === true
|
|
71
|
+
});
|
|
72
|
+
registries.render = renderRegistry;
|
|
73
|
+
}
|
|
74
|
+
if (config.transitionTracker) {
|
|
75
|
+
transitionRegistry = setupTransitionRegistry();
|
|
76
|
+
registries.transition = transitionRegistry;
|
|
77
|
+
}
|
|
58
78
|
if (import.meta.client) {
|
|
59
79
|
delete window.__observatory__;
|
|
60
|
-
window.__observatory__ =
|
|
61
|
-
fetch: fetchRegistry,
|
|
62
|
-
provideInject: provideInjectRegistry,
|
|
63
|
-
composable: composableRegistry,
|
|
64
|
-
render: renderRegistry,
|
|
65
|
-
transition: transitionRegistry
|
|
66
|
-
};
|
|
80
|
+
window.__observatory__ = registries;
|
|
67
81
|
let lastMessageSource = null;
|
|
68
82
|
let lastMessageOrigin = "";
|
|
69
83
|
window.addEventListener("message", (event) => {
|
|
@@ -79,13 +93,17 @@ export default defineNuxtPlugin(() => {
|
|
|
79
93
|
return;
|
|
80
94
|
}
|
|
81
95
|
if (type === "observatory:clear-composables") {
|
|
82
|
-
composableRegistry
|
|
96
|
+
if (composableRegistry) {
|
|
97
|
+
composableRegistry.clear();
|
|
98
|
+
}
|
|
83
99
|
const source = event.source;
|
|
84
100
|
source?.postMessage({ type: "observatory:snapshot", data: buildSnapshot() }, event.origin);
|
|
85
101
|
}
|
|
86
102
|
if (type === "observatory:edit-composable") {
|
|
87
103
|
const { id, key, value } = event.data;
|
|
88
|
-
composableRegistry
|
|
104
|
+
if (composableRegistry) {
|
|
105
|
+
composableRegistry.editValue(id, key, value);
|
|
106
|
+
}
|
|
89
107
|
}
|
|
90
108
|
if (type === "observatory:open-in-editor") {
|
|
91
109
|
const { file } = event.data;
|
|
@@ -96,18 +114,20 @@ export default defineNuxtPlugin(() => {
|
|
|
96
114
|
}
|
|
97
115
|
}
|
|
98
116
|
});
|
|
99
|
-
composableRegistry.onComposableChange
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
if (composableRegistry && composableRegistry.onComposableChange) {
|
|
118
|
+
composableRegistry.onComposableChange(() => {
|
|
119
|
+
if (!lastMessageSource || !lastMessageOrigin) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
lastMessageSource.postMessage(
|
|
123
|
+
{
|
|
124
|
+
type: "observatory:snapshot",
|
|
125
|
+
data: buildSnapshot()
|
|
126
|
+
},
|
|
127
|
+
lastMessageOrigin
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
111
131
|
}
|
|
112
132
|
nuxtApp.hook("app:mounted", () => {
|
|
113
133
|
broadcastAll();
|
|
@@ -119,14 +139,23 @@ export default defineNuxtPlugin(() => {
|
|
|
119
139
|
if (!from || from.name === void 0) {
|
|
120
140
|
return;
|
|
121
141
|
}
|
|
122
|
-
renderRegistry
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
if (renderRegistry) {
|
|
143
|
+
renderRegistry.reset();
|
|
144
|
+
}
|
|
145
|
+
;
|
|
146
|
+
provideInjectRegistry?.clear?.();
|
|
147
|
+
if (composableRegistry) {
|
|
148
|
+
composableRegistry.clear();
|
|
149
|
+
}
|
|
125
150
|
}
|
|
126
151
|
);
|
|
127
152
|
router.afterEach((to) => {
|
|
128
|
-
composableRegistry
|
|
129
|
-
|
|
153
|
+
if (composableRegistry) {
|
|
154
|
+
composableRegistry.setRoute(to.path ?? "/");
|
|
155
|
+
}
|
|
156
|
+
if (renderRegistry) {
|
|
157
|
+
renderRegistry.setRoute(to.path ?? "/");
|
|
158
|
+
}
|
|
130
159
|
nextTick(() => broadcastAll());
|
|
131
160
|
});
|
|
132
161
|
}
|
|
@@ -141,13 +170,30 @@ export default defineNuxtPlugin(() => {
|
|
|
141
170
|
channel.send("observatory:snapshot", buildSnapshot());
|
|
142
171
|
}
|
|
143
172
|
function buildSnapshot() {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
173
|
+
const snap = {};
|
|
174
|
+
if (fetchRegistry) {
|
|
175
|
+
snap.fetch = fetchRegistry.getAll();
|
|
176
|
+
}
|
|
177
|
+
if (provideInjectRegistry) {
|
|
178
|
+
snap.provideInject = provideInjectRegistry.getAll();
|
|
179
|
+
}
|
|
180
|
+
if (composableRegistry) {
|
|
181
|
+
snap.composables = composableRegistry.getAll();
|
|
182
|
+
}
|
|
183
|
+
if (renderRegistry) {
|
|
184
|
+
snap.renders = renderRegistry.getAll();
|
|
185
|
+
}
|
|
186
|
+
if (transitionRegistry) {
|
|
187
|
+
snap.transitions = transitionRegistry.getAll();
|
|
188
|
+
}
|
|
189
|
+
snap.features = {
|
|
190
|
+
fetchDashboard: !!fetchRegistry,
|
|
191
|
+
provideInjectGraph: !!provideInjectRegistry,
|
|
192
|
+
composableTracker: !!composableRegistry,
|
|
193
|
+
renderHeatmap: !!renderRegistry,
|
|
194
|
+
transitionTracker: !!transitionRegistry
|
|
195
|
+
};
|
|
196
|
+
return toSerializable(snap);
|
|
151
197
|
}
|
|
152
198
|
function getDevtoolsChannel() {
|
|
153
199
|
return window.__nuxt_devtools__?.channel ?? null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-devtools-observatory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Nuxt DevTools: useFetch Dashboard, provide/inject Graph, Composable Tracker, Render Heatmap",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/module.mjs",
|
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
"typecheck": "vue-tsc --noEmit",
|
|
38
38
|
"test": "vitest run",
|
|
39
39
|
"test:watch": "vitest",
|
|
40
|
-
"test:coverage": "vitest run --coverage"
|
|
40
|
+
"test:coverage": "vitest run --coverage",
|
|
41
|
+
"test:screenshots": "playwright test scripts/playwright/screenshot-trackers.spec.ts",
|
|
42
|
+
"capture:screenshots": "node scripts/playwright/capture-observatory-screenshots.cjs"
|
|
41
43
|
},
|
|
42
44
|
"dependencies": {
|
|
43
45
|
"@babel/generator": "^7.29.1",
|
|
@@ -51,6 +53,7 @@
|
|
|
51
53
|
"@nuxt/kit": "^3.0.0",
|
|
52
54
|
"@nuxt/module-builder": "^1.0.2",
|
|
53
55
|
"@nuxt/schema": "^3.0.0",
|
|
56
|
+
"@playwright/test": "^1.58.2",
|
|
54
57
|
"@types/babel__generator": "^7.27.0",
|
|
55
58
|
"@types/babel__traverse": "^7.28.0",
|
|
56
59
|
"@types/node": "^25.5.0",
|
|
@@ -65,6 +68,7 @@
|
|
|
65
68
|
"globals": "^17.3.0",
|
|
66
69
|
"happy-dom": "^20.8.4",
|
|
67
70
|
"nuxt": "^3.0.0 || ^4.0.0",
|
|
71
|
+
"playwright": "^1.58.2",
|
|
68
72
|
"postcss-html": "^1.8.1",
|
|
69
73
|
"prettier": "^3.8.1",
|
|
70
74
|
"stylelint": "^17.4.0",
|