@rozenite/network-activity-plugin 1.0.0-alpha.15 → 1.0.0-alpha.16

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.
Files changed (30) hide show
  1. package/dist/App.html +2 -2
  2. package/dist/assets/{App-CfJuBHc_.css → App-BrSkOkws.css} +21 -0
  3. package/dist/assets/{App-CZPlDq_M.js → App-CM3Ub2ZA.js} +911 -479
  4. package/dist/rozenite.json +1 -1
  5. package/dist/src/react-native/http/overrides-registry.d.ts +6 -0
  6. package/dist/src/react-native/http/xhr-interceptor.d.ts +5 -0
  7. package/dist/src/shared/client.d.ts +7 -0
  8. package/dist/src/ui/components/CodeEditor.d.ts +5 -0
  9. package/dist/src/ui/components/OverrideResponse.d.ts +8 -0
  10. package/dist/src/ui/components/RequestList.d.ts +3 -2
  11. package/dist/src/ui/components/Section.d.ts +2 -1
  12. package/dist/src/ui/state/hooks.d.ts +3 -0
  13. package/dist/src/ui/state/store.d.ts +26 -3
  14. package/dist/useNetworkActivityDevTools.cjs +72 -0
  15. package/dist/useNetworkActivityDevTools.js +72 -0
  16. package/package.json +4 -4
  17. package/src/react-native/http/network-inspector.ts +50 -0
  18. package/src/react-native/http/overrides-registry.ts +32 -0
  19. package/src/react-native/http/xhr-interceptor.ts +14 -0
  20. package/src/react-native/useNetworkActivityDevTools.ts +6 -0
  21. package/src/shared/client.ts +9 -0
  22. package/src/ui/components/CodeEditor.tsx +26 -0
  23. package/src/ui/components/OverrideResponse.tsx +132 -0
  24. package/src/ui/components/RequestList.tsx +15 -8
  25. package/src/ui/components/Section.tsx +5 -1
  26. package/src/ui/components/SidePanel.tsx +8 -0
  27. package/src/ui/state/hooks.ts +4 -0
  28. package/src/ui/state/store.ts +585 -502
  29. package/src/ui/tabs/ResponseTab.tsx +60 -12
  30. package/src/ui/views/InspectorView.tsx +7 -1
@@ -15062,6 +15062,10 @@ const Check = createLucideIcon$1("Check", [
15062
15062
  const ChevronDown = createLucideIcon$1("ChevronDown", [
15063
15063
  ["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]
15064
15064
  ]);
15065
+ const CircleSlash2 = createLucideIcon$1("CircleSlash2", [
15066
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
15067
+ ["path", { d: "M22 2 2 22", key: "y4kqgn" }]
15068
+ ]);
15065
15069
  const Circle = createLucideIcon$1("Circle", [
15066
15070
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]
15067
15071
  ]);
@@ -15095,6 +15099,13 @@ const Filter = createLucideIcon$1("Filter", [
15095
15099
  const Loader2 = createLucideIcon$1("Loader2", [
15096
15100
  ["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]
15097
15101
  ]);
15102
+ const Pencil = createLucideIcon$1("Pencil", [
15103
+ [
15104
+ "path",
15105
+ { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z", key: "5qss01" }
15106
+ ],
15107
+ ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
15108
+ ]);
15098
15109
  const Square = createLucideIcon$1("Square", [
15099
15110
  [
15100
15111
  "rect",
@@ -15133,7 +15144,7 @@ const createStoreImpl = (createState) => {
15133
15144
  const initialState = state = createState(setState, getState, api);
15134
15145
  return api;
15135
15146
  };
15136
- const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
15147
+ const createStore = (createState) => createStoreImpl;
15137
15148
  const identity$2 = (arg) => arg;
15138
15149
  function useStore(api, selector = identity$2) {
15139
15150
  const slice2 = React.useSyncExternalStore(
@@ -15144,6 +15155,192 @@ function useStore(api, selector = identity$2) {
15144
15155
  React.useDebugValue(slice2);
15145
15156
  return slice2;
15146
15157
  }
15158
+ function createJSONStorage(getStorage, options) {
15159
+ let storage;
15160
+ try {
15161
+ storage = getStorage();
15162
+ } catch (e) {
15163
+ return;
15164
+ }
15165
+ const persistStorage = {
15166
+ getItem: (name) => {
15167
+ var _a;
15168
+ const parse2 = (str2) => {
15169
+ if (str2 === null) {
15170
+ return null;
15171
+ }
15172
+ return JSON.parse(str2, options == null ? void 0 : options.reviver);
15173
+ };
15174
+ const str = (_a = storage.getItem(name)) != null ? _a : null;
15175
+ if (str instanceof Promise) {
15176
+ return str.then(parse2);
15177
+ }
15178
+ return parse2(str);
15179
+ },
15180
+ setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),
15181
+ removeItem: (name) => storage.removeItem(name)
15182
+ };
15183
+ return persistStorage;
15184
+ }
15185
+ const toThenable = (fn) => (input) => {
15186
+ try {
15187
+ const result = fn(input);
15188
+ if (result instanceof Promise) {
15189
+ return result;
15190
+ }
15191
+ return {
15192
+ then(onFulfilled) {
15193
+ return toThenable(onFulfilled)(result);
15194
+ },
15195
+ catch(_onRejected) {
15196
+ return this;
15197
+ }
15198
+ };
15199
+ } catch (e) {
15200
+ return {
15201
+ then(_onFulfilled) {
15202
+ return this;
15203
+ },
15204
+ catch(onRejected) {
15205
+ return toThenable(onRejected)(e);
15206
+ }
15207
+ };
15208
+ }
15209
+ };
15210
+ const persistImpl = (config, baseOptions) => (set, get, api) => {
15211
+ let options = {
15212
+ storage: createJSONStorage(() => localStorage),
15213
+ partialize: (state) => state,
15214
+ version: 0,
15215
+ merge: (persistedState, currentState) => ({
15216
+ ...currentState,
15217
+ ...persistedState
15218
+ }),
15219
+ ...baseOptions
15220
+ };
15221
+ let hasHydrated = false;
15222
+ const hydrationListeners = /* @__PURE__ */ new Set();
15223
+ const finishHydrationListeners = /* @__PURE__ */ new Set();
15224
+ let storage = options.storage;
15225
+ if (!storage) {
15226
+ return config(
15227
+ (...args) => {
15228
+ console.warn(
15229
+ `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
15230
+ );
15231
+ set(...args);
15232
+ },
15233
+ get,
15234
+ api
15235
+ );
15236
+ }
15237
+ const setItem = () => {
15238
+ const state = options.partialize({ ...get() });
15239
+ return storage.setItem(options.name, {
15240
+ state,
15241
+ version: options.version
15242
+ });
15243
+ };
15244
+ const savedSetState = api.setState;
15245
+ api.setState = (state, replace) => {
15246
+ savedSetState(state, replace);
15247
+ void setItem();
15248
+ };
15249
+ const configResult = config(
15250
+ (...args) => {
15251
+ set(...args);
15252
+ void setItem();
15253
+ },
15254
+ get,
15255
+ api
15256
+ );
15257
+ api.getInitialState = () => configResult;
15258
+ let stateFromStorage;
15259
+ const hydrate2 = () => {
15260
+ var _a, _b;
15261
+ if (!storage) return;
15262
+ hasHydrated = false;
15263
+ hydrationListeners.forEach((cb) => {
15264
+ var _a2;
15265
+ return cb((_a2 = get()) != null ? _a2 : configResult);
15266
+ });
15267
+ const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;
15268
+ return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
15269
+ if (deserializedStorageValue) {
15270
+ if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
15271
+ if (options.migrate) {
15272
+ const migration = options.migrate(
15273
+ deserializedStorageValue.state,
15274
+ deserializedStorageValue.version
15275
+ );
15276
+ if (migration instanceof Promise) {
15277
+ return migration.then((result) => [true, result]);
15278
+ }
15279
+ return [true, migration];
15280
+ }
15281
+ console.error(
15282
+ `State loaded from storage couldn't be migrated since no migrate function was provided`
15283
+ );
15284
+ } else {
15285
+ return [false, deserializedStorageValue.state];
15286
+ }
15287
+ }
15288
+ return [false, void 0];
15289
+ }).then((migrationResult) => {
15290
+ var _a2;
15291
+ const [migrated, migratedState] = migrationResult;
15292
+ stateFromStorage = options.merge(
15293
+ migratedState,
15294
+ (_a2 = get()) != null ? _a2 : configResult
15295
+ );
15296
+ set(stateFromStorage, true);
15297
+ if (migrated) {
15298
+ return setItem();
15299
+ }
15300
+ }).then(() => {
15301
+ postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
15302
+ stateFromStorage = get();
15303
+ hasHydrated = true;
15304
+ finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
15305
+ }).catch((e) => {
15306
+ postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
15307
+ });
15308
+ };
15309
+ api.persist = {
15310
+ setOptions: (newOptions) => {
15311
+ options = {
15312
+ ...options,
15313
+ ...newOptions
15314
+ };
15315
+ if (newOptions.storage) {
15316
+ storage = newOptions.storage;
15317
+ }
15318
+ },
15319
+ clearStorage: () => {
15320
+ storage == null ? void 0 : storage.removeItem(options.name);
15321
+ },
15322
+ getOptions: () => options,
15323
+ rehydrate: () => hydrate2(),
15324
+ hasHydrated: () => hasHydrated,
15325
+ onHydrate: (cb) => {
15326
+ hydrationListeners.add(cb);
15327
+ return () => {
15328
+ hydrationListeners.delete(cb);
15329
+ };
15330
+ },
15331
+ onFinishHydration: (cb) => {
15332
+ finishHydrationListeners.add(cb);
15333
+ return () => {
15334
+ finishHydrationListeners.delete(cb);
15335
+ };
15336
+ }
15337
+ };
15338
+ if (!options.skipHydration) {
15339
+ hydrate2();
15340
+ }
15341
+ return stateFromStorage || configResult;
15342
+ };
15343
+ const persist = persistImpl;
15147
15344
  const idMap = /* @__PURE__ */ new Map();
15148
15345
  const getId = (namespace) => {
15149
15346
  if (!idMap.has(namespace)) {
@@ -15196,450 +15393,513 @@ function applyReactNativeRequestHeadersLogic(headers, postData) {
15196
15393
  "Content-Type": inferredContentType
15197
15394
  };
15198
15395
  }
15199
- const createNetworkActivityStore = () => createStore((set, get) => ({
15200
- // Initial state
15201
- isRecording: false,
15202
- selectedRequestId: null,
15203
- networkEntries: /* @__PURE__ */ new Map(),
15204
- websocketMessages: /* @__PURE__ */ new Map(),
15205
- // Actions
15206
- actions: {
15207
- setRecording: (isRecording) => {
15208
- const { _client } = get();
15209
- assert(!!_client, "Client is not set");
15210
- _client.send(isRecording ? "network-enable" : "network-disable", {});
15211
- set({ isRecording });
15212
- },
15213
- setSelectedRequest: (requestId) => set({ selectedRequestId: requestId }),
15214
- clearRequests: () => set({
15396
+ const STORE_VERSION = 1;
15397
+ const createNetworkActivityStore = () => createStore()(
15398
+ persist(
15399
+ (set, get) => ({
15400
+ // Initial state
15401
+ isRecording: false,
15402
+ selectedRequestId: null,
15215
15403
  networkEntries: /* @__PURE__ */ new Map(),
15216
15404
  websocketMessages: /* @__PURE__ */ new Map(),
15217
- selectedRequestId: null
15218
- })
15219
- },
15220
- // Event handling
15221
- handleEvent: (eventType, data) => {
15222
- switch (eventType) {
15223
- case "request-sent": {
15224
- const eventData = data;
15225
- set((state) => {
15226
- const headersWithContentType = applyReactNativeRequestHeadersLogic(
15227
- eventData.request.headers,
15228
- eventData.request.postData
15229
- );
15230
- const requestContentType = getContentTypeMime(headersWithContentType) || "text/plain";
15231
- const entry = {
15232
- id: eventData.requestId,
15233
- type: "http",
15234
- timestamp: eventData.timestamp,
15235
- request: {
15236
- url: eventData.request.url,
15237
- method: eventData.request.method,
15238
- headers: headersWithContentType,
15239
- body: eventData.request.postData ? {
15240
- type: requestContentType,
15241
- data: eventData.request.postData
15242
- } : void 0
15243
- },
15244
- status: "pending",
15245
- initiator: eventData.initiator,
15246
- resourceType: eventData.type
15247
- };
15248
- const newEntries = new Map(state.networkEntries);
15249
- newEntries.set(eventData.requestId, entry);
15250
- return { networkEntries: newEntries };
15251
- });
15252
- break;
15253
- }
15254
- case "response-received": {
15255
- const eventData = data;
15256
- set((state) => {
15257
- const entry = state.networkEntries.get(eventData.requestId);
15258
- if (!entry || entry.type !== "http") return state;
15259
- const httpEntry = entry;
15260
- const updatedEntry = {
15261
- ...httpEntry,
15262
- status: "loading",
15263
- response: eventData.response
15264
- };
15265
- const newEntries = new Map(state.networkEntries);
15266
- newEntries.set(eventData.requestId, updatedEntry);
15267
- return { networkEntries: newEntries };
15268
- });
15269
- break;
15270
- }
15271
- case "request-completed": {
15272
- const eventData = data;
15273
- set((state) => {
15274
- const entry = state.networkEntries.get(eventData.requestId);
15275
- if (!entry || entry.type !== "http") return state;
15276
- const httpEntry = entry;
15277
- const updatedEntry = {
15278
- ...httpEntry,
15279
- status: "finished",
15280
- duration: eventData.duration,
15281
- size: eventData.size,
15282
- ttfb: eventData.ttfb
15283
- };
15284
- const newEntries = new Map(state.networkEntries);
15285
- newEntries.set(eventData.requestId, updatedEntry);
15286
- return { networkEntries: newEntries };
15287
- });
15288
- break;
15289
- }
15290
- case "request-failed": {
15291
- const eventData = data;
15292
- set((state) => {
15293
- const entry = state.networkEntries.get(eventData.requestId);
15294
- if (!entry || entry.type !== "http") return state;
15295
- const httpEntry = entry;
15296
- const updatedEntry = {
15297
- ...httpEntry,
15298
- status: "failed",
15299
- error: eventData.error
15300
- };
15301
- const newEntries = new Map(state.networkEntries);
15302
- newEntries.set(eventData.requestId, updatedEntry);
15303
- return { networkEntries: newEntries };
15304
- });
15305
- break;
15306
- }
15307
- case "response-body": {
15308
- const eventData = data;
15309
- set((state) => {
15310
- var _a;
15311
- const entry = state.networkEntries.get(eventData.requestId);
15312
- if (!entry || entry.type !== "http") return state;
15313
- const httpEntry = entry;
15314
- const updatedEntry = {
15315
- ...httpEntry,
15316
- response: httpEntry.response ? {
15317
- ...httpEntry.response,
15318
- body: eventData.body ? {
15319
- type: getContentTypeMime(
15320
- ((_a = httpEntry.response) == null ? void 0 : _a.headers) ?? {}
15321
- ) || "text/plain",
15322
- data: eventData.body
15323
- } : void 0
15324
- } : void 0
15325
- };
15326
- const newEntries = new Map(state.networkEntries);
15327
- newEntries.set(eventData.requestId, updatedEntry);
15328
- return { networkEntries: newEntries };
15329
- });
15330
- break;
15331
- }
15332
- case "websocket-connect": {
15333
- const eventData = data;
15334
- set((state) => {
15335
- const entry = {
15336
- id: `ws-${eventData.socketId}`,
15337
- type: "websocket",
15338
- timestamp: eventData.timestamp,
15339
- connection: {
15340
- url: eventData.url,
15341
- socketId: eventData.socketId,
15342
- protocols: eventData.protocols || void 0,
15343
- options: eventData.options
15344
- },
15345
- status: "connecting"
15346
- };
15347
- const newEntries = new Map(state.networkEntries);
15348
- newEntries.set(entry.id, entry);
15349
- const newMessages = new Map(state.websocketMessages);
15350
- newMessages.set(entry.id, []);
15351
- return {
15352
- networkEntries: newEntries,
15353
- websocketMessages: newMessages
15354
- };
15355
- });
15356
- break;
15357
- }
15358
- case "websocket-open": {
15359
- const eventData = data;
15360
- set((state) => {
15361
- const entry = state.networkEntries.get(`ws-${eventData.socketId}`);
15362
- if (!entry || entry.type !== "websocket") return state;
15363
- const wsEntry = entry;
15364
- const updatedEntry = {
15365
- ...wsEntry,
15366
- status: "open"
15367
- };
15368
- const newEntries = new Map(state.networkEntries);
15369
- newEntries.set(entry.id, updatedEntry);
15370
- return { networkEntries: newEntries };
15371
- });
15372
- break;
15373
- }
15374
- case "websocket-close": {
15375
- const eventData = data;
15376
- set((state) => {
15377
- const entry = state.networkEntries.get(`ws-${eventData.socketId}`);
15378
- if (!entry || entry.type !== "websocket") return state;
15379
- const wsEntry = entry;
15380
- const updatedEntry = {
15381
- ...wsEntry,
15382
- status: "closed",
15383
- closeCode: eventData.code,
15384
- closeReason: eventData.reason,
15385
- duration: eventData.timestamp - wsEntry.timestamp
15386
- };
15387
- const newEntries = new Map(state.networkEntries);
15388
- newEntries.set(entry.id, updatedEntry);
15389
- return { networkEntries: newEntries };
15390
- });
15391
- break;
15392
- }
15393
- case "websocket-message-sent": {
15394
- const eventData = data;
15395
- set((state) => {
15396
- const socketId = `ws-${eventData.socketId}`;
15397
- const currentMessages = state.websocketMessages.get(socketId) || [];
15398
- const message = {
15399
- id: getId(`${socketId}-message`),
15400
- direction: "sent",
15401
- data: eventData.data,
15402
- messageType: eventData.messageType,
15403
- timestamp: eventData.timestamp
15404
- };
15405
- const newMessages = new Map(state.websocketMessages);
15406
- newMessages.set(
15407
- socketId,
15408
- [...currentMessages, message].slice(
15409
- -32
15410
- )
15411
- );
15412
- return { websocketMessages: newMessages };
15413
- });
15414
- break;
15415
- }
15416
- case "websocket-message-received": {
15417
- const eventData = data;
15418
- set((state) => {
15419
- const socketId = `ws-${eventData.socketId}`;
15420
- const currentMessages = state.websocketMessages.get(socketId) || [];
15421
- const message = {
15422
- id: getId(`${socketId}-message`),
15423
- direction: "received",
15424
- data: eventData.data,
15425
- messageType: eventData.messageType,
15426
- timestamp: eventData.timestamp
15427
- };
15428
- const newMessages = new Map(state.websocketMessages);
15429
- newMessages.set(
15430
- socketId,
15431
- [...currentMessages, message].slice(
15432
- -32
15433
- )
15405
+ overrides: /* @__PURE__ */ new Map(),
15406
+ // Actions
15407
+ actions: {
15408
+ setRecording: (isRecording) => {
15409
+ const { _client } = get();
15410
+ assert(!!_client, "Client is not set");
15411
+ _client.send(
15412
+ isRecording ? "network-enable" : "network-disable",
15413
+ {}
15434
15414
  );
15435
- return { websocketMessages: newMessages };
15436
- });
15437
- break;
15438
- }
15439
- case "websocket-error": {
15440
- const eventData = data;
15441
- set((state) => {
15442
- const entry = state.networkEntries.get(`ws-${eventData.socketId}`);
15443
- if (!entry || entry.type !== "websocket") return state;
15444
- const wsEntry = entry;
15445
- const updatedEntry = {
15446
- ...wsEntry,
15447
- status: "error",
15448
- error: eventData.error
15449
- };
15450
- const newEntries = new Map(state.networkEntries);
15451
- newEntries.set(entry.id, updatedEntry);
15452
- return { networkEntries: newEntries };
15453
- });
15454
- break;
15455
- }
15456
- case "websocket-connection-status-changed": {
15457
- const eventData = data;
15458
- set((state) => {
15459
- const entry = state.networkEntries.get(`ws-${eventData.socketId}`);
15460
- if (!entry || entry.type !== "websocket") return state;
15461
- const wsEntry = entry;
15462
- const updatedEntry = {
15463
- ...wsEntry,
15464
- status: eventData.status
15465
- };
15466
- const newEntries = new Map(state.networkEntries);
15467
- newEntries.set(entry.id, updatedEntry);
15468
- return { networkEntries: newEntries };
15469
- });
15470
- break;
15471
- }
15472
- case "sse-open": {
15473
- const eventData = data;
15474
- set((state) => {
15475
- const entry = state.networkEntries.get(eventData.requestId);
15476
- if (!entry || entry.type !== "http") return state;
15477
- const httpEntry = entry;
15478
- const sseEntry = {
15479
- ...httpEntry,
15480
- type: "sse",
15481
- // Change type from 'http' to 'sse'
15482
- status: "open",
15483
- // Update status
15484
- messages: [],
15485
- // Add SSE-specific field
15486
- response: eventData.response
15487
- };
15488
- const newEntries = new Map(state.networkEntries);
15489
- newEntries.set(eventData.requestId, sseEntry);
15490
- return { networkEntries: newEntries };
15491
- });
15492
- break;
15493
- }
15494
- case "sse-message": {
15495
- const eventData = data;
15496
- set((state) => {
15497
- const entry = state.networkEntries.get(eventData.requestId);
15498
- if (!entry || entry.type !== "sse") return state;
15499
- const sseEntry = entry;
15500
- const newMessage = {
15501
- id: getId(`${eventData.requestId}-message`),
15502
- type: eventData.payload.type,
15503
- data: eventData.payload.data,
15504
- timestamp: eventData.timestamp
15505
- };
15506
- const updatedEntry = {
15507
- ...sseEntry,
15508
- messages: [...sseEntry.messages, newMessage].slice(
15509
- -32
15415
+ set({ isRecording });
15416
+ },
15417
+ setSelectedRequest: (requestId) => set({ selectedRequestId: requestId }),
15418
+ clearRequests: () => set({
15419
+ networkEntries: /* @__PURE__ */ new Map(),
15420
+ websocketMessages: /* @__PURE__ */ new Map(),
15421
+ selectedRequestId: null
15422
+ }),
15423
+ addOverride: (requestUrl, override) => {
15424
+ const { overrides, _client } = get();
15425
+ assert(!!_client, "Client is not set");
15426
+ const newOverrides = new Map(overrides);
15427
+ newOverrides.set(requestUrl, override);
15428
+ _client.send("set-overrides", {
15429
+ overrides: Array.from(newOverrides.entries())
15430
+ });
15431
+ set({ overrides: newOverrides });
15432
+ },
15433
+ clearOverride: (requestUrl) => {
15434
+ const { overrides, _client } = get();
15435
+ assert(!!_client, "Client is not set");
15436
+ const newOverrides = new Map(overrides);
15437
+ newOverrides.delete(requestUrl);
15438
+ _client.send("set-overrides", {
15439
+ overrides: Array.from(newOverrides.entries())
15440
+ });
15441
+ set({ overrides: newOverrides });
15442
+ }
15443
+ },
15444
+ // Event handling
15445
+ handleEvent: (eventType, data) => {
15446
+ switch (eventType) {
15447
+ case "request-sent": {
15448
+ const eventData = data;
15449
+ set((state) => {
15450
+ const headersWithContentType = applyReactNativeRequestHeadersLogic(
15451
+ eventData.request.headers,
15452
+ eventData.request.postData
15453
+ );
15454
+ const requestContentType = getContentTypeMime(headersWithContentType) || "text/plain";
15455
+ const entry = {
15456
+ id: eventData.requestId,
15457
+ type: "http",
15458
+ timestamp: eventData.timestamp,
15459
+ request: {
15460
+ url: eventData.request.url,
15461
+ method: eventData.request.method,
15462
+ headers: headersWithContentType,
15463
+ body: eventData.request.postData ? {
15464
+ type: requestContentType,
15465
+ data: eventData.request.postData
15466
+ } : void 0
15467
+ },
15468
+ status: "pending",
15469
+ initiator: eventData.initiator,
15470
+ resourceType: eventData.type
15471
+ };
15472
+ const newEntries = new Map(state.networkEntries);
15473
+ newEntries.set(eventData.requestId, entry);
15474
+ return { networkEntries: newEntries };
15475
+ });
15476
+ break;
15477
+ }
15478
+ case "response-received": {
15479
+ const eventData = data;
15480
+ set((state) => {
15481
+ const entry = state.networkEntries.get(eventData.requestId);
15482
+ if (!entry || entry.type !== "http") return state;
15483
+ const httpEntry = entry;
15484
+ const updatedEntry = {
15485
+ ...httpEntry,
15486
+ status: "loading",
15487
+ response: eventData.response
15488
+ };
15489
+ const newEntries = new Map(state.networkEntries);
15490
+ newEntries.set(eventData.requestId, updatedEntry);
15491
+ return { networkEntries: newEntries };
15492
+ });
15493
+ break;
15494
+ }
15495
+ case "request-completed": {
15496
+ const eventData = data;
15497
+ set((state) => {
15498
+ const entry = state.networkEntries.get(eventData.requestId);
15499
+ if (!entry || entry.type !== "http") return state;
15500
+ const httpEntry = entry;
15501
+ const updatedEntry = {
15502
+ ...httpEntry,
15503
+ status: "finished",
15504
+ duration: eventData.duration,
15505
+ size: eventData.size,
15506
+ ttfb: eventData.ttfb
15507
+ };
15508
+ const newEntries = new Map(state.networkEntries);
15509
+ newEntries.set(eventData.requestId, updatedEntry);
15510
+ return { networkEntries: newEntries };
15511
+ });
15512
+ break;
15513
+ }
15514
+ case "request-failed": {
15515
+ const eventData = data;
15516
+ set((state) => {
15517
+ const entry = state.networkEntries.get(eventData.requestId);
15518
+ if (!entry || entry.type !== "http") return state;
15519
+ const httpEntry = entry;
15520
+ const updatedEntry = {
15521
+ ...httpEntry,
15522
+ status: "failed",
15523
+ error: eventData.error
15524
+ };
15525
+ const newEntries = new Map(state.networkEntries);
15526
+ newEntries.set(eventData.requestId, updatedEntry);
15527
+ return { networkEntries: newEntries };
15528
+ });
15529
+ break;
15530
+ }
15531
+ case "response-body": {
15532
+ const eventData = data;
15533
+ set((state) => {
15534
+ var _a;
15535
+ const entry = state.networkEntries.get(eventData.requestId);
15536
+ if (!entry || entry.type !== "http") return state;
15537
+ const httpEntry = entry;
15538
+ const updatedEntry = {
15539
+ ...httpEntry,
15540
+ response: httpEntry.response ? {
15541
+ ...httpEntry.response,
15542
+ body: eventData.body ? {
15543
+ type: getContentTypeMime(
15544
+ ((_a = httpEntry.response) == null ? void 0 : _a.headers) ?? {}
15545
+ ) || "text/plain",
15546
+ data: eventData.body
15547
+ } : void 0
15548
+ } : void 0
15549
+ };
15550
+ const newEntries = new Map(state.networkEntries);
15551
+ newEntries.set(eventData.requestId, updatedEntry);
15552
+ return { networkEntries: newEntries };
15553
+ });
15554
+ break;
15555
+ }
15556
+ case "websocket-connect": {
15557
+ const eventData = data;
15558
+ set((state) => {
15559
+ const entry = {
15560
+ id: `ws-${eventData.socketId}`,
15561
+ type: "websocket",
15562
+ timestamp: eventData.timestamp,
15563
+ connection: {
15564
+ url: eventData.url,
15565
+ socketId: eventData.socketId,
15566
+ protocols: eventData.protocols || void 0,
15567
+ options: eventData.options
15568
+ },
15569
+ status: "connecting"
15570
+ };
15571
+ const newEntries = new Map(state.networkEntries);
15572
+ newEntries.set(entry.id, entry);
15573
+ const newMessages = new Map(state.websocketMessages);
15574
+ newMessages.set(entry.id, []);
15575
+ return {
15576
+ networkEntries: newEntries,
15577
+ websocketMessages: newMessages
15578
+ };
15579
+ });
15580
+ break;
15581
+ }
15582
+ case "websocket-open": {
15583
+ const eventData = data;
15584
+ set((state) => {
15585
+ const entry = state.networkEntries.get(
15586
+ `ws-${eventData.socketId}`
15587
+ );
15588
+ if (!entry || entry.type !== "websocket") return state;
15589
+ const wsEntry = entry;
15590
+ const updatedEntry = {
15591
+ ...wsEntry,
15592
+ status: "open"
15593
+ };
15594
+ const newEntries = new Map(state.networkEntries);
15595
+ newEntries.set(entry.id, updatedEntry);
15596
+ return { networkEntries: newEntries };
15597
+ });
15598
+ break;
15599
+ }
15600
+ case "websocket-close": {
15601
+ const eventData = data;
15602
+ set((state) => {
15603
+ const entry = state.networkEntries.get(
15604
+ `ws-${eventData.socketId}`
15605
+ );
15606
+ if (!entry || entry.type !== "websocket") return state;
15607
+ const wsEntry = entry;
15608
+ const updatedEntry = {
15609
+ ...wsEntry,
15610
+ status: "closed",
15611
+ closeCode: eventData.code,
15612
+ closeReason: eventData.reason,
15613
+ duration: eventData.timestamp - wsEntry.timestamp
15614
+ };
15615
+ const newEntries = new Map(state.networkEntries);
15616
+ newEntries.set(entry.id, updatedEntry);
15617
+ return { networkEntries: newEntries };
15618
+ });
15619
+ break;
15620
+ }
15621
+ case "websocket-message-sent": {
15622
+ const eventData = data;
15623
+ set((state) => {
15624
+ const socketId = `ws-${eventData.socketId}`;
15625
+ const currentMessages = state.websocketMessages.get(socketId) || [];
15626
+ const message = {
15627
+ id: getId(`${socketId}-message`),
15628
+ direction: "sent",
15629
+ data: eventData.data,
15630
+ messageType: eventData.messageType,
15631
+ timestamp: eventData.timestamp
15632
+ };
15633
+ const newMessages = new Map(state.websocketMessages);
15634
+ newMessages.set(
15635
+ socketId,
15636
+ [...currentMessages, message].slice(
15637
+ -32
15638
+ )
15639
+ );
15640
+ return { websocketMessages: newMessages };
15641
+ });
15642
+ break;
15643
+ }
15644
+ case "websocket-message-received": {
15645
+ const eventData = data;
15646
+ set((state) => {
15647
+ const socketId = `ws-${eventData.socketId}`;
15648
+ const currentMessages = state.websocketMessages.get(socketId) || [];
15649
+ const message = {
15650
+ id: getId(`${socketId}-message`),
15651
+ direction: "received",
15652
+ data: eventData.data,
15653
+ messageType: eventData.messageType,
15654
+ timestamp: eventData.timestamp
15655
+ };
15656
+ const newMessages = new Map(state.websocketMessages);
15657
+ newMessages.set(
15658
+ socketId,
15659
+ [...currentMessages, message].slice(
15660
+ -32
15661
+ )
15662
+ );
15663
+ return { websocketMessages: newMessages };
15664
+ });
15665
+ break;
15666
+ }
15667
+ case "websocket-error": {
15668
+ const eventData = data;
15669
+ set((state) => {
15670
+ const entry = state.networkEntries.get(
15671
+ `ws-${eventData.socketId}`
15672
+ );
15673
+ if (!entry || entry.type !== "websocket") return state;
15674
+ const wsEntry = entry;
15675
+ const updatedEntry = {
15676
+ ...wsEntry,
15677
+ status: "error",
15678
+ error: eventData.error
15679
+ };
15680
+ const newEntries = new Map(state.networkEntries);
15681
+ newEntries.set(entry.id, updatedEntry);
15682
+ return { networkEntries: newEntries };
15683
+ });
15684
+ break;
15685
+ }
15686
+ case "websocket-connection-status-changed": {
15687
+ const eventData = data;
15688
+ set((state) => {
15689
+ const entry = state.networkEntries.get(
15690
+ `ws-${eventData.socketId}`
15691
+ );
15692
+ if (!entry || entry.type !== "websocket") return state;
15693
+ const wsEntry = entry;
15694
+ const updatedEntry = {
15695
+ ...wsEntry,
15696
+ status: eventData.status
15697
+ };
15698
+ const newEntries = new Map(state.networkEntries);
15699
+ newEntries.set(entry.id, updatedEntry);
15700
+ return { networkEntries: newEntries };
15701
+ });
15702
+ break;
15703
+ }
15704
+ case "sse-open": {
15705
+ const eventData = data;
15706
+ set((state) => {
15707
+ const entry = state.networkEntries.get(eventData.requestId);
15708
+ if (!entry || entry.type !== "http") return state;
15709
+ const httpEntry = entry;
15710
+ const sseEntry = {
15711
+ ...httpEntry,
15712
+ type: "sse",
15713
+ // Change type from 'http' to 'sse'
15714
+ status: "open",
15715
+ // Update status
15716
+ messages: [],
15717
+ // Add SSE-specific field
15718
+ response: eventData.response
15719
+ };
15720
+ const newEntries = new Map(state.networkEntries);
15721
+ newEntries.set(eventData.requestId, sseEntry);
15722
+ return { networkEntries: newEntries };
15723
+ });
15724
+ break;
15725
+ }
15726
+ case "sse-message": {
15727
+ const eventData = data;
15728
+ set((state) => {
15729
+ const entry = state.networkEntries.get(eventData.requestId);
15730
+ if (!entry || entry.type !== "sse") return state;
15731
+ const sseEntry = entry;
15732
+ const newMessage = {
15733
+ id: getId(`${eventData.requestId}-message`),
15734
+ type: eventData.payload.type,
15735
+ data: eventData.payload.data,
15736
+ timestamp: eventData.timestamp
15737
+ };
15738
+ const updatedEntry = {
15739
+ ...sseEntry,
15740
+ messages: [...sseEntry.messages, newMessage].slice(
15741
+ -32
15742
+ )
15743
+ };
15744
+ const newEntries = new Map(state.networkEntries);
15745
+ newEntries.set(eventData.requestId, updatedEntry);
15746
+ return { networkEntries: newEntries };
15747
+ });
15748
+ break;
15749
+ }
15750
+ case "sse-error": {
15751
+ const eventData = data;
15752
+ set((state) => {
15753
+ const entry = state.networkEntries.get(eventData.requestId);
15754
+ if (!entry || entry.type !== "sse") return state;
15755
+ const sseEntry = entry;
15756
+ const updatedEntry = {
15757
+ ...sseEntry,
15758
+ status: "error",
15759
+ error: eventData.error.message
15760
+ };
15761
+ const newEntries = new Map(state.networkEntries);
15762
+ newEntries.set(eventData.requestId, updatedEntry);
15763
+ return { networkEntries: newEntries };
15764
+ });
15765
+ break;
15766
+ }
15767
+ case "sse-close": {
15768
+ const eventData = data;
15769
+ set((state) => {
15770
+ const entry = state.networkEntries.get(eventData.requestId);
15771
+ if (!entry || entry.type !== "sse") return state;
15772
+ const sseEntry = entry;
15773
+ const updatedEntry = {
15774
+ ...sseEntry,
15775
+ status: "closed",
15776
+ duration: eventData.timestamp - sseEntry.timestamp
15777
+ };
15778
+ const newEntries = new Map(state.networkEntries);
15779
+ newEntries.set(eventData.requestId, updatedEntry);
15780
+ return { networkEntries: newEntries };
15781
+ });
15782
+ break;
15783
+ }
15784
+ }
15785
+ },
15786
+ // Client management
15787
+ client: {
15788
+ setupClient: (client2) => {
15789
+ const { handleEvent } = get();
15790
+ const unsubscribeFunctions = [
15791
+ client2.onMessage(
15792
+ "request-sent",
15793
+ (data) => handleEvent("request-sent", data)
15794
+ ),
15795
+ client2.onMessage(
15796
+ "response-received",
15797
+ (data) => handleEvent("response-received", data)
15798
+ ),
15799
+ client2.onMessage(
15800
+ "request-completed",
15801
+ (data) => handleEvent("request-completed", data)
15802
+ ),
15803
+ client2.onMessage(
15804
+ "request-failed",
15805
+ (data) => handleEvent("request-failed", data)
15806
+ ),
15807
+ client2.onMessage(
15808
+ "response-body",
15809
+ (data) => handleEvent("response-body", data)
15810
+ ),
15811
+ client2.onMessage(
15812
+ "websocket-connect",
15813
+ (data) => handleEvent("websocket-connect", data)
15814
+ ),
15815
+ client2.onMessage(
15816
+ "websocket-open",
15817
+ (data) => handleEvent("websocket-open", data)
15818
+ ),
15819
+ client2.onMessage(
15820
+ "websocket-close",
15821
+ (data) => handleEvent("websocket-close", data)
15822
+ ),
15823
+ client2.onMessage(
15824
+ "websocket-message-sent",
15825
+ (data) => handleEvent("websocket-message-sent", data)
15826
+ ),
15827
+ client2.onMessage(
15828
+ "websocket-message-received",
15829
+ (data) => handleEvent("websocket-message-received", data)
15830
+ ),
15831
+ client2.onMessage(
15832
+ "websocket-error",
15833
+ (data) => handleEvent("websocket-error", data)
15834
+ ),
15835
+ client2.onMessage(
15836
+ "websocket-connection-status-changed",
15837
+ (data) => handleEvent("websocket-connection-status-changed", data)
15838
+ ),
15839
+ client2.onMessage(
15840
+ "sse-open",
15841
+ (data) => handleEvent("sse-open", data)
15842
+ ),
15843
+ client2.onMessage(
15844
+ "sse-message",
15845
+ (data) => handleEvent("sse-message", data)
15846
+ ),
15847
+ client2.onMessage(
15848
+ "sse-error",
15849
+ (data) => handleEvent("sse-error", data)
15850
+ ),
15851
+ client2.onMessage(
15852
+ "sse-close",
15853
+ (data) => handleEvent("sse-close", data)
15510
15854
  )
15511
- };
15512
- const newEntries = new Map(state.networkEntries);
15513
- newEntries.set(eventData.requestId, updatedEntry);
15514
- return { networkEntries: newEntries };
15515
- });
15516
- break;
15517
- }
15518
- case "sse-error": {
15519
- const eventData = data;
15520
- set((state) => {
15521
- const entry = state.networkEntries.get(eventData.requestId);
15522
- if (!entry || entry.type !== "sse") return state;
15523
- const sseEntry = entry;
15524
- const updatedEntry = {
15525
- ...sseEntry,
15526
- status: "error",
15527
- error: eventData.error.message
15528
- };
15529
- const newEntries = new Map(state.networkEntries);
15530
- newEntries.set(eventData.requestId, updatedEntry);
15531
- return { networkEntries: newEntries };
15532
- });
15533
- break;
15534
- }
15535
- case "sse-close": {
15536
- const eventData = data;
15537
- set((state) => {
15538
- const entry = state.networkEntries.get(eventData.requestId);
15539
- if (!entry || entry.type !== "sse") return state;
15540
- const sseEntry = entry;
15541
- const updatedEntry = {
15542
- ...sseEntry,
15543
- status: "closed",
15544
- duration: eventData.timestamp - sseEntry.timestamp
15545
- };
15546
- const newEntries = new Map(state.networkEntries);
15547
- newEntries.set(eventData.requestId, updatedEntry);
15548
- return { networkEntries: newEntries };
15549
- });
15550
- break;
15551
- }
15552
- }
15553
- },
15554
- // Client management
15555
- client: {
15556
- setupClient: (client2) => {
15557
- const { handleEvent } = get();
15558
- const unsubscribeFunctions = [
15559
- client2.onMessage(
15560
- "request-sent",
15561
- (data) => handleEvent("request-sent", data)
15562
- ),
15563
- client2.onMessage(
15564
- "response-received",
15565
- (data) => handleEvent("response-received", data)
15566
- ),
15567
- client2.onMessage(
15568
- "request-completed",
15569
- (data) => handleEvent("request-completed", data)
15570
- ),
15571
- client2.onMessage(
15572
- "request-failed",
15573
- (data) => handleEvent("request-failed", data)
15574
- ),
15575
- client2.onMessage(
15576
- "response-body",
15577
- (data) => handleEvent("response-body", data)
15578
- ),
15579
- client2.onMessage(
15580
- "websocket-connect",
15581
- (data) => handleEvent("websocket-connect", data)
15582
- ),
15583
- client2.onMessage(
15584
- "websocket-open",
15585
- (data) => handleEvent("websocket-open", data)
15586
- ),
15587
- client2.onMessage(
15588
- "websocket-close",
15589
- (data) => handleEvent("websocket-close", data)
15590
- ),
15591
- client2.onMessage(
15592
- "websocket-message-sent",
15593
- (data) => handleEvent("websocket-message-sent", data)
15594
- ),
15595
- client2.onMessage(
15596
- "websocket-message-received",
15597
- (data) => handleEvent("websocket-message-received", data)
15598
- ),
15599
- client2.onMessage(
15600
- "websocket-error",
15601
- (data) => handleEvent("websocket-error", data)
15602
- ),
15603
- client2.onMessage(
15604
- "websocket-connection-status-changed",
15605
- (data) => handleEvent("websocket-connection-status-changed", data)
15606
- ),
15607
- client2.onMessage("sse-open", (data) => handleEvent("sse-open", data)),
15608
- client2.onMessage(
15609
- "sse-message",
15610
- (data) => handleEvent("sse-message", data)
15611
- ),
15612
- client2.onMessage(
15613
- "sse-error",
15614
- (data) => handleEvent("sse-error", data)
15615
- ),
15616
- client2.onMessage(
15617
- "sse-close",
15618
- (data) => handleEvent("sse-close", data)
15619
- )
15620
- ];
15621
- set({
15622
- _unsubscribeFunctions: unsubscribeFunctions,
15623
- _client: client2
15624
- });
15625
- },
15626
- cleanupClient: () => {
15627
- const { _unsubscribeFunctions, _client } = get();
15628
- if (_unsubscribeFunctions) {
15629
- _unsubscribeFunctions.forEach(
15630
- (unsubscribe) => unsubscribe.remove()
15631
- );
15632
- }
15633
- if (_client) {
15634
- _client.send("network-disable", {});
15855
+ ];
15856
+ set({
15857
+ _unsubscribeFunctions: unsubscribeFunctions,
15858
+ _client: client2
15859
+ });
15860
+ },
15861
+ cleanupClient: () => {
15862
+ const { _unsubscribeFunctions, _client } = get();
15863
+ if (_unsubscribeFunctions) {
15864
+ _unsubscribeFunctions.forEach(
15865
+ (unsubscribe) => unsubscribe.remove()
15866
+ );
15867
+ }
15868
+ if (_client) {
15869
+ _client.send("network-disable", {});
15870
+ }
15871
+ set({
15872
+ _unsubscribeFunctions: void 0,
15873
+ _client: void 0
15874
+ });
15875
+ }
15635
15876
  }
15636
- set({
15637
- _unsubscribeFunctions: void 0,
15638
- _client: void 0
15639
- });
15877
+ }),
15878
+ {
15879
+ name: "rozenite-network-activity-storage",
15880
+ version: STORE_VERSION,
15881
+ storage: createJSONStorage(() => localStorage, {
15882
+ replacer: (key, value) => {
15883
+ if (value instanceof Map) {
15884
+ return {
15885
+ _type: "map",
15886
+ value: Array.from(value.entries())
15887
+ };
15888
+ }
15889
+ return value;
15890
+ },
15891
+ reviver: (key, value) => {
15892
+ if (typeof value === "object" && value !== null && value._type === "map") {
15893
+ return new Map(value.value);
15894
+ }
15895
+ return value;
15896
+ }
15897
+ }),
15898
+ partialize: (state) => ({ overrides: state.overrides })
15899
+ // Persist only the overrides
15640
15900
  }
15641
- }
15642
- }));
15901
+ )
15902
+ );
15643
15903
  const store = createNetworkActivityStore();
15644
15904
  const TRACK_MEMO_SYMBOL = Symbol();
15645
15905
  const GET_ORIGINAL_SYMBOL = Symbol();
@@ -15998,6 +16258,9 @@ const useWebSocketMessages = (requestId) => {
15998
16258
  (state) => state.websocketMessages.get(requestId) || []
15999
16259
  );
16000
16260
  };
16261
+ const useOverrides = () => {
16262
+ return useNetworkActivityStore((state) => state.overrides);
16263
+ };
16001
16264
  const Toolbar = () => {
16002
16265
  const actions = useNetworkActivityActions();
16003
16266
  const isRecording = useIsRecording();
@@ -18875,10 +19138,11 @@ const sortTime = (rowA, rowB, columnId) => {
18875
19138
  };
18876
19139
  return getNumericValue(a) - getNumericValue(b);
18877
19140
  };
18878
- const processNetworkRequests = (processedRequests) => {
19141
+ const processNetworkRequests = (processedRequests, overrides) => {
18879
19142
  return processedRequests.map((request) => {
18880
19143
  const { domain, path } = extractDomainAndPath(request.name);
18881
19144
  const duration = request.duration || 0;
19145
+ const hasOverride = overrides.has(request.name);
18882
19146
  return {
18883
19147
  id: request.id,
18884
19148
  name: generateName(request.name),
@@ -18889,7 +19153,8 @@ const processNetworkRequests = (processedRequests) => {
18889
19153
  size: isNumber(request.size) ? formatSize(request.size) : "—",
18890
19154
  time: formatDuration(duration),
18891
19155
  type: request.type,
18892
- startTime: formatStartTime(request.timestamp)
19156
+ startTime: formatStartTime(request.timestamp),
19157
+ hasOverride
18893
19158
  };
18894
19159
  });
18895
19160
  };
@@ -18903,14 +19168,10 @@ const columns$1 = [
18903
19168
  }),
18904
19169
  columnHelper$2.accessor("name", {
18905
19170
  header: "Name",
18906
- cell: ({ row, getValue: getValue2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
18907
- "div",
18908
- {
18909
- className: "flex-1 min-w-0 truncate",
18910
- title: row.original.path,
18911
- children: getValue2()
18912
- }
18913
- ),
19171
+ cell: ({ row, getValue: getValue2 }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 truncate", title: row.original.path, children: [
19172
+ getValue2(),
19173
+ row.original.hasOverride && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-2 h-2 rounded-full bg-violet-300 ms-2 inline-block" })
19174
+ ] }),
18914
19175
  sortingFn: "alphanumeric"
18915
19176
  }),
18916
19177
  columnHelper$2.accessor("status", {
@@ -18951,6 +19212,7 @@ const RequestList = ({ filter: filter2 }) => {
18951
19212
  const processedRequests = useProcessedRequests();
18952
19213
  const selectedRequestId = useSelectedRequestId();
18953
19214
  const [sorting, setSorting] = reactExports.useState([]);
19215
+ const overrides = useOverrides();
18954
19216
  const filteredRequests = reactExports.useMemo(() => {
18955
19217
  return processedRequests.filter((request) => {
18956
19218
  if (!filter2.types.has(request.type)) {
@@ -18969,8 +19231,8 @@ const RequestList = ({ filter: filter2 }) => {
18969
19231
  });
18970
19232
  }, [processedRequests, filter2]);
18971
19233
  const requests = reactExports.useMemo(() => {
18972
- return processNetworkRequests(filteredRequests);
18973
- }, [filteredRequests]);
19234
+ return processNetworkRequests(filteredRequests, overrides);
19235
+ }, [filteredRequests, overrides]);
18974
19236
  const table = useReactTable({
18975
19237
  data: requests,
18976
19238
  columns: columns$1,
@@ -20584,7 +20846,8 @@ ScrollBar.displayName = ScrollAreaScrollbar.displayName;
20584
20846
  const Section = ({
20585
20847
  title,
20586
20848
  children,
20587
- collapsible = true
20849
+ collapsible = true,
20850
+ action
20588
20851
  }) => {
20589
20852
  const [isCollapsed, setIsCollapsed] = reactExports.useState(false);
20590
20853
  const isChildrenVisible = !collapsible || !isCollapsed;
@@ -20601,7 +20864,8 @@ const Section = ({
20601
20864
  tabIndex: collapsible ? 0 : -1,
20602
20865
  children: [
20603
20866
  collapsible && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("mr-2", { "rotate-90": !isCollapsed }), children: "▶" }),
20604
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: title })
20867
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium me-auto", children: title }),
20868
+ action
20605
20869
  ]
20606
20870
  }
20607
20871
  ),
@@ -29416,8 +29680,139 @@ const RequestTab = ({ selectedRequest }) => {
29416
29680
  !hasQueryParams && !requestBody && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-400", children: "No request body or query params for this request" })
29417
29681
  ] }) });
29418
29682
  };
29419
- const renderResponseBodySection = (children) => {
29420
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Section, { title: "Response Body", collapsible: false, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children }) });
29683
+ const CodeEditor = reactExports.forwardRef(
29684
+ ({ data, onInput }, ref) => {
29685
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
29686
+ "pre",
29687
+ {
29688
+ ref,
29689
+ contentEditable: true,
29690
+ suppressContentEditableWarning: true,
29691
+ className: "w-full text-sm font-mono text-gray-300 whitespace-pre-wrap bg-gray-800 p-3 rounded-md border border-gray-700 overflow-x-auto wrap-anywhere ring-offset-blue-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
29692
+ onInput,
29693
+ children: data
29694
+ }
29695
+ );
29696
+ }
29697
+ );
29698
+ CodeEditor.displayName = "CodeEditor";
29699
+ const OverrideResponse = ({
29700
+ selectedRequest,
29701
+ initialOverride,
29702
+ onClear
29703
+ }) => {
29704
+ var _a;
29705
+ const actions = useNetworkActivityActions();
29706
+ const [savedOverride, setSavedOverride] = reactExports.useState(initialOverride);
29707
+ const [editedBody, setEditedBody] = reactExports.useState(
29708
+ initialOverride == null ? void 0 : initialOverride.body
29709
+ );
29710
+ const [editedStatus, setEditedStatus] = reactExports.useState(
29711
+ initialOverride == null ? void 0 : initialOverride.status
29712
+ );
29713
+ const responseEditorRef = reactExports.useRef(null);
29714
+ const responseBody = (_a = selectedRequest.response) == null ? void 0 : _a.body;
29715
+ const saveOverride = () => {
29716
+ if (editedBody === void 0 && editedStatus === void 0) return;
29717
+ const newOverrideData = {
29718
+ body: editedBody,
29719
+ status: editedStatus
29720
+ };
29721
+ setSavedOverride(newOverrideData);
29722
+ actions.addOverride(selectedRequest.request.url, newOverrideData);
29723
+ };
29724
+ const clearOverride = () => {
29725
+ setSavedOverride(void 0);
29726
+ setEditedBody(void 0);
29727
+ actions.clearOverride(selectedRequest.request.url);
29728
+ onClear();
29729
+ };
29730
+ if (!responseBody || responseBody.data === null) {
29731
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-400", children: "No response body available for this request" });
29732
+ }
29733
+ const { type } = responseBody;
29734
+ const hasChanges = editedBody !== (savedOverride == null ? void 0 : savedOverride.body) || editedStatus !== (savedOverride == null ? void 0 : savedOverride.status);
29735
+ const overrideActions = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
29736
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
29737
+ Button,
29738
+ {
29739
+ variant: "ghost",
29740
+ size: "xs",
29741
+ className: "text-violet-300 hover:text-violet-300 ms-2",
29742
+ onClick: clearOverride,
29743
+ children: [
29744
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleSlash2, { className: "h-2 w-2" }),
29745
+ "Clear override"
29746
+ ]
29747
+ }
29748
+ ),
29749
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
29750
+ Button,
29751
+ {
29752
+ variant: "ghost",
29753
+ size: "xs",
29754
+ className: "text-violet-300 hover:text-violet-300",
29755
+ onClick: saveOverride,
29756
+ disabled: !hasChanges,
29757
+ children: [
29758
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "h-2 w-2" }),
29759
+ hasChanges ? "Save override" : "Saved"
29760
+ ]
29761
+ }
29762
+ )
29763
+ ] });
29764
+ if (savedOverride !== void 0) {
29765
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
29766
+ Section,
29767
+ {
29768
+ title: "Response Body",
29769
+ collapsible: false,
29770
+ action: overrideActions,
29771
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
29772
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29773
+ KeyValueGrid,
29774
+ {
29775
+ items: [
29776
+ {
29777
+ key: "Content-Type",
29778
+ value: type,
29779
+ valueClassName: "text-blue-400"
29780
+ }
29781
+ ]
29782
+ }
29783
+ ),
29784
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[minmax(7rem,25%)_minmax(3rem,1fr)] gap-x-2 gap-y-2 text-sm", children: [
29785
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400 wrap-anywhere", children: "Status Code" }),
29786
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29787
+ "input",
29788
+ {
29789
+ type: "number",
29790
+ value: editedStatus,
29791
+ onChange: (e) => {
29792
+ setEditedStatus(parseInt(e.target.value));
29793
+ },
29794
+ className: "max-w-24 font-mono text-gray-300 whitespace-pre-wrap bg-gray-800 p-1 rounded-md border border-gray-700 overflow-x-auto wrap-anywhere ring-offset-blue-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
29795
+ }
29796
+ )
29797
+ ] }),
29798
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
29799
+ CodeEditor,
29800
+ {
29801
+ data: savedOverride == null ? void 0 : savedOverride.body,
29802
+ ref: responseEditorRef,
29803
+ onInput: (e) => setEditedBody(e.currentTarget.innerText)
29804
+ }
29805
+ )
29806
+ ] })
29807
+ }
29808
+ );
29809
+ }
29810
+ };
29811
+ const RenderResponseBodySection = ({
29812
+ children,
29813
+ action
29814
+ }) => {
29815
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Section, { title: "Response Body", collapsible: false, action, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children }) });
29421
29816
  };
29422
29817
  const ResponseTab = ({
29423
29818
  selectedRequest,
@@ -29425,6 +29820,11 @@ const ResponseTab = ({
29425
29820
  }) => {
29426
29821
  var _a;
29427
29822
  const onRequestResponseBodyRef = reactExports.useRef(onRequestResponseBody);
29823
+ const overrides = useOverrides();
29824
+ const [initialOverride, setInitialOverride] = reactExports.useState(() => {
29825
+ const override = overrides.get(selectedRequest.request.url);
29826
+ return override;
29827
+ });
29428
29828
  reactExports.useEffect(() => {
29429
29829
  onRequestResponseBodyRef.current = onRequestResponseBody;
29430
29830
  }, [onRequestResponseBody]);
@@ -29435,10 +29835,12 @@ const ResponseTab = ({
29435
29835
  }, [selectedRequest.id]);
29436
29836
  const responseBody = (_a = selectedRequest.response) == null ? void 0 : _a.body;
29437
29837
  const renderResponseBody = () => {
29838
+ var _a2;
29438
29839
  if (!responseBody || responseBody.data === null) {
29439
29840
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-400", children: "No response body available for this request" });
29440
29841
  }
29441
29842
  const { type, data } = responseBody;
29843
+ const statusCode = (_a2 = selectedRequest.response) == null ? void 0 : _a2.status;
29442
29844
  const contentTypeGrid = /* @__PURE__ */ jsxRuntimeExports.jsx(
29443
29845
  KeyValueGrid,
29444
29846
  {
@@ -29451,6 +29853,32 @@ const ResponseTab = ({
29451
29853
  ]
29452
29854
  }
29453
29855
  );
29856
+ const overrideAction = /* @__PURE__ */ jsxRuntimeExports.jsxs(
29857
+ Button,
29858
+ {
29859
+ variant: "ghost",
29860
+ size: "xs",
29861
+ className: "text-violet-300 hover:text-violet-300",
29862
+ onClick: () => setInitialOverride({
29863
+ body: data,
29864
+ status: statusCode
29865
+ }),
29866
+ children: [
29867
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "h-2 w-2" }),
29868
+ "Override"
29869
+ ]
29870
+ }
29871
+ );
29872
+ if (initialOverride !== void 0) {
29873
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
29874
+ OverrideResponse,
29875
+ {
29876
+ selectedRequest,
29877
+ initialOverride,
29878
+ onClear: () => setInitialOverride(void 0)
29879
+ }
29880
+ );
29881
+ }
29454
29882
  if (type.startsWith("application/json")) {
29455
29883
  let bodyContent;
29456
29884
  try {
@@ -29462,31 +29890,25 @@ const ResponseTab = ({
29462
29890
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 mt-1", children: "⚠️ Failed to parse as JSON, showing as raw text" })
29463
29891
  ] });
29464
29892
  }
29465
- return renderResponseBodySection(
29466
- /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
29467
- contentTypeGrid,
29468
- bodyContent
29469
- ] })
29470
- );
29893
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(RenderResponseBodySection, { action: overrideAction, children: [
29894
+ contentTypeGrid,
29895
+ bodyContent
29896
+ ] });
29471
29897
  }
29472
29898
  if (type.startsWith("text/") || type.startsWith("application/xml") || type.startsWith("application/javascript")) {
29473
- return renderResponseBodySection(
29474
- /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
29475
- contentTypeGrid,
29476
- /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { children: data })
29477
- ] })
29478
- );
29479
- }
29480
- return renderResponseBodySection(
29481
- /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
29899
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(RenderResponseBodySection, { action: overrideAction, children: [
29482
29900
  contentTypeGrid,
29483
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-gray-400", children: [
29484
- "Binary content not shown - ",
29485
- data.length,
29486
- " bytes"
29487
- ] })
29901
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { children: data })
29902
+ ] });
29903
+ }
29904
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(RenderResponseBodySection, { children: [
29905
+ contentTypeGrid,
29906
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-gray-400", children: [
29907
+ "Binary content not shown - ",
29908
+ data.length,
29909
+ " bytes"
29488
29910
  ] })
29489
- );
29911
+ ] });
29490
29912
  };
29491
29913
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "h-full w-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: renderResponseBody() }) });
29492
29914
  };
@@ -30052,6 +30474,7 @@ const SidePanel = () => {
30052
30474
  const actions = useNetworkActivityActions();
30053
30475
  const selectedRequest = useSelectedRequest();
30054
30476
  const client2 = useNetworkActivityStore((state) => state._client);
30477
+ const overrides = useOverrides();
30055
30478
  const onClose = () => {
30056
30479
  actions.setSelectedRequest(null);
30057
30480
  };
@@ -30072,6 +30495,8 @@ const SidePanel = () => {
30072
30495
  if (legacyEntry) {
30073
30496
  legacyNetworkEntries.set(legacyEntry.requestId, legacyEntry);
30074
30497
  }
30498
+ const override = legacyEntry !== null ? overrides.get(legacyEntry.url) : null;
30499
+ const hasResponseOverride = override && override.body ? true : false;
30075
30500
  const getTabsListTriggers = () => {
30076
30501
  if (httpDetails) {
30077
30502
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
@@ -30091,12 +30516,15 @@ const SidePanel = () => {
30091
30516
  children: "Request"
30092
30517
  }
30093
30518
  ),
30094
- /* @__PURE__ */ jsxRuntimeExports.jsx(
30519
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
30095
30520
  TabsTrigger,
30096
30521
  {
30097
30522
  value: "response",
30098
30523
  className: "data-[state=active]:bg-gray-700",
30099
- children: "Response"
30524
+ children: [
30525
+ "Response",
30526
+ hasResponseOverride && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-2 h-2 rounded-full bg-violet-300 ms-2 inline-block" })
30527
+ ]
30100
30528
  }
30101
30529
  ),
30102
30530
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -30335,6 +30763,7 @@ const InspectorView = ({ client: client2 }) => {
30335
30763
  const actions = useNetworkActivityActions();
30336
30764
  const clientManagement = useNetworkActivityClientManagement();
30337
30765
  const hasSelectedRequest = useHasSelectedRequest();
30766
+ const overrides = useOverrides();
30338
30767
  const [filter2, setFilter] = reactExports.useState({
30339
30768
  text: "",
30340
30769
  types: /* @__PURE__ */ new Set(["http", "websocket", "sse"])
@@ -30345,11 +30774,14 @@ const InspectorView = ({ client: client2 }) => {
30345
30774
  }
30346
30775
  clientManagement.setupClient(client2);
30347
30776
  actions.setRecording(true);
30777
+ client2.send("set-overrides", {
30778
+ overrides: Array.from(overrides.entries())
30779
+ });
30348
30780
  return () => {
30349
30781
  actions.setRecording(false);
30350
30782
  clientManagement.cleanupClient();
30351
30783
  };
30352
- }, [client2, clientManagement, actions]);
30784
+ }, [client2, clientManagement, actions, overrides]);
30353
30785
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-screen bg-gray-900 text-gray-100 flex flex-col", children: [
30354
30786
  /* @__PURE__ */ jsxRuntimeExports.jsx(Toolbar, {}),
30355
30787
  /* @__PURE__ */ jsxRuntimeExports.jsx(FilterBar, { filter: filter2, onFilterChange: setFilter }),