Skip to content

Conversation

@dprevost-LMI
Copy link
Contributor

@dprevost-LMI dprevost-LMI commented Nov 15, 2025

Description

Using a queuing mechanism, we can queue boot clients' messages destined to the DevTool and display them once the inspector panel is connected and is ready.

  • I added a generic interface for all the inspectors
  • I use an event listener to switch from a queue to the client, and kept it generic to be reused in other plugins
  • I renamed the former network-inspector to http and created a new network-inspector managing the three types (http, ws,sse)
  • I tried not needing withOnBootNetworkActivityRecording, but I was unable to initialize everything sooner.
  • Align some HTTP code with how SSE and WS were done, like the events in a separate type and file.

TODO

  • revert code added temporarily to have a working playground
  • Add official docs
  • Review if we keep laststart and in progress event....
  • Review last TODOs
  • Test without the withOnBootNetworkActivityRecording
  • Review implementation following code review change request

Related Issue

See #82

Context

We heavily rely on the WebSocket and HTTP requests on boot for our enterprise app, so we totally need this feature, so I took a go for it.

Testing

Tested as below, plus using unit test coverage yet to open in another PR, see preview in this PR

Screen.Recording.2025-11-15.at.6.54.19.PM.mov

Note

Adds boot-time HTTP request capture via a queued client and withOnBootNetworkActivityRecording, includes progress/timeout support and UI updates, plus docs and playground examples.

  • Network Activity Plugin (core):
    • Boot-time capture: New withOnBootNetworkActivityRecording and queued client (queued-client-wrapper) to buffer events before DevTools connects; network-inspector updated to flush queue on enable.
    • Refactor: Extract per-request logic to request-tracker (tracking, overrides, response body helpers).
    • Events: Add request-progress (with loaded/total), handle timeout; wire through store (model, derived, store) and client (shared/client).
    • UI: RequestList shows in-progress percent; Toolbar swaps record/stop icon logic and adds tooltip; default recording enabled.
  • Playground:
    • Extract real API to apps/.../utils/network-activity/api.ts; add "Large File" download flow using api.getLargeFile and UI tab; main.tsx enables on-boot recording and triggers sample requests.
  • Docs:
    • Update README and website to document boot-time recording usage.
  • Tooling:
    • Add repo scripts; upgrade Prettier to v3; broaden .prettierignore to **/dist and **/coverage.

Written by Cursor Bugbot for commit 020a939. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Nov 15, 2025

@dprevost-LMI is attempting to deploy a commit to the Callstack Team on Vercel.

A member of the Team first needs to authorize it.

@V3RON
Copy link
Contributor

V3RON commented Nov 15, 2025

Unfortunately, it's not going to work in some cases. There is a slight delay between the client becoming available and the other side being ready to accept messages. In other words, useRozeniteDevToolsClient may return a client instance and allow you to send messages, but the other side may not be listening yet.

I need to refactor the bridge to include some sort of handshake mechanism so both sides can confirm that they’re ready to handle communication correctly.

@dprevost-LMI
Copy link
Contributor Author

Unfortunately, it's not going to work in some cases. There is a slight delay between the client becoming available and the other side being ready to accept messages. In other words, useRozeniteDevToolsClient may return a client instance and allow you to send messages, but the other side may not be listening yet.

I need to refactor the bridge to include some sort of handshake mechanism so both sides can confirm that they’re ready to handle communication correctly.

I performed a few iterations and flushed the queue when I received the network-enable signal.
For sure, having a "more intelligent" client would be better across the board

@dprevost-LMI dprevost-LMI changed the title feat(network-activity-plugin): draft show network requests on boot feat(network-activity-plugin): show network requests on boot Nov 16, 2025
@dprevost-LMI
Copy link
Contributor Author

I have reached a point where this solution, although not entirely finalized, is the one I suggest.
After that, a fully persisted solution would be the next step!

@dprevost-LMI dprevost-LMI changed the title feat(network-activity-plugin): show network requests on boot feat(network-activity-plugin): show http network requests on boot Nov 16, 2025
@dprevost-LMI dprevost-LMI marked this pull request as ready for review November 16, 2025 16:04
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bug: HTTP Inspector Fails to Auto-Enable Recording

The HTTP network inspector is never automatically enabled when the component mounts, even though isRecording defaults to true in the store. The removed code that checked isRecordingEnabledRef.current and called networkInspector.enable() was necessary to enable the inspector on initial mount and after hot reloads. WebSocket and SSE inspectors still have this logic (lines 121-123 and 159-161), creating an inconsistency where HTTP requests won't be captured until the user manually toggles recording, while WebSocket and SSE connections will be captured automatically.

packages/network-activity-plugin/src/react-native/useNetworkActivityDevTools.ts#L78-L89

useEffect(() => {
if (!client || !isHttpInspectorEnabled) {
return;
}
const networkInspector = getNetworkInspector(client);
return () => {
networkInspector.dispose();
};
}, [client, isHttpInspectorEnabled]);

Fix in Cursor Fix in Web


Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@dprevost-LMI dprevost-LMI marked this pull request as draft November 16, 2025 19:02
@dprevost-LMI dprevost-LMI force-pushed the show-network-requests-on-boot branch 2 times, most recently from 0ba0550 to 319ce0c Compare November 16, 2025 19:17
@dprevost-LMI dprevost-LMI marked this pull request as ready for review November 16, 2025 22:02
Copy link
Contributor

@V3RON V3RON left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request includes not only recording network traffic on boot, but also changing the way how 'long requests' are displayed (status with progress). Please clean it up, so only a single feature remains.

For the implementation, instead of combining traffic inspection and queueing logic, I suggest the following approach:
a) refactor inspectors to share the same API (emit events)
b) provide a special type of an inspector accumulating events and flushing them on demand
c) detect the presence of 'queued inspector' and flush events when plugin client is ready (in practice, when DevTools UI sends some kind of 'hello' message)

type Inspector<TEventMap> = {
  enable: () => void;
  disable: () => void;
  on<TEventType extends keyof TEventMap(type: TEventType, callback: (event: TEventMap[TEventType]) => void);
  on(type: '*', callback: (event: TEventMap[keyof TEventMap]) => void);
};

type NetworkInspector = Inspector<NetworkEventMap>;

type QueuedInspector = Inspector & {
  flush: () => void;
};

const networkInspector = createRozeniteNetworkInspector({
  recordOnBoot: true,
});
const websocketInspector = createRozeniteWebSocketInespector();

const useNetworkActivityDevTools = ({ inspectors }) => {
  const pluginClient = useRozeniteDevToolsClient({ pluginId: '...' });
  useEffect(() => {
    inspectors.forEach((inspector) => {
      inspector.on('*', (event) => pluginClient.send(event.type, event));
      
      if ('flush' in inspector) {
        inspector.flush();
      }
    });
  }, [inspectors, pluginClient]);
}

const App = () => {
  useNetworkActivityDevTools({
    inspectors: [networkInspector, websocketInspector]
  });
}

Note: this is pseudo-code, not production-ready 😄

In this approach, the inspector only handles inspection and passing data to the listeners. Queuing is not its concern.

@dprevost-LMI
Copy link
Contributor Author

I'll proceed to the change as you requested!

Just so you know: One thing I was thinking about with this queued client is that if we can make it generic enough, it could be exposed as a generic interface, allowing any package to use it directly and be boot-time compliant.

@dprevost-LMI dprevost-LMI marked this pull request as draft November 17, 2025 14:55
@dprevost-LMI dprevost-LMI force-pushed the show-network-requests-on-boot branch from 020a939 to c3a31e1 Compare November 18, 2025 00:56
@dprevost-LMI
Copy link
Contributor Author

dprevost-LMI commented Nov 18, 2025

Please clean it up, so only a single feature remains.

Done, see #147 and also #150

For the implementation, instead of combining traffic inspection and queueing logic, I suggest the following approach:
a) refactor inspectors to share the same API (emit events)
b) provide a special type of an inspector accumulating events and flushing them on demand
c) detect the presence of 'queued inspector' and flush events when plugin client is ready (in practice, when DevTools UI sends some kind of 'hello' message)

a) I think I had partially done it with request-tracker.ts, I'll look again to see how I can do it with network-inspector 🤔.
b) That sounds similar to my queue-client-wrapper, will look to move that into the inspector instead 🤔.
c) That was done in inspector.enable() called when the DevTool is ready, and sends the network-enable

I might reach out to you tomorrow on Discord since it seems blurry in my mind right now!

@dprevost-LMI dprevost-LMI force-pushed the show-network-requests-on-boot branch from c3a31e1 to e6e00f6 Compare November 28, 2025 12:38
@dprevost-LMI
Copy link
Contributor Author

dprevost-LMI commented Nov 29, 2025

@V3RON, seeing that rn 83 will provide a network panel by default (see change logs and screenshots), then I'm not sure that iterating on this solution is a good use of time. So, what I see:

  1. Finishing the solution I provided without significant changes, since, anyway, with RN 83, this plugin will be "dead"
  2. Close the PR and wait on RN 83

What do you think?

Screenshot 2025-11-29 at 6 50 15 AM

After discussion, even though they provide a network, but probably not WebSockets or SSE, then it is worth continuing.

@dprevost-LMI dprevost-LMI force-pushed the show-network-requests-on-boot branch from e6e00f6 to 685f480 Compare December 2, 2025 11:39
@dprevost-LMI dprevost-LMI force-pushed the show-network-requests-on-boot branch from 685f480 to 490734b Compare December 14, 2025 12:13
@dprevost-LMI

This comment was marked as outdated.

@dprevost-LMI dprevost-LMI deleted the show-network-requests-on-boot branch December 17, 2025 00:27
@dprevost-LMI dprevost-LMI restored the show-network-requests-on-boot branch December 17, 2025 00:27
@dprevost-LMI dprevost-LMI reopened this Dec 17, 2025
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mainly renamed to http since the network is broader than HTTP and includes SSE and WS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is new and different from the one before. Now the network inspector manage all 3 types, not just http

isEnabled: () => SSEInterceptor.isInterceptorEnabled(),
dispose: () => {
SSEInterceptor.disableInterception();
eventEmitter.events = {};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove since when toggling the boolean from true => false => true, refresh was required instead of hot reload only

@dprevost-LMI
Copy link
Contributor Author

@V3RON the PR should be ready now:

  1. I added the suggested interface
  2. I use an event-listener, maybe not entirely as you requested, but kept generic to be reused in other plugins
  3. I rename the former network-inspector to http and create a new network-inspector managing the three types (http, ws,sse)
  4. I tried not needing withOnBootNetworkActivityRecording but I was unable to initialize everything sooner.
  5. Align some HTTP code with how SSE and WS were done, like the events in a separate type and file.

@dprevost-LMI dprevost-LMI marked this pull request as ready for review December 17, 2025 03:06
dprevost-LMI and others added 11 commits December 20, 2025 14:32
1. Still not fully align with changes request
2. Now include also sse and ws not just http
3. All inspectors are more aligned now and the network one was rename to http
4. Instead of a queue client, we use an event listener that queues and then switch to sending with tje client when available and "connect" in the hook
5. Still draft but tested and working
6. Unfinished: try to use the type suggested, review the solution if we can align it more with the changes requested
1. Use shared inspectorConfig between hook and the boot config
2. Have event-listener disabled by default and enable when withOnBootNetworkActivityRecording is called
3. Simplify the setup code phase
1. Use `withOnBootNetworkActivityRecording` in App.tsx since it is imported in main.tsx
2. Streamline the setup of all inspectors and keep only `setupXXInspector` function
…spector

1. align the http events as we had with sse & ws
2.  Have all 3 http,ws and sse under the network-inspector unbrella
3. Move some http logic from network inspector to http inspector
4. Fix issue where toggling http or sse ot ws from true false true was not showing anymore in DevTools
@dprevost-LMI dprevost-LMI force-pushed the show-network-requests-on-boot branch from a007533 to b1fffc1 Compare December 20, 2025 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants