@rozenite/network-activity-plugin 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.html +1 -1
- package/dist/assets/{App-C6wCDVkW.js → App-Kyi7zHUX.js} +40 -3
- package/dist/rozenite.json +1 -1
- package/dist/src/shared/client.d.ts +7 -0
- package/dist/src/ui/state/model.d.ts +10 -0
- package/dist/useNetworkActivityDevTools.cjs +18 -0
- package/dist/useNetworkActivityDevTools.js +18 -0
- package/package.json +4 -4
- package/src/react-native/http/network-inspector.ts +20 -0
- package/src/shared/client.ts +8 -0
- package/src/ui/components/RequestList.tsx +9 -1
- package/src/ui/components/Toolbar.tsx +3 -2
- package/src/ui/state/derived.ts +2 -0
- package/src/ui/state/model.ts +10 -0
- package/src/ui/state/store.ts +30 -0
package/dist/App.html
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<script>
|
|
23
23
|
var __ROZENITE_PANEL__ = true;
|
|
24
24
|
</script>
|
|
25
|
-
<script type="module" crossorigin src="./assets/App-
|
|
25
|
+
<script type="module" crossorigin src="./assets/App-Kyi7zHUX.js"></script>
|
|
26
26
|
<link rel="stylesheet" crossorigin href="./assets/App-BrSkOkws.css">
|
|
27
27
|
</head>
|
|
28
28
|
<body>
|
|
@@ -15481,6 +15481,29 @@ const createNetworkActivityStore = () => createStore()(
|
|
|
15481
15481
|
});
|
|
15482
15482
|
break;
|
|
15483
15483
|
}
|
|
15484
|
+
case "request-progress": {
|
|
15485
|
+
const eventData = data;
|
|
15486
|
+
set((state) => {
|
|
15487
|
+
const entry = state.networkEntries.get(eventData.requestId);
|
|
15488
|
+
if (!entry || entry.type !== "http") {
|
|
15489
|
+
return state;
|
|
15490
|
+
}
|
|
15491
|
+
const httpEntry = entry;
|
|
15492
|
+
const updatedEntry = {
|
|
15493
|
+
...httpEntry,
|
|
15494
|
+
status: "loading",
|
|
15495
|
+
progress: {
|
|
15496
|
+
loaded: eventData.loaded,
|
|
15497
|
+
total: eventData.total,
|
|
15498
|
+
lengthComputable: eventData.lengthComputable
|
|
15499
|
+
}
|
|
15500
|
+
};
|
|
15501
|
+
const newEntries = new Map(state.networkEntries);
|
|
15502
|
+
newEntries.set(eventData.requestId, updatedEntry);
|
|
15503
|
+
return { networkEntries: newEntries };
|
|
15504
|
+
});
|
|
15505
|
+
break;
|
|
15506
|
+
}
|
|
15484
15507
|
case "response-received": {
|
|
15485
15508
|
const eventData = data;
|
|
15486
15509
|
set((state) => {
|
|
@@ -15808,6 +15831,10 @@ const createNetworkActivityStore = () => createStore()(
|
|
|
15808
15831
|
"request-sent",
|
|
15809
15832
|
(data) => handleEvent("request-sent", data)
|
|
15810
15833
|
),
|
|
15834
|
+
client2.onMessage(
|
|
15835
|
+
"request-progress",
|
|
15836
|
+
(data) => handleEvent("request-progress", data)
|
|
15837
|
+
),
|
|
15811
15838
|
client2.onMessage(
|
|
15812
15839
|
"response-received",
|
|
15813
15840
|
(data) => handleEvent("response-received", data)
|
|
@@ -16211,7 +16238,8 @@ const getProcessedRequests = memoize((state) => {
|
|
|
16211
16238
|
duration: httpEntry.duration,
|
|
16212
16239
|
size: httpEntry.size,
|
|
16213
16240
|
method: httpEntry.request.method,
|
|
16214
|
-
httpStatus: (_a = httpEntry.response) == null ? void 0 : _a.status
|
|
16241
|
+
httpStatus: (_a = httpEntry.response) == null ? void 0 : _a.status,
|
|
16242
|
+
progress: httpEntry.progress
|
|
16215
16243
|
});
|
|
16216
16244
|
} else if (entry.type === "websocket") {
|
|
16217
16245
|
const wsEntry = entry;
|
|
@@ -16298,7 +16326,8 @@ const Toolbar = () => {
|
|
|
16298
16326
|
size: "sm",
|
|
16299
16327
|
onClick: onToggleRecording,
|
|
16300
16328
|
className: `h-8 w-8 p-0 ${isRecording ? "text-red-400 hover:text-red-300" : "text-gray-400 hover:text-blue-400"}`,
|
|
16301
|
-
|
|
16329
|
+
title: isRecording ? "Stop recording" : "Start recording",
|
|
16330
|
+
children: isRecording ? /* @__PURE__ */ jsxRuntimeExports.jsx(Square, { className: "h-4 w-4 fill-current" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Circle, { className: "h-4 w-4 fill-current" })
|
|
16302
16331
|
}
|
|
16303
16332
|
),
|
|
16304
16333
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -19160,13 +19189,21 @@ const sortTime = (rowA, rowB, columnId) => {
|
|
|
19160
19189
|
};
|
|
19161
19190
|
const processNetworkRequests = (processedRequests, overrides, showEntirePathAsName = false) => {
|
|
19162
19191
|
return processedRequests.map((request) => {
|
|
19192
|
+
var _a;
|
|
19163
19193
|
const { domain, path } = extractDomainAndPath(request.name);
|
|
19164
19194
|
const duration = request.duration || 0;
|
|
19165
19195
|
const hasOverride = overrides.has(request.name);
|
|
19196
|
+
let statusDisplay = request.httpStatus || request.status;
|
|
19197
|
+
if (request.status === "loading" && ((_a = request.progress) == null ? void 0 : _a.lengthComputable)) {
|
|
19198
|
+
const percentage = Math.round(
|
|
19199
|
+
request.progress.loaded / request.progress.total * 100
|
|
19200
|
+
);
|
|
19201
|
+
statusDisplay = `${percentage}%`;
|
|
19202
|
+
}
|
|
19166
19203
|
return {
|
|
19167
19204
|
id: request.id,
|
|
19168
19205
|
name: generateName(request.name, showEntirePathAsName),
|
|
19169
|
-
status:
|
|
19206
|
+
status: statusDisplay,
|
|
19170
19207
|
method: request.method,
|
|
19171
19208
|
domain,
|
|
19172
19209
|
path,
|
package/dist/rozenite.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@rozenite/network-activity-plugin","version":"1.0.0
|
|
1
|
+
{"name":"@rozenite/network-activity-plugin","version":"1.0.0","description":"Network Activity for Rozenite.","panels":[{"name":"Network Activity","source":"/App.html"}]}
|
|
@@ -98,6 +98,13 @@ export type NetworkActivityEventMap = {
|
|
|
98
98
|
error: string;
|
|
99
99
|
canceled: boolean;
|
|
100
100
|
};
|
|
101
|
+
'request-progress': {
|
|
102
|
+
requestId: RequestId;
|
|
103
|
+
timestamp: Timestamp;
|
|
104
|
+
loaded: number;
|
|
105
|
+
total: number;
|
|
106
|
+
lengthComputable: boolean;
|
|
107
|
+
};
|
|
101
108
|
'get-response-body': {
|
|
102
109
|
requestId: RequestId;
|
|
103
110
|
};
|
|
@@ -43,6 +43,11 @@ export type HttpNetworkEntry = {
|
|
|
43
43
|
size?: number;
|
|
44
44
|
initiator?: Initiator;
|
|
45
45
|
resourceType?: ResourceType;
|
|
46
|
+
progress?: {
|
|
47
|
+
loaded: number;
|
|
48
|
+
total: number;
|
|
49
|
+
lengthComputable: boolean;
|
|
50
|
+
};
|
|
46
51
|
};
|
|
47
52
|
export type SSEMessage = {
|
|
48
53
|
id: string;
|
|
@@ -100,4 +105,9 @@ export type ProcessedRequest = {
|
|
|
100
105
|
size: number | null;
|
|
101
106
|
method: HttpMethod | 'WS' | 'SSE';
|
|
102
107
|
httpStatus?: number;
|
|
108
|
+
progress?: {
|
|
109
|
+
loaded: number;
|
|
110
|
+
total: number;
|
|
111
|
+
lengthComputable: boolean;
|
|
112
|
+
};
|
|
103
113
|
};
|
|
@@ -430,6 +430,15 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
430
430
|
type: "XHR",
|
|
431
431
|
initiator
|
|
432
432
|
});
|
|
433
|
+
request.addEventListener("progress", (event) => {
|
|
434
|
+
pluginClient.send("request-progress", {
|
|
435
|
+
requestId,
|
|
436
|
+
timestamp: Date.now(),
|
|
437
|
+
loaded: event.loaded,
|
|
438
|
+
total: event.total,
|
|
439
|
+
lengthComputable: event.lengthComputable
|
|
440
|
+
});
|
|
441
|
+
});
|
|
433
442
|
request.addEventListener("readystatechange", () => {
|
|
434
443
|
if (request.readyState === READY_STATE_HEADERS_RECEIVED) {
|
|
435
444
|
ttfb = Date.now() - sendTime;
|
|
@@ -480,6 +489,15 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
480
489
|
canceled: true
|
|
481
490
|
});
|
|
482
491
|
});
|
|
492
|
+
request.addEventListener("timeout", () => {
|
|
493
|
+
pluginClient.send("request-failed", {
|
|
494
|
+
requestId,
|
|
495
|
+
timestamp: Date.now(),
|
|
496
|
+
type: "XHR",
|
|
497
|
+
error: "Timeout",
|
|
498
|
+
canceled: false
|
|
499
|
+
});
|
|
500
|
+
});
|
|
483
501
|
};
|
|
484
502
|
const handleRequestOverride = (request) => {
|
|
485
503
|
const override = overridesRegistry$1.getOverrideForUrl(
|
|
@@ -426,6 +426,15 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
426
426
|
type: "XHR",
|
|
427
427
|
initiator
|
|
428
428
|
});
|
|
429
|
+
request.addEventListener("progress", (event) => {
|
|
430
|
+
pluginClient.send("request-progress", {
|
|
431
|
+
requestId,
|
|
432
|
+
timestamp: Date.now(),
|
|
433
|
+
loaded: event.loaded,
|
|
434
|
+
total: event.total,
|
|
435
|
+
lengthComputable: event.lengthComputable
|
|
436
|
+
});
|
|
437
|
+
});
|
|
429
438
|
request.addEventListener("readystatechange", () => {
|
|
430
439
|
if (request.readyState === READY_STATE_HEADERS_RECEIVED) {
|
|
431
440
|
ttfb = Date.now() - sendTime;
|
|
@@ -476,6 +485,15 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
476
485
|
canceled: true
|
|
477
486
|
});
|
|
478
487
|
});
|
|
488
|
+
request.addEventListener("timeout", () => {
|
|
489
|
+
pluginClient.send("request-failed", {
|
|
490
|
+
requestId,
|
|
491
|
+
timestamp: Date.now(),
|
|
492
|
+
type: "XHR",
|
|
493
|
+
error: "Timeout",
|
|
494
|
+
canceled: false
|
|
495
|
+
});
|
|
496
|
+
});
|
|
479
497
|
};
|
|
480
498
|
const handleRequestOverride = (request) => {
|
|
481
499
|
const override = overridesRegistry$1.getOverrideForUrl(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rozenite/network-activity-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Network Activity for Rozenite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/react-native.cjs",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"types": "./dist/react-native.d.ts",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"nanoevents": "^9.1.0",
|
|
11
|
-
"@rozenite/plugin-bridge": "1.
|
|
11
|
+
"@rozenite/plugin-bridge": "1.1.0"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"@floating-ui/react": "^0.26.0",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"zustand": "^5.0.6",
|
|
37
37
|
"@types/react": "~18.3.23",
|
|
38
38
|
"@types/react-dom": "~18.3.1",
|
|
39
|
-
"@rozenite/vite-plugin": "1.
|
|
40
|
-
"rozenite": "1.
|
|
39
|
+
"@rozenite/vite-plugin": "1.1.0",
|
|
40
|
+
"rozenite": "1.1.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"react-native-sse": "*"
|
|
@@ -227,6 +227,16 @@ export const getNetworkInspector = (
|
|
|
227
227
|
initiator,
|
|
228
228
|
});
|
|
229
229
|
|
|
230
|
+
request.addEventListener('progress', (event) => {
|
|
231
|
+
pluginClient.send('request-progress', {
|
|
232
|
+
requestId: requestId,
|
|
233
|
+
timestamp: Date.now(),
|
|
234
|
+
loaded: event.loaded,
|
|
235
|
+
total: event.total,
|
|
236
|
+
lengthComputable: event.lengthComputable,
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
230
240
|
request.addEventListener('readystatechange', () => {
|
|
231
241
|
if (request.readyState === READY_STATE_HEADERS_RECEIVED) {
|
|
232
242
|
ttfb = Date.now() - sendTime;
|
|
@@ -281,6 +291,16 @@ export const getNetworkInspector = (
|
|
|
281
291
|
canceled: true,
|
|
282
292
|
});
|
|
283
293
|
});
|
|
294
|
+
|
|
295
|
+
request.addEventListener('timeout', () => {
|
|
296
|
+
pluginClient.send('request-failed', {
|
|
297
|
+
requestId: requestId,
|
|
298
|
+
timestamp: Date.now(),
|
|
299
|
+
type: 'XHR',
|
|
300
|
+
error: 'Timeout',
|
|
301
|
+
canceled: false,
|
|
302
|
+
});
|
|
303
|
+
});
|
|
284
304
|
};
|
|
285
305
|
|
|
286
306
|
const handleRequestOverride = (request: XMLHttpRequest): void => {
|
package/src/shared/client.ts
CHANGED
|
@@ -136,6 +136,14 @@ export type NetworkActivityEventMap = {
|
|
|
136
136
|
canceled: boolean;
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
+
'request-progress': {
|
|
140
|
+
requestId: RequestId;
|
|
141
|
+
timestamp: Timestamp;
|
|
142
|
+
loaded: number;
|
|
143
|
+
total: number;
|
|
144
|
+
lengthComputable: boolean;
|
|
145
|
+
};
|
|
146
|
+
|
|
139
147
|
'get-response-body': {
|
|
140
148
|
requestId: RequestId;
|
|
141
149
|
};
|
|
@@ -135,10 +135,18 @@ const processNetworkRequests = (
|
|
|
135
135
|
const duration = request.duration || 0;
|
|
136
136
|
const hasOverride = overrides.has(request.name);
|
|
137
137
|
|
|
138
|
+
let statusDisplay: string | number = request.httpStatus || request.status;
|
|
139
|
+
if (request.status === 'loading' && request.progress?.lengthComputable) {
|
|
140
|
+
const percentage = Math.round(
|
|
141
|
+
(request.progress.loaded / request.progress.total) * 100,
|
|
142
|
+
);
|
|
143
|
+
statusDisplay = `${percentage}%`;
|
|
144
|
+
}
|
|
145
|
+
|
|
138
146
|
return {
|
|
139
147
|
id: request.id,
|
|
140
148
|
name: generateName(request.name, showEntirePathAsName),
|
|
141
|
-
status:
|
|
149
|
+
status: statusDisplay,
|
|
142
150
|
method: request.method,
|
|
143
151
|
domain,
|
|
144
152
|
path,
|
|
@@ -25,11 +25,12 @@ export const Toolbar = () => {
|
|
|
25
25
|
? 'text-red-400 hover:text-red-300'
|
|
26
26
|
: 'text-gray-400 hover:text-blue-400'
|
|
27
27
|
}`}
|
|
28
|
+
title={isRecording ? 'Stop recording' : 'Start recording'}
|
|
28
29
|
>
|
|
29
30
|
{isRecording ? (
|
|
30
|
-
<
|
|
31
|
+
<Square className="h-4 w-4 fill-current" />
|
|
31
32
|
) : (
|
|
32
|
-
<
|
|
33
|
+
<Circle className="h-4 w-4 fill-current" />
|
|
33
34
|
)}
|
|
34
35
|
</Button>
|
|
35
36
|
<Button
|
package/src/ui/state/derived.ts
CHANGED
|
@@ -24,6 +24,7 @@ export const getProcessedRequests = memoize((state: NetworkActivityState) => {
|
|
|
24
24
|
size: httpEntry.size,
|
|
25
25
|
method: httpEntry.request.method,
|
|
26
26
|
httpStatus: httpEntry.response?.status,
|
|
27
|
+
progress: httpEntry.progress,
|
|
27
28
|
});
|
|
28
29
|
} else if (entry.type === 'websocket') {
|
|
29
30
|
const wsEntry = entry as WebSocketNetworkEntry;
|
|
@@ -81,6 +82,7 @@ export const getRequestSummary = (
|
|
|
81
82
|
size: httpEntry.size,
|
|
82
83
|
method: httpEntry.request.method,
|
|
83
84
|
httpStatus: httpEntry.response?.status || 0,
|
|
85
|
+
progress: httpEntry.progress,
|
|
84
86
|
};
|
|
85
87
|
} else if (entry.type === 'websocket') {
|
|
86
88
|
const wsEntry = entry as WebSocketNetworkEntry;
|
package/src/ui/state/model.ts
CHANGED
|
@@ -58,6 +58,11 @@ export type HttpNetworkEntry = {
|
|
|
58
58
|
size?: number;
|
|
59
59
|
initiator?: Initiator;
|
|
60
60
|
resourceType?: ResourceType;
|
|
61
|
+
progress?: {
|
|
62
|
+
loaded: number;
|
|
63
|
+
total: number;
|
|
64
|
+
lengthComputable: boolean;
|
|
65
|
+
};
|
|
61
66
|
};
|
|
62
67
|
|
|
63
68
|
/* SSE */
|
|
@@ -137,4 +142,9 @@ export type ProcessedRequest = {
|
|
|
137
142
|
size: number | null;
|
|
138
143
|
method: HttpMethod | 'WS' | 'SSE';
|
|
139
144
|
httpStatus?: number;
|
|
145
|
+
progress?: {
|
|
146
|
+
loaded: number;
|
|
147
|
+
total: number;
|
|
148
|
+
lengthComputable: boolean;
|
|
149
|
+
};
|
|
140
150
|
};
|
package/src/ui/state/store.ts
CHANGED
|
@@ -168,6 +168,33 @@ export const createNetworkActivityStore = () =>
|
|
|
168
168
|
break;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
case 'request-progress': {
|
|
172
|
+
const eventData =
|
|
173
|
+
data as NetworkActivityEventMap['request-progress'];
|
|
174
|
+
set((state) => {
|
|
175
|
+
const entry = state.networkEntries.get(eventData.requestId);
|
|
176
|
+
if (!entry || entry.type !== 'http') {
|
|
177
|
+
return state;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const httpEntry = entry as HttpNetworkEntry;
|
|
181
|
+
const updatedEntry: HttpNetworkEntry = {
|
|
182
|
+
...httpEntry,
|
|
183
|
+
status: 'loading',
|
|
184
|
+
progress: {
|
|
185
|
+
loaded: eventData.loaded,
|
|
186
|
+
total: eventData.total,
|
|
187
|
+
lengthComputable: eventData.lengthComputable,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const newEntries = new Map(state.networkEntries);
|
|
192
|
+
newEntries.set(eventData.requestId, updatedEntry);
|
|
193
|
+
return { networkEntries: newEntries };
|
|
194
|
+
});
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
|
|
171
198
|
case 'response-received': {
|
|
172
199
|
const eventData =
|
|
173
200
|
data as NetworkActivityEventMap['response-received'];
|
|
@@ -559,6 +586,9 @@ export const createNetworkActivityStore = () =>
|
|
|
559
586
|
client.onMessage('request-sent', (data) =>
|
|
560
587
|
handleEvent('request-sent', data)
|
|
561
588
|
),
|
|
589
|
+
client.onMessage('request-progress', (data) =>
|
|
590
|
+
handleEvent('request-progress', data)
|
|
591
|
+
),
|
|
562
592
|
client.onMessage('response-received', (data) =>
|
|
563
593
|
handleEvent('response-received', data)
|
|
564
594
|
),
|