@flotrace/runtime-core 2.2.2 → 2.2.4

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.d.mts CHANGED
@@ -708,15 +708,12 @@ interface ValueTrace {
708
708
  steps: TraceStep[];
709
709
  /** Wall-clock time the resolver completed. */
710
710
  resolvedAtMs: number;
711
- /** True when the 50ms budget tripped and the chain is partial. */
712
- truncated?: boolean;
713
711
  /**
714
712
  * Optional error hint for friendly empty states.
715
713
  * - `value-not-found`: target path doesn't exist on the current fiber.
716
714
  * - `no-fiber`: nodeId no longer present in fiberRefMap (component unmounted).
717
- * - `budget-exceeded`: bailed before finding origin.
718
715
  */
719
- error?: 'value-not-found' | 'no-fiber' | 'budget-exceeded';
716
+ error?: 'value-not-found' | 'no-fiber';
720
717
  }
721
718
  interface RuntimeValueTraceMessage {
722
719
  type: 'runtime:valueTrace';
@@ -898,7 +895,8 @@ declare const DEFAULT_CONFIG: ResolvedFloTraceConfig;
898
895
  * 2. Store match — scan Zustand / Redux / TanStack Query live snapshots
899
896
  * 3. API match — feed matched reference into fetchOriginRegistry WeakMap
900
897
  *
901
- * On-demand only — never runs per-render. Hard 50 ms wall-clock budget.
898
+ * On-demand only — never runs per-render. Bounded by MAX_PROP_CHAIN_DEPTH and
899
+ * SCAN_DEPTH structural limits; no wall-clock budget so every trace runs to origin.
902
900
  * Uses reference identity (`===`) before fingerprinting to keep common cases fast.
903
901
  *
904
902
  * See docs/PRD-VALUE-LINEAGE.md §6 and docs/IMPLEMENTATION-PLAN-VALUE-LINEAGE.md Phase 2.
package/dist/index.d.ts CHANGED
@@ -708,15 +708,12 @@ interface ValueTrace {
708
708
  steps: TraceStep[];
709
709
  /** Wall-clock time the resolver completed. */
710
710
  resolvedAtMs: number;
711
- /** True when the 50ms budget tripped and the chain is partial. */
712
- truncated?: boolean;
713
711
  /**
714
712
  * Optional error hint for friendly empty states.
715
713
  * - `value-not-found`: target path doesn't exist on the current fiber.
716
714
  * - `no-fiber`: nodeId no longer present in fiberRefMap (component unmounted).
717
- * - `budget-exceeded`: bailed before finding origin.
718
715
  */
719
- error?: 'value-not-found' | 'no-fiber' | 'budget-exceeded';
716
+ error?: 'value-not-found' | 'no-fiber';
720
717
  }
721
718
  interface RuntimeValueTraceMessage {
722
719
  type: 'runtime:valueTrace';
@@ -898,7 +895,8 @@ declare const DEFAULT_CONFIG: ResolvedFloTraceConfig;
898
895
  * 2. Store match — scan Zustand / Redux / TanStack Query live snapshots
899
896
  * 3. API match — feed matched reference into fetchOriginRegistry WeakMap
900
897
  *
901
- * On-demand only — never runs per-render. Hard 50 ms wall-clock budget.
898
+ * On-demand only — never runs per-render. Bounded by MAX_PROP_CHAIN_DEPTH and
899
+ * SCAN_DEPTH structural limits; no wall-clock budget so every trace runs to origin.
902
900
  * Uses reference identity (`===`) before fingerprinting to keep common cases fast.
903
901
  *
904
902
  * See docs/PRD-VALUE-LINEAGE.md §6 and docs/IMPLEMENTATION-PLAN-VALUE-LINEAGE.md Phase 2.
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
  }
@@ -3722,7 +3730,6 @@ function safeCall(fn, fallback) {
3722
3730
 
3723
3731
  // src/valueTraceResolver.ts
3724
3732
  var FIBER_TAG_CONTEXT_PROVIDER = 10;
3725
- var BUDGET_MS = 100;
3726
3733
  var SCAN_DEPTH = 3;
3727
3734
  var MAX_PROP_CHAIN_DEPTH = 30;
3728
3735
  function now() {
@@ -3769,8 +3776,7 @@ function findReferenceMatchAtTopLevel(target, container) {
3769
3776
  }
3770
3777
  return null;
3771
3778
  }
3772
- function findMatchingPathInObject(target, targetFp, container, currentPath, depth, deadline, cache) {
3773
- if (now() > deadline) return null;
3779
+ function findMatchingPathInObject(target, targetFp, container, currentPath, depth, cache) {
3774
3780
  if (depth > SCAN_DEPTH) return null;
3775
3781
  if (container === null || typeof container !== "object") return null;
3776
3782
  const selfMatch = valuesMatch(target, targetFp, container, cache);
@@ -3780,7 +3786,7 @@ function findMatchingPathInObject(target, targetFp, container, currentPath, dept
3780
3786
  const child = container[i];
3781
3787
  const directMatch = valuesMatch(target, targetFp, child, cache);
3782
3788
  if (directMatch) return { path: [...currentPath, String(i)], confidence: directMatch };
3783
- const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, String(i)], depth + 1, deadline, cache);
3789
+ const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, String(i)], depth + 1, cache);
3784
3790
  if (nested) return nested;
3785
3791
  }
3786
3792
  } else {
@@ -3788,7 +3794,7 @@ function findMatchingPathInObject(target, targetFp, container, currentPath, dept
3788
3794
  const child = container[key];
3789
3795
  const directMatch = valuesMatch(target, targetFp, child, cache);
3790
3796
  if (directMatch) return { path: [...currentPath, key], confidence: directMatch };
3791
- const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, key], depth + 1, deadline, cache);
3797
+ const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, key], depth + 1, cache);
3792
3798
  if (nested) return nested;
3793
3799
  }
3794
3800
  }
@@ -3855,8 +3861,6 @@ function resolveOriginViaTagOrKeyPath(matchedValue, stateRoot, keyPath) {
3855
3861
  return findFetchOrigin(matchedValue, { ignoreTTL: true }) ?? findFetchOriginUpKeyPath(stateRoot, keyPath);
3856
3862
  }
3857
3863
  function resolveValueTrace(input) {
3858
- const startedAt = now();
3859
- const deadline = startedAt + BUDGET_MS;
3860
3864
  const steps = [];
3861
3865
  const base = {
3862
3866
  rootNodeId: input.nodeId,
@@ -3913,7 +3917,6 @@ function resolveValueTrace(input) {
3913
3917
  let current = fiber.return;
3914
3918
  let hops = 0;
3915
3919
  while (current && hops < MAX_PROP_CHAIN_DEPTH) {
3916
- if (now() > deadline) return { ...base, steps, truncated: true, resolvedAtMs: now() };
3917
3920
  if (current.tag !== FIBER_TAG_CONTEXT_PROVIDER) {
3918
3921
  const props = current.memoizedProps;
3919
3922
  if (props) {
@@ -3921,7 +3924,7 @@ function resolveValueTrace(input) {
3921
3924
  let matchPath = refKey !== null ? [refKey] : null;
3922
3925
  let matchConfidence = "exact";
3923
3926
  if (matchPath === null) {
3924
- const match = findMatchingPathInObject(rootValue, rootFp, props, [], 0, deadline, fpCache);
3927
+ const match = findMatchingPathInObject(rootValue, rootFp, props, [], 0, fpCache);
3925
3928
  if (match) {
3926
3929
  matchPath = match.path;
3927
3930
  matchConfidence = match.confidence;
@@ -3985,7 +3988,7 @@ function resolveValueTrace(input) {
3985
3988
  const contextMatch = findContextMatch(fiber, rootValue, rootFp, fiberToNodeId, fpCache);
3986
3989
  if (contextMatch) {
3987
3990
  steps.push(contextMatch.step);
3988
- const providerStoreMatch = findStoreMatch(contextMatch.providerValue, cachedFp(contextMatch.providerValue, fpCache), deadline, fpCache);
3991
+ const providerStoreMatch = findStoreMatch(contextMatch.providerValue, cachedFp(contextMatch.providerValue, fpCache), fpCache);
3989
3992
  if (providerStoreMatch) {
3990
3993
  steps.push({
3991
3994
  kind: "store",
@@ -4010,7 +4013,7 @@ function resolveValueTrace(input) {
4010
4013
  }
4011
4014
  return { ...base, steps, resolvedAtMs: now() };
4012
4015
  }
4013
- const storeMatch = findStoreMatch(rootValue, rootFp, deadline, fpCache);
4016
+ const storeMatch = findStoreMatch(rootValue, rootFp, fpCache);
4014
4017
  if (storeMatch) {
4015
4018
  steps.push({
4016
4019
  kind: "store",
@@ -4115,10 +4118,9 @@ function findNearestProvider(consumer, contextObj) {
4115
4118
  }
4116
4119
  return null;
4117
4120
  }
4118
- function findStoreMatch(target, targetFp, deadline, cache) {
4121
+ function findStoreMatch(target, targetFp, cache) {
4119
4122
  for (const [storeName, state] of getZustandSnapshot()) {
4120
- if (now() > deadline) return null;
4121
- const hit = findMatchingPathInObject(target, targetFp, state, [], 0, deadline, cache);
4123
+ const hit = findMatchingPathInObject(target, targetFp, state, [], 0, cache);
4122
4124
  if (hit) {
4123
4125
  return {
4124
4126
  source: "zustand",
@@ -4132,8 +4134,7 @@ function findStoreMatch(target, targetFp, deadline, cache) {
4132
4134
  }
4133
4135
  const redux = getReduxSnapshot();
4134
4136
  if (redux) {
4135
- if (now() > deadline) return null;
4136
- const hit = findMatchingPathInObject(target, targetFp, redux, [], 0, deadline, cache);
4137
+ const hit = findMatchingPathInObject(target, targetFp, redux, [], 0, cache);
4137
4138
  if (hit) {
4138
4139
  return {
4139
4140
  source: "redux",
@@ -4146,8 +4147,7 @@ function findStoreMatch(target, targetFp, deadline, cache) {
4146
4147
  }
4147
4148
  }
4148
4149
  for (const [queryHash, entry] of getTanstackSnapshot()) {
4149
- if (now() > deadline) return null;
4150
- const hit = findMatchingPathInObject(target, targetFp, entry.data, [], 0, deadline, cache);
4150
+ const hit = findMatchingPathInObject(target, targetFp, entry.data, [], 0, cache);
4151
4151
  if (hit) {
4152
4152
  return {
4153
4153
  source: "tanstack-query",
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
  }
@@ -3640,7 +3648,6 @@ function safeCall(fn, fallback) {
3640
3648
 
3641
3649
  // src/valueTraceResolver.ts
3642
3650
  var FIBER_TAG_CONTEXT_PROVIDER = 10;
3643
- var BUDGET_MS = 100;
3644
3651
  var SCAN_DEPTH = 3;
3645
3652
  var MAX_PROP_CHAIN_DEPTH = 30;
3646
3653
  function now() {
@@ -3687,8 +3694,7 @@ function findReferenceMatchAtTopLevel(target, container) {
3687
3694
  }
3688
3695
  return null;
3689
3696
  }
3690
- function findMatchingPathInObject(target, targetFp, container, currentPath, depth, deadline, cache) {
3691
- if (now() > deadline) return null;
3697
+ function findMatchingPathInObject(target, targetFp, container, currentPath, depth, cache) {
3692
3698
  if (depth > SCAN_DEPTH) return null;
3693
3699
  if (container === null || typeof container !== "object") return null;
3694
3700
  const selfMatch = valuesMatch(target, targetFp, container, cache);
@@ -3698,7 +3704,7 @@ function findMatchingPathInObject(target, targetFp, container, currentPath, dept
3698
3704
  const child = container[i];
3699
3705
  const directMatch = valuesMatch(target, targetFp, child, cache);
3700
3706
  if (directMatch) return { path: [...currentPath, String(i)], confidence: directMatch };
3701
- const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, String(i)], depth + 1, deadline, cache);
3707
+ const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, String(i)], depth + 1, cache);
3702
3708
  if (nested) return nested;
3703
3709
  }
3704
3710
  } else {
@@ -3706,7 +3712,7 @@ function findMatchingPathInObject(target, targetFp, container, currentPath, dept
3706
3712
  const child = container[key];
3707
3713
  const directMatch = valuesMatch(target, targetFp, child, cache);
3708
3714
  if (directMatch) return { path: [...currentPath, key], confidence: directMatch };
3709
- const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, key], depth + 1, deadline, cache);
3715
+ const nested = findMatchingPathInObject(target, targetFp, child, [...currentPath, key], depth + 1, cache);
3710
3716
  if (nested) return nested;
3711
3717
  }
3712
3718
  }
@@ -3773,8 +3779,6 @@ function resolveOriginViaTagOrKeyPath(matchedValue, stateRoot, keyPath) {
3773
3779
  return findFetchOrigin(matchedValue, { ignoreTTL: true }) ?? findFetchOriginUpKeyPath(stateRoot, keyPath);
3774
3780
  }
3775
3781
  function resolveValueTrace(input) {
3776
- const startedAt = now();
3777
- const deadline = startedAt + BUDGET_MS;
3778
3782
  const steps = [];
3779
3783
  const base = {
3780
3784
  rootNodeId: input.nodeId,
@@ -3831,7 +3835,6 @@ function resolveValueTrace(input) {
3831
3835
  let current = fiber.return;
3832
3836
  let hops = 0;
3833
3837
  while (current && hops < MAX_PROP_CHAIN_DEPTH) {
3834
- if (now() > deadline) return { ...base, steps, truncated: true, resolvedAtMs: now() };
3835
3838
  if (current.tag !== FIBER_TAG_CONTEXT_PROVIDER) {
3836
3839
  const props = current.memoizedProps;
3837
3840
  if (props) {
@@ -3839,7 +3842,7 @@ function resolveValueTrace(input) {
3839
3842
  let matchPath = refKey !== null ? [refKey] : null;
3840
3843
  let matchConfidence = "exact";
3841
3844
  if (matchPath === null) {
3842
- const match = findMatchingPathInObject(rootValue, rootFp, props, [], 0, deadline, fpCache);
3845
+ const match = findMatchingPathInObject(rootValue, rootFp, props, [], 0, fpCache);
3843
3846
  if (match) {
3844
3847
  matchPath = match.path;
3845
3848
  matchConfidence = match.confidence;
@@ -3903,7 +3906,7 @@ function resolveValueTrace(input) {
3903
3906
  const contextMatch = findContextMatch(fiber, rootValue, rootFp, fiberToNodeId, fpCache);
3904
3907
  if (contextMatch) {
3905
3908
  steps.push(contextMatch.step);
3906
- const providerStoreMatch = findStoreMatch(contextMatch.providerValue, cachedFp(contextMatch.providerValue, fpCache), deadline, fpCache);
3909
+ const providerStoreMatch = findStoreMatch(contextMatch.providerValue, cachedFp(contextMatch.providerValue, fpCache), fpCache);
3907
3910
  if (providerStoreMatch) {
3908
3911
  steps.push({
3909
3912
  kind: "store",
@@ -3928,7 +3931,7 @@ function resolveValueTrace(input) {
3928
3931
  }
3929
3932
  return { ...base, steps, resolvedAtMs: now() };
3930
3933
  }
3931
- const storeMatch = findStoreMatch(rootValue, rootFp, deadline, fpCache);
3934
+ const storeMatch = findStoreMatch(rootValue, rootFp, fpCache);
3932
3935
  if (storeMatch) {
3933
3936
  steps.push({
3934
3937
  kind: "store",
@@ -4033,10 +4036,9 @@ function findNearestProvider(consumer, contextObj) {
4033
4036
  }
4034
4037
  return null;
4035
4038
  }
4036
- function findStoreMatch(target, targetFp, deadline, cache) {
4039
+ function findStoreMatch(target, targetFp, cache) {
4037
4040
  for (const [storeName, state] of getZustandSnapshot()) {
4038
- if (now() > deadline) return null;
4039
- const hit = findMatchingPathInObject(target, targetFp, state, [], 0, deadline, cache);
4041
+ const hit = findMatchingPathInObject(target, targetFp, state, [], 0, cache);
4040
4042
  if (hit) {
4041
4043
  return {
4042
4044
  source: "zustand",
@@ -4050,8 +4052,7 @@ function findStoreMatch(target, targetFp, deadline, cache) {
4050
4052
  }
4051
4053
  const redux = getReduxSnapshot();
4052
4054
  if (redux) {
4053
- if (now() > deadline) return null;
4054
- const hit = findMatchingPathInObject(target, targetFp, redux, [], 0, deadline, cache);
4055
+ const hit = findMatchingPathInObject(target, targetFp, redux, [], 0, cache);
4055
4056
  if (hit) {
4056
4057
  return {
4057
4058
  source: "redux",
@@ -4064,8 +4065,7 @@ function findStoreMatch(target, targetFp, deadline, cache) {
4064
4065
  }
4065
4066
  }
4066
4067
  for (const [queryHash, entry] of getTanstackSnapshot()) {
4067
- if (now() > deadline) return null;
4068
- const hit = findMatchingPathInObject(target, targetFp, entry.data, [], 0, deadline, cache);
4068
+ const hit = findMatchingPathInObject(target, targetFp, entry.data, [], 0, cache);
4069
4069
  if (hit) {
4070
4070
  return {
4071
4071
  source: "tanstack-query",
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.4",
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"