Skip to content

Conversation

@dprevost-LMI
Copy link
Contributor

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

Description

Using a queuing mechanism, we can keep booting requests and display them when the inspector panel is ready.

Other:

  • I inverted the record red button and the stop button + added a tooltip on it since they were confusing me (let me know if this is incorrect) (TODO move into a separate PR)
  • I separated the logic to track a single request into the request-tracker.ts file.
  • I try to implement a queue messages client so that it is generic enough to be extracted and plug-and-play with other packages having the same needs

Out of scope:

  • SSE and Websocket were not considered yet; if this solution is adopted, then considering the rest will be an option.

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

Final solution

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.

Comment on lines 2 to 3
**/dist
**/coverage
Copy link
Contributor Author

@dprevost-LMI dprevost-LMI Nov 15, 2025

Choose a reason for hiding this comment

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

To revert, waiting on the merge of #130

Copy link
Contributor Author

@dprevost-LMI dprevost-LMI Nov 15, 2025

Choose a reason for hiding this comment

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

To revert, waiting on the merge of #130 and #144

@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!

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.

2 participants