@flotrace/runtime-core 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sameer Sitre
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -11,6 +11,33 @@ Platform-agnostic core for [FloTrace](https://flotrace.dev) — fiber walker, ho
11
11
 
12
12
  `runtime-core` is published publicly so adapters can pin a compatible version and so users can audit the open-source half of FloTrace. It has zero runtime dependency on `window` / `document` / `XMLHttpRequest` — all platform-specific features live in the adapters.
13
13
 
14
+ ---
15
+
16
+ ## About FloTrace Desktop
17
+
18
+ [**FloTrace Desktop**](https://flotrace.dev) is a free Electron app (macOS / Windows / Linux) that visualizes a running React app's component hierarchy in real time. It pairs with this runtime over a local WebSocket on port `3457` — the runtime sits inside your app and emits metadata; the desktop app renders the live tree, props, hooks, effects, and state. **Source code never leaves your machine.**
19
+
20
+ What you get when this runtime is paired with the desktop:
21
+
22
+ - **Live component tree** — React Flow graph, render-flash animation, frequency-based heatmap, breadcrumb navigation.
23
+ - **Per-node inspection** — props (with diff history), hooks (14 classified types + dep diffs), effects (willRun + dep diffs), component timeline.
24
+ - **State tracking** — Zustand (per-store), Redux (with change highlighting), Router, TanStack Query (with health warnings + wasted-refetch detection), Context.
25
+ - **Render cascade tracing** — trigger log, cascade tree, flame chart, cascade compare modal.
26
+ - **Prop drilling detection** — chain detection (≥3 levels deep), severity badges, heatmap overlay, refactor recommendations.
27
+ - **Network health** — fetch / XHR tracking, method badges, status dots, duplicate detection, API → store causal correlation.
28
+ - **Watch expressions** — pin values from 8 sources (Zustand / Redux / Router / Context / Props / Hooks / TanStack Query / API).
29
+ - **AI Code Review Dashboard** — 6-tab review (Re-renders, Memo, Drilling, Effects, Compiler, Network) with Lighthouse-style scores.
30
+ - **Copy-as-Prompt** — turn any panel into an AI-ready prompt for Cursor / Claude / ChatGPT in one click.
31
+
32
+ How it fits together:
33
+
34
+ ```
35
+ your React app ←→ @flotrace/runtime[-native] ←→ ws://localhost:3457 ←→ FloTrace Desktop
36
+ (this stack — open source, MIT) (closed-source commercial)
37
+ ```
38
+
39
+ [**Download FloTrace Desktop →**](https://flotrace.dev) · [Docs](https://flotrace.dev/docs) · [Security model](https://flotrace.dev/security)
40
+
14
41
  ## What's inside
15
42
 
16
43
  | Module | Purpose |
@@ -38,8 +65,12 @@ The runtime is what lives inside your app. Open-source means you can read every
38
65
 
39
66
  ## Contributing
40
67
 
41
- Issues and PRs welcome at [github.com/flotrace](https://github.com/flotrace). The runtime packages target Hermes, V8 (Chromium), and JavaScriptCore — please test against all three when changing fiber-walker or serializer code.
68
+ Issues and PRs welcome at [github.com/sameersitre/runtime-core](https://github.com/sameersitre/runtime-core). The runtime packages target Hermes, V8 (Chromium), and JavaScriptCore — please test against all three when changing fiber-walker or serializer code.
42
69
 
43
70
  ## License
44
71
 
45
- MIT.
72
+ MIT — see [LICENSE](./LICENSE).
73
+
74
+ ---
75
+
76
+ > **Mirrored from the [flotrace-desktop](https://github.com/sameersitre/flotrace-desktop) monorepo.** This repo is read-only — every release is regenerated by the lockstep publisher in the desktop monorepo. Issues filed here are tracked, but PRs are best opened against the upstream monorepo where the canonical source lives.
package/dist/index.js CHANGED
@@ -1847,20 +1847,23 @@ function extractRoute(url) {
1847
1847
  var originalFetch = null;
1848
1848
  var interceptorClient = null;
1849
1849
  var isInstalled2 = false;
1850
+ var patchedFetchRef = null;
1850
1851
  function installRscPayloadInterceptor(client2) {
1851
1852
  if (isInstalled2 || typeof globalThis.fetch !== "function") return;
1852
1853
  isInstalled2 = true;
1853
1854
  interceptorClient = client2;
1854
1855
  originalFetch = globalThis.fetch;
1855
- globalThis.fetch = async function patchedFetch(input, init) {
1856
+ const capturedOriginalFetch = originalFetch;
1857
+ const capturedClient = client2;
1858
+ const patchedFetch = async function patchedFetch2(input, init) {
1856
1859
  const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1857
1860
  const isRscRequest = RSC_URL_PATTERNS.some((p) => p.test(url));
1858
- const response = await originalFetch.call(globalThis, input, init);
1859
- if (isRscRequest && interceptorClient?.connected) {
1861
+ const response = await capturedOriginalFetch.call(globalThis, input, init);
1862
+ if (isRscRequest && interceptorClient === capturedClient && capturedClient.connected) {
1860
1863
  try {
1861
1864
  const sizeHeader = response.headers.get("content-length");
1862
1865
  const payloadSizeBytes = sizeHeader ? parseInt(sizeHeader, 10) : 0;
1863
- interceptorClient.send({
1866
+ capturedClient.send({
1864
1867
  type: "runtime:rscPayload",
1865
1868
  route: extractRoute(url),
1866
1869
  payloadSizeBytes: isNaN(payloadSizeBytes) ? 0 : payloadSizeBytes,
@@ -1872,11 +1875,16 @@ function installRscPayloadInterceptor(client2) {
1872
1875
  }
1873
1876
  return response;
1874
1877
  };
1878
+ patchedFetchRef = patchedFetch;
1879
+ globalThis.fetch = patchedFetch;
1875
1880
  }
1876
1881
  function uninstallRscPayloadInterceptor() {
1877
1882
  if (!isInstalled2 || !originalFetch) return;
1878
- globalThis.fetch = originalFetch;
1883
+ if (globalThis.fetch === patchedFetchRef) {
1884
+ globalThis.fetch = originalFetch;
1885
+ }
1879
1886
  originalFetch = null;
1887
+ patchedFetchRef = null;
1880
1888
  interceptorClient = null;
1881
1889
  isInstalled2 = false;
1882
1890
  }
package/dist/index.mjs CHANGED
@@ -1765,20 +1765,23 @@ function extractRoute(url) {
1765
1765
  var originalFetch = null;
1766
1766
  var interceptorClient = null;
1767
1767
  var isInstalled2 = false;
1768
+ var patchedFetchRef = null;
1768
1769
  function installRscPayloadInterceptor(client2) {
1769
1770
  if (isInstalled2 || typeof globalThis.fetch !== "function") return;
1770
1771
  isInstalled2 = true;
1771
1772
  interceptorClient = client2;
1772
1773
  originalFetch = globalThis.fetch;
1773
- globalThis.fetch = async function patchedFetch(input, init) {
1774
+ const capturedOriginalFetch = originalFetch;
1775
+ const capturedClient = client2;
1776
+ const patchedFetch = async function patchedFetch2(input, init) {
1774
1777
  const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1775
1778
  const isRscRequest = RSC_URL_PATTERNS.some((p) => p.test(url));
1776
- const response = await originalFetch.call(globalThis, input, init);
1777
- if (isRscRequest && interceptorClient?.connected) {
1779
+ const response = await capturedOriginalFetch.call(globalThis, input, init);
1780
+ if (isRscRequest && interceptorClient === capturedClient && capturedClient.connected) {
1778
1781
  try {
1779
1782
  const sizeHeader = response.headers.get("content-length");
1780
1783
  const payloadSizeBytes = sizeHeader ? parseInt(sizeHeader, 10) : 0;
1781
- interceptorClient.send({
1784
+ capturedClient.send({
1782
1785
  type: "runtime:rscPayload",
1783
1786
  route: extractRoute(url),
1784
1787
  payloadSizeBytes: isNaN(payloadSizeBytes) ? 0 : payloadSizeBytes,
@@ -1790,11 +1793,16 @@ function installRscPayloadInterceptor(client2) {
1790
1793
  }
1791
1794
  return response;
1792
1795
  };
1796
+ patchedFetchRef = patchedFetch;
1797
+ globalThis.fetch = patchedFetch;
1793
1798
  }
1794
1799
  function uninstallRscPayloadInterceptor() {
1795
1800
  if (!isInstalled2 || !originalFetch) return;
1796
- globalThis.fetch = originalFetch;
1801
+ if (globalThis.fetch === patchedFetchRef) {
1802
+ globalThis.fetch = originalFetch;
1803
+ }
1797
1804
  originalFetch = null;
1805
+ patchedFetchRef = null;
1798
1806
  interceptorClient = null;
1799
1807
  isInstalled2 = false;
1800
1808
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flotrace/runtime-core",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "description": "Platform-agnostic core for FloTrace runtime — fiber walker, analyzers, trackers. Shared by @flotrace/runtime (web) and @flotrace/runtime-native (React Native).",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -13,7 +13,9 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "LICENSE",
18
+ "README.md"
17
19
  ],
18
20
  "scripts": {
19
21
  "build": "tsup",
@@ -46,10 +48,13 @@
46
48
  "flotrace"
47
49
  ],
48
50
  "license": "MIT",
51
+ "homepage": "https://flotrace.dev",
49
52
  "repository": {
50
53
  "type": "git",
51
- "url": "https://github.com/flotrace/flotrace.git",
52
- "directory": "packages/runtime-core"
54
+ "url": "https://github.com/sameersitre/runtime-core.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/sameersitre/runtime-core/issues"
53
58
  },
54
59
  "publishConfig": {
55
60
  "access": "public"