@buoy-gg/network 7.0.36 → 7.0.38

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 (91) hide show
  1. package/README.md +45 -12
  2. package/lib/commonjs/index.js +26 -1
  3. package/lib/commonjs/index.web.js +26 -1
  4. package/lib/commonjs/network/components/NetworkEventDetailView.js +6 -1
  5. package/lib/commonjs/network/components/NetworkHeaderMenu.js +4 -0
  6. package/lib/commonjs/network/components/NetworkModal.js +24 -8
  7. package/lib/commonjs/network/conditions/NetworkConditionsControl.js +235 -0
  8. package/lib/commonjs/network/conditions/NetworkConditionsControl.test.js +136 -0
  9. package/lib/commonjs/network/conditions/NetworkConditionsIcon.js +33 -0
  10. package/lib/commonjs/network/conditions/NetworkFloatingTool.js +310 -0
  11. package/lib/commonjs/network/conditions/NetworkFloatingTool.test.js +219 -0
  12. package/lib/commonjs/network/conditions/store.js +75 -0
  13. package/lib/commonjs/network/conditions/wait.js +43 -0
  14. package/lib/commonjs/network/conditions/xhr.js +110 -0
  15. package/lib/commonjs/network/hooks/useNetworkEvents.js +1 -1
  16. package/lib/commonjs/network/overrides/applyToXhr.js +10 -8
  17. package/lib/commonjs/network/overrides/engine.js +2 -1
  18. package/lib/commonjs/network/sync/networkSyncAdapter.js +26 -1
  19. package/lib/commonjs/network/utils/generateNetworkCopyText.js +2 -0
  20. package/lib/commonjs/network/utils/networkEventStore.js +5 -77
  21. package/lib/commonjs/network/utils/networkListener.js +96 -51
  22. package/lib/commonjs/network/utils/networkSavedStore.js +2 -2
  23. package/lib/commonjs/network/utils/selectSavedEvents.js +2 -2
  24. package/lib/commonjs/preset.js +2 -1
  25. package/lib/module/index.js +2 -1
  26. package/lib/module/index.web.js +2 -1
  27. package/lib/module/network/components/NetworkEventDetailView.js +6 -1
  28. package/lib/module/network/components/NetworkHeaderMenu.js +4 -0
  29. package/lib/module/network/components/NetworkModal.js +25 -9
  30. package/lib/module/network/conditions/NetworkConditionsControl.js +231 -0
  31. package/lib/module/network/conditions/NetworkConditionsControl.test.js +135 -0
  32. package/lib/module/network/conditions/NetworkConditionsIcon.js +29 -0
  33. package/lib/module/network/conditions/NetworkFloatingTool.js +304 -0
  34. package/lib/module/network/conditions/NetworkFloatingTool.test.js +218 -0
  35. package/lib/module/network/conditions/store.js +65 -0
  36. package/lib/module/network/conditions/wait.js +38 -0
  37. package/lib/module/network/conditions/xhr.js +106 -0
  38. package/lib/module/network/hooks/useNetworkEvents.js +1 -1
  39. package/lib/module/network/overrides/applyToXhr.js +9 -8
  40. package/lib/module/network/overrides/engine.js +2 -1
  41. package/lib/module/network/sync/networkSyncAdapter.js +26 -1
  42. package/lib/module/network/utils/generateNetworkCopyText.js +2 -0
  43. package/lib/module/network/utils/networkEventStore.js +6 -77
  44. package/lib/module/network/utils/networkListener.js +97 -52
  45. package/lib/module/network/utils/networkSavedStore.js +2 -2
  46. package/lib/module/network/utils/selectSavedEvents.js +2 -2
  47. package/lib/module/preset.js +3 -2
  48. package/lib/typescript/index.d.ts +2 -0
  49. package/lib/typescript/index.d.ts.map +1 -1
  50. package/lib/typescript/index.web.d.ts +2 -0
  51. package/lib/typescript/index.web.d.ts.map +1 -1
  52. package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +1 -1
  53. package/lib/typescript/network/components/NetworkHeaderMenu.d.ts +2 -1
  54. package/lib/typescript/network/components/NetworkHeaderMenu.d.ts.map +1 -1
  55. package/lib/typescript/network/components/NetworkModal.d.ts +3 -0
  56. package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -1
  57. package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts +12 -0
  58. package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts.map +1 -0
  59. package/lib/typescript/network/conditions/NetworkConditionsControl.test.d.ts +2 -0
  60. package/lib/typescript/network/conditions/NetworkConditionsControl.test.d.ts.map +1 -0
  61. package/lib/typescript/network/conditions/NetworkConditionsIcon.d.ts +4 -0
  62. package/lib/typescript/network/conditions/NetworkConditionsIcon.d.ts.map +1 -0
  63. package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts +15 -0
  64. package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts.map +1 -0
  65. package/lib/typescript/network/conditions/NetworkFloatingTool.test.d.ts +2 -0
  66. package/lib/typescript/network/conditions/NetworkFloatingTool.test.d.ts.map +1 -0
  67. package/lib/typescript/network/conditions/store.d.ts +30 -0
  68. package/lib/typescript/network/conditions/store.d.ts.map +1 -0
  69. package/lib/typescript/network/conditions/wait.d.ts +4 -0
  70. package/lib/typescript/network/conditions/wait.d.ts.map +1 -0
  71. package/lib/typescript/network/conditions/xhr.d.ts +5 -0
  72. package/lib/typescript/network/conditions/xhr.d.ts.map +1 -0
  73. package/lib/typescript/network/hooks/useNetworkEvents.d.ts +1 -1
  74. package/lib/typescript/network/overrides/applyToXhr.d.ts +2 -0
  75. package/lib/typescript/network/overrides/applyToXhr.d.ts.map +1 -1
  76. package/lib/typescript/network/overrides/engine.d.ts +0 -10
  77. package/lib/typescript/network/overrides/engine.d.ts.map +1 -1
  78. package/lib/typescript/network/sync/networkSyncAdapter.d.ts +17 -0
  79. package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +1 -1
  80. package/lib/typescript/network/types/index.d.ts +1 -0
  81. package/lib/typescript/network/types/index.d.ts.map +1 -1
  82. package/lib/typescript/network/utils/generateNetworkCopyText.d.ts.map +1 -1
  83. package/lib/typescript/network/utils/networkEventStore.d.ts +0 -15
  84. package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -1
  85. package/lib/typescript/network/utils/networkListener.d.ts +2 -1
  86. package/lib/typescript/network/utils/networkListener.d.ts.map +1 -1
  87. package/lib/typescript/network/utils/networkSavedStore.d.ts +2 -2
  88. package/lib/typescript/network/utils/selectSavedEvents.d.ts +2 -2
  89. package/lib/typescript/preset.d.ts +0 -16
  90. package/lib/typescript/preset.d.ts.map +1 -1
  91. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import { getAccountAccess } from "@buoy-gg/shared-ui";
3
4
  /**
4
5
  * Network Event Store
5
6
  *
@@ -43,14 +44,6 @@ import { networkSavedStore } from "./networkSavedStore";
43
44
  const BOOT_BUFFER_MAX = 200;
44
45
  class NetworkEventStore extends BaseEventStore {
45
46
  pendingRequests = new Map();
46
- /**
47
- * Recently seen `METHOD:url` keys → when, and which event id we kept.
48
- *
49
- * The timestamp powers the dual-interception dedup below. The id is what lets
50
- * a DROPPED duplicate still contribute something the kept event doesn't know
51
- * — see `applyOverrideMark`.
52
- */
53
- recentRequests = new Map();
54
47
  rawListenerUnsubscribe = null;
55
48
  /** Raw events captured before the first consumer subscribed — see startBootCapture. */
56
49
  bootBuffer = [];
@@ -82,6 +75,7 @@ class NetworkEventStore extends BaseEventStore {
82
75
  * state therefore never gains events it didn't ask for).
83
76
  */
84
77
  startBootCapture() {
78
+ if (getAccountAccess().status === "locked") return;
85
79
  if (this.mirrorMode || this.bootBufferUnsubscribe || this.isCapturing()) {
86
80
  return;
87
81
  }
@@ -136,6 +130,7 @@ class NetworkEventStore extends BaseEventStore {
136
130
  * Stop capturing network events
137
131
  */
138
132
  stopCapturing() {
133
+ this.takeBootBuffer();
139
134
  // Remove our raw listener
140
135
  if (this.rawListenerUnsubscribe) {
141
136
  this.rawListenerUnsubscribe();
@@ -202,57 +197,11 @@ class NetworkEventStore extends BaseEventStore {
202
197
  * Process a network listener event
203
198
  */
204
199
  processNetworkEvent(event) {
200
+ if (getAccountAccess().status === "locked") return;
205
201
  const {
206
202
  request
207
203
  } = event;
208
204
  if (event.type === "request") {
209
- // Check for duplicate request based on URL, method, and timing.
210
- // The clock is the event's CAPTURE time, not Date.now(): boot-buffered
211
- // events are flushed in one synchronous burst, and wall-clock "now"
212
- // would put two genuinely separate boot requests to the same endpoint
213
- // inside the 50ms dual-interception window, silently dropping one. For
214
- // live events the two clocks are the same (the raw event is emitted
215
- // synchronously at capture).
216
- const requestKey = `${request.method}:${request.url}`;
217
- const now = event.timestamp instanceof Date ? event.timestamp.getTime() : Date.now();
218
- const recent = this.recentRequests.get(requestKey);
219
-
220
- // If same request within 50ms, likely a duplicate from XHR/fetch dual
221
- // interception. The age must be non-negative: Date.now() is not
222
- // monotonic, and after a backwards clock adjustment (iOS time sync) a
223
- // future-dated entry would satisfy `< 50` for EVERY request to this
224
- // endpoint until the clock caught up — capture going silent for minutes
225
- // to hours, "fixed" only by Clear wiping this map (field-reported). A
226
- // negative age falls through and re-stamps the entry with the new clock.
227
- if (recent && now - recent.at >= 0 && now - recent.at < 50) {
228
- // …but the duplicate is not always redundant. On React Native a
229
- // `fetch()` is seen twice: once by the fetch wrapper, which is what
230
- // creates this event, and again by the XHR wrapper underneath it —
231
- // and ONLY the XHR layer resolves overrides, because that's where the
232
- // request can actually be intercepted. So the mark arrives on the copy
233
- // we're about to throw away. Move it across before dropping.
234
- if (event.override) {
235
- this.applyOverrideMark(recent.id, event.override);
236
- }
237
- return;
238
- }
239
- this.recentRequests.set(requestKey, {
240
- at: now,
241
- id: request.id
242
- });
243
-
244
- // Clean up old entries to prevent memory leak. Future-dated entries are
245
- // stale by definition (clock moved backwards) — drop those too, or they
246
- // survive every sweep until the clock overtakes them.
247
- if (this.recentRequests.size > 100) {
248
- const cutoff = now - 5000;
249
- for (const [key, entry] of this.recentRequests.entries()) {
250
- if (entry.at < cutoff || entry.at > now) {
251
- this.recentRequests.delete(key);
252
- }
253
- }
254
- }
255
-
256
205
  // Build full URL with query params if present
257
206
  const queryString = request.params ? `?${new URLSearchParams(request.params).toString()}` : "";
258
207
  const fullUrl = `${request.url}${queryString}`;
@@ -284,7 +233,8 @@ class NetworkEventStore extends BaseEventStore {
284
233
  graphqlVariables,
285
234
  // Present when this request came straight through the XHR wrapper
286
235
  // (axios, raw XHR). For `fetch` it arrives later — see the dedup branch.
287
- override: event.override
236
+ override: event.override,
237
+ condition: event.condition
288
238
  };
289
239
  this.pendingRequests.set(request.id, networkEvent);
290
240
  this.events = [networkEvent, ...this.events].slice(0, this.maxEvents);
@@ -328,26 +278,6 @@ class NetworkEventStore extends BaseEventStore {
328
278
  }
329
279
  }
330
280
  }
331
-
332
- /**
333
- * Stamp an override mark onto an already-recorded event.
334
- *
335
- * Only ever moves a mark from a dropped duplicate onto the event that was
336
- * kept, so it never overwrites one that is already there.
337
- */
338
- applyOverrideMark(id, override) {
339
- const index = this.events.findIndex(e => e.id === id);
340
- if (index === -1 || this.events[index].override) return;
341
- const updatedEvent = {
342
- ...this.events[index],
343
- override
344
- };
345
- this.events = this.events.map((e, i) => i === index ? updatedEvent : e);
346
- const pending = this.pendingRequests.get(id);
347
- if (pending) this.pendingRequests.set(id, updatedEvent);
348
- this.notify(updatedEvent);
349
- this.notifyArrayListeners();
350
- }
351
281
  extractHost(url) {
352
282
  try {
353
283
  const urlObj = new URL(url);
@@ -385,7 +315,6 @@ class NetworkEventStore extends BaseEventStore {
385
315
  clearEvents() {
386
316
  super.clearEvents();
387
317
  this.pendingRequests.clear();
388
- this.recentRequests.clear();
389
318
  }
390
319
 
391
320
  /**
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
 
3
+ import { runConditionXhr } from "../conditions/xhr";
4
+ import { snapshotNetworkCondition } from "../conditions/store";
5
+ import { throwIfAborted, waitBeforeDispatch } from "../conditions/wait";
3
6
  /**
4
7
  * Network listener using Reactotron-style event pattern
5
8
  * Simple and reliable network interception for React Native
@@ -7,7 +10,7 @@
7
10
 
8
11
  import { overrideForRequest } from "../overrides/engine";
9
12
  import { runOverride } from "../overrides/applyToXhr";
10
- import { canSynthesizeResponse, sleep, synthesizeFetchError, synthesizeResponse } from "../overrides/applyToFetch";
13
+ import { canSynthesizeResponse, synthesizeFetchError, synthesizeResponse } from "../overrides/applyToFetch";
11
14
  import { markForOutcome } from "../overrides/types";
12
15
  import { httpStatusText, xhrCompletionKind } from "./httpCompletion";
13
16
 
@@ -23,7 +26,7 @@ import { httpStatusText, xhrCompletionKind } from "./httpCompletion";
23
26
  * executor, so a flag raised across the call expression alone is enough to
24
27
  * cover the inner `send()` without leaking across the await.
25
28
  */
26
- let insideOverriddenFetch = false;
29
+ let insideFetchHandoff = false;
27
30
 
28
31
  // Extended XMLHttpRequest interface for monkey-patching
29
32
 
@@ -102,9 +105,14 @@ const INTERNAL_HOSTS_KEY = "__BUOY_INTERNAL_HOSTS__";
102
105
  function isInternalBuoyHost(url) {
103
106
  const hosts = globalThis[INTERNAL_HOSTS_KEY];
104
107
  if (!(hosts instanceof Set) || hosts.size === 0) return false;
105
- const lower = url.toLowerCase();
108
+ let authority;
109
+ try {
110
+ authority = new URL(url).host.toLowerCase();
111
+ } catch {
112
+ return false;
113
+ }
106
114
  for (const host of hosts) {
107
- if (typeof host === "string" && host && lower.includes(host)) return true;
115
+ if (typeof host === "string" && host && authority === host.toLowerCase()) return true;
108
116
  }
109
117
  return false;
110
118
  }
@@ -113,12 +121,6 @@ class NetworkListener {
113
121
  isListening = false;
114
122
  requestCounter = 1000;
115
123
 
116
- // URLs to ignore (Metro bundler, symbolicate, etc.)
117
- ignoredUrls = [/\/symbolicate$/, /\/logs$/, /\/debugger-proxy/, /\/reload$/, /\/launch-js-devtools/, /localhost:8081/, /100\.64\.\d+\.\d+:8081/,
118
- // iOS simulator
119
- /10\.0\.\d+\.\d+:8081/ // Android emulator
120
- ];
121
-
122
124
  // Store original methods
123
125
 
124
126
  /**
@@ -142,7 +144,7 @@ class NetworkListener {
142
144
  xhrGeneration = 0;
143
145
  constructor() {
144
146
  // Store original methods
145
- this.originalFetch = globalThis.fetch.bind(globalThis);
147
+ this.originalFetch = globalThis.fetch;
146
148
  this.originalXHROpen = XMLHttpRequest.prototype.open;
147
149
  this.originalXHRSend = XMLHttpRequest.prototype.send;
148
150
  this.originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
@@ -158,7 +160,14 @@ class NetworkListener {
158
160
  * @returns True if the URL should be ignored
159
161
  */
160
162
  shouldIgnoreUrl(url) {
161
- if (this.ignoredUrls.some(pattern => pattern.test(url))) return true;
163
+ try {
164
+ const parsed = new URL(url);
165
+ if (parsed.hostname === "keygen.sh" || parsed.hostname.endsWith(".keygen.sh")) return true;
166
+ const local = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "10.0.2.2";
167
+ if (local && ["8081", "8802"].includes(parsed.port)) return true;
168
+ } catch {
169
+ return false;
170
+ }
162
171
  return isInternalBuoyHost(url);
163
172
  }
164
173
 
@@ -244,7 +253,7 @@ class NetworkListener {
244
253
  out += decoder.decode(value, {
245
254
  stream: true
246
255
  });
247
- if (out.length >= maxSize) {
256
+ if (size >= maxSize) {
248
257
  out = `${out.slice(0, maxSize)}\n\n... [truncated]`;
249
258
  capped = true;
250
259
  break;
@@ -341,14 +350,14 @@ class NetworkListener {
341
350
  * Handle XMLHttpRequest response processing
342
351
  * This method processes the response and emits appropriate events
343
352
  */
344
- handleXHRResponse(xhr, requestId, cleanUrl, method, requestHeaders, requestData, params, startTime, isError = false, clientType = "xhr", override) {
353
+ handleXHRResponse(xhr, requestId, cleanUrl, method, requestHeaders, requestData, params, startTime, isError = false, clientType = "xhr", override, condition) {
345
354
  const duration = startTime ? Date.now() - startTime : 0;
346
355
 
347
356
  // XHR's duration was ALREADY total (measured at readyState 4 / load), so
348
- // only the split is new. `_ttfb` is stamped at HEADERS_RECEIVED; it is
357
+ // only the split is new. `_buoyTtfb` is stamped at HEADERS_RECEIVED; it is
349
358
  // absent for a request that failed before any headers arrived, and the
350
359
  // breakdown is then correctly omitted rather than faked as 0.
351
- const ttfb = xhr._ttfb;
360
+ const ttfb = xhr._buoyTtfb;
352
361
  const timings = ttfb === undefined ? undefined : {
353
362
  ttfb,
354
363
  download: Math.max(0, duration - ttfb)
@@ -371,7 +380,8 @@ class NetworkListener {
371
380
  error: {
372
381
  message: isError ? "Request failed" : "Network error or request aborted"
373
382
  },
374
- override
383
+ override,
384
+ condition
375
385
  });
376
386
  return;
377
387
  }
@@ -513,7 +523,8 @@ class NetworkListener {
513
523
  body,
514
524
  size: responseSize
515
525
  },
516
- override
526
+ override,
527
+ condition
517
528
  });
518
529
  } else {
519
530
  this.emit({
@@ -539,7 +550,8 @@ class NetworkListener {
539
550
  error: {
540
551
  message: "Network Error"
541
552
  },
542
- override
553
+ override,
554
+ condition
543
555
  });
544
556
  }
545
557
  }
@@ -605,7 +617,7 @@ class NetworkListener {
605
617
  // re-installing after a clobber must call through the replacement, and a
606
618
  // stale generation must replay the chain exactly as it stood beneath it.
607
619
  const passthroughFetch = globalThis.fetch.bind(globalThis);
608
- this.originalFetch = passthroughFetch;
620
+ this.originalFetch = globalThis.fetch;
609
621
  const generation = ++this.fetchGeneration;
610
622
  const wrappedFetch = async (input, init) => {
611
623
  const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
@@ -623,7 +635,11 @@ class NetworkListener {
623
635
  }
624
636
  const startTime = Date.now();
625
637
  const requestId = `fetch_${++self.requestCounter}`;
626
- const method = init?.method || "GET";
638
+ const inputRequest = typeof input === "object" && "method" in input ? input : undefined;
639
+ const method = init?.method ?? inputRequest?.method ?? "GET";
640
+ const signal = init?.signal !== undefined ? init.signal : inputRequest?.signal;
641
+ throwIfAborted(signal);
642
+ const condition = snapshotNetworkCondition(url);
627
643
  const {
628
644
  url: cleanUrl,
629
645
  params
@@ -631,17 +647,18 @@ class NetworkListener {
631
647
 
632
648
  // Parse request headers
633
649
  let requestHeaders = {};
634
- if (init?.headers) {
635
- if (init.headers instanceof Headers) {
636
- init.headers.forEach((value, key) => {
650
+ const headers = init?.headers ?? inputRequest?.headers;
651
+ if (headers) {
652
+ if (headers instanceof Headers) {
653
+ headers.forEach((value, key) => {
637
654
  requestHeaders[key] = value;
638
655
  });
639
- } else if (Array.isArray(init.headers)) {
640
- init.headers.forEach(([key, value]) => {
656
+ } else if (Array.isArray(headers)) {
657
+ headers.forEach(([key, value]) => {
641
658
  requestHeaders[key] = value;
642
659
  });
643
660
  } else {
644
- requestHeaders = init.headers;
661
+ requestHeaders = headers;
645
662
  }
646
663
  }
647
664
 
@@ -673,7 +690,7 @@ class NetworkListener {
673
690
  * Skipped when `canSynthesizeResponse()` is false so a runtime without a
674
691
  * `Response` global degrades to a real request rather than a broken one.
675
692
  */
676
- const outcome = canSynthesizeResponse() ? overrideForRequest(url, method) : null;
693
+ const outcome = condition?.profile !== "offline" && canSynthesizeResponse() ? overrideForRequest(url, method) : null;
677
694
  const override = outcome ? markForOutcome(outcome) : undefined;
678
695
 
679
696
  // Emit request event
@@ -689,24 +706,28 @@ class NetworkListener {
689
706
  params: params || undefined,
690
707
  client: clientType
691
708
  },
692
- override
709
+ override,
710
+ condition
693
711
  });
694
712
  try {
695
- if (outcome) await sleep(outcome.delayMs);
713
+ if (condition || outcome) await waitBeforeDispatch((condition?.delayMs ?? 0) + (outcome?.delayMs ?? 0), signal);
714
+ throwIfAborted(signal);
715
+ if (condition?.profile === "offline") throw new TypeError("Network request failed (Buoy Offline)");
696
716
  if (outcome?.kind === "fail") throw synthesizeFetchError(outcome);
697
717
  let response;
698
718
  if (outcome?.kind === "respond") {
699
719
  response = synthesizeResponse(url, outcome);
700
720
  } else {
701
- // The flag spans the CALL only — see `insideOverriddenFetch`. It has
721
+ // The flag spans the CALL only — see `insideFetchHandoff`. It has
702
722
  // to be cleared before the await, or it would still be raised for
703
723
  // every unrelated request that starts while this one is in flight.
704
- insideOverriddenFetch = outcome != null;
724
+ const previousFetchHandoff = insideFetchHandoff;
725
+ insideFetchHandoff = true;
705
726
  let pending;
706
727
  try {
707
728
  pending = passthroughFetch(input, init);
708
729
  } finally {
709
- insideOverriddenFetch = false;
730
+ insideFetchHandoff = previousFetchHandoff;
710
731
  }
711
732
  response = await pending;
712
733
  }
@@ -728,7 +749,7 @@ class NetworkListener {
728
749
  * known, and the body is filled in when the stream closes: the store
729
750
  * merges a second `response` event onto the same request id.
730
751
  */
731
- const streamed = isStreamedContentType(response.headers?.get?.("content-type"));
752
+ const streamed = typeof response.body?.getReader === "function" || isStreamedContentType(response.headers?.get?.("content-type"));
732
753
 
733
754
  // Clone response to read body with size limits
734
755
  const responseClone = response.clone();
@@ -795,11 +816,18 @@ class NetworkListener {
795
816
  body,
796
817
  size: responseSize
797
818
  },
798
- override
819
+ override,
820
+ condition
799
821
  });
800
822
  if (streamed) {
801
823
  // Bounded, cancelled at the cap, and never awaited by the caller.
802
824
  void self.readStreamedBody(responseClone).then(late => {
825
+ let capturedBody = late.body;
826
+ if (response.headers?.get?.("content-type")?.includes("json")) {
827
+ try {
828
+ capturedBody = JSON.parse(late.body);
829
+ } catch {/* Partial or malformed JSON stays text. */}
830
+ }
803
831
  self.emit({
804
832
  type: "response",
805
833
  timestamp: new Date(),
@@ -818,10 +846,11 @@ class NetworkListener {
818
846
  status: response.status,
819
847
  statusText: response.statusText,
820
848
  headers: responseHeaders,
821
- body: late.body,
849
+ body: capturedBody,
822
850
  size: late.size
823
851
  },
824
- override
852
+ override,
853
+ condition
825
854
  });
826
855
  }).catch(() => {
827
856
  /* the caller's response is unaffected either way */
@@ -849,7 +878,8 @@ class NetworkListener {
849
878
  message: error instanceof Error ? error.message : "Network error",
850
879
  stack: error instanceof Error ? error.stack : undefined
851
880
  },
852
- override
881
+ override,
882
+ condition
853
883
  });
854
884
  throw error;
855
885
  }
@@ -870,18 +900,20 @@ class NetworkListener {
870
900
  this.originalXHRSend = passthroughSend;
871
901
  this.originalXHRSetRequestHeader = passthroughSetRequestHeader;
872
902
  const generation = ++this.xhrGeneration;
903
+ const pendingCapture = new WeakMap();
873
904
  const patchedOpen = function (method, url, async, user, password) {
874
- // Superseded generations must not re-stamp (a double stamp burns two
875
- // request ids per request) — just pass through.
905
+ // Native validation runs before replacing metadata or capture listeners.
906
+ const result = passthroughOpen.call(this, method, url, async ?? true, user, password);
876
907
  if (generation === self.xhrGeneration) {
908
+ pendingCapture.get(this)?.();
877
909
  const xhr = this;
878
- xhr._requestId = `xhr_${++self.requestCounter}`;
910
+ xhr._buoyRequestId = `xhr_${++self.requestCounter}`;
879
911
  xhr._method = method;
880
912
  xhr._url = url;
881
- xhr._startTime = Date.now();
913
+ xhr._buoyStartTime = Date.now();
882
914
  xhr._requestHeaders = {};
883
915
  }
884
- return passthroughOpen.call(this, method, url, async ?? true, user, password);
916
+ return result;
885
917
  };
886
918
 
887
919
  // Track request headers
@@ -896,14 +928,19 @@ class NetworkListener {
896
928
  // @ts-ignore - this does exist on native
897
929
  data) {
898
930
  // Superseded generation: silent pass-through (see the fetch wrapper).
899
- if (generation !== self.xhrGeneration) {
931
+ if (generation !== self.xhrGeneration || insideFetchHandoff) {
932
+ return passthroughSend.call(this, data);
933
+ }
934
+ if (this.readyState !== 1 || this._sent) {
900
935
  return passthroughSend.call(this, data);
901
936
  }
902
937
  const xhr = this;
903
- const requestId = xhr._requestId;
938
+ const requestId = xhr._buoyRequestId;
904
939
  const method = xhr._method || "GET";
905
940
  const url = xhr._url || "";
906
- const startTime = xhr._startTime;
941
+ const startTime = Date.now();
942
+ xhr._buoyStartTime = startTime;
943
+ xhr._buoyTtfb = undefined;
907
944
  const requestHeaders = xhr._requestHeaders || {};
908
945
 
909
946
  // Skip ignored URLs
@@ -943,14 +980,15 @@ class NetworkListener {
943
980
  * This is the layer that covers `axios` and raw XMLHttpRequest. It also
944
981
  * covers `fetch` on BARE React Native, where the whatwg-fetch polyfill
945
982
  * runs through XHR — which is why the fetch wrapper raises
946
- * `insideOverriddenFetch` around its pass-through, so one request can't
983
+ * `insideFetchHandoff` around its pass-through, so one request can't
947
984
  * be overridden twice.
948
985
  *
949
986
  * Matching uses the raw `url` (query string included), which is what the
950
987
  * developer sees in the list and writes into a rule. No-ops in production
951
988
  * builds; see `overrideForRequest`.
952
989
  */
953
- const outcome = insideOverriddenFetch ? null : overrideForRequest(url, method);
990
+ const condition = snapshotNetworkCondition(url);
991
+ const outcome = condition?.profile === "offline" ? null : overrideForRequest(url, method);
954
992
  const override = outcome ? markForOutcome(outcome) : undefined;
955
993
 
956
994
  // Emit request event
@@ -966,7 +1004,8 @@ class NetworkListener {
966
1004
  params: params || undefined,
967
1005
  client: clientType
968
1006
  },
969
- override
1007
+ override,
1008
+ condition
970
1009
  });
971
1010
 
972
1011
  // Track if we've already processed this request to avoid duplicate events
@@ -974,18 +1013,20 @@ class NetworkListener {
974
1013
  const processResponse = (isError = false) => {
975
1014
  if (processed) return;
976
1015
  processed = true;
977
- self.handleXHRResponse(this, requestId || "unknown", cleanUrl, method, requestHeaders, requestData, params, startTime || 0, isError, clientType, override);
1016
+ self.handleXHRResponse(this, requestId || "unknown", cleanUrl, method, requestHeaders, requestData, params, startTime || 0, isError, clientType, override, condition);
978
1017
  // Clean up event listeners after processing to prevent memory leaks
979
1018
  cleanup();
980
1019
  };
981
1020
 
982
1021
  // Cleanup function to remove event listeners
983
1022
  const cleanup = () => {
1023
+ pendingCapture.delete(this);
984
1024
  this.removeEventListener("load", loadListener);
985
1025
  this.removeEventListener("error", errorListener);
986
1026
  this.removeEventListener("abort", abortListener);
987
1027
  this.removeEventListener("readystatechange", readyStateListener);
988
1028
  };
1029
+ pendingCapture.set(this, cleanup);
989
1030
 
990
1031
  // Use addEventListener to listen to events WITHOUT replacing user handlers
991
1032
  // This is critical because React Native's XMLHttpRequest uses EventTarget
@@ -1007,8 +1048,8 @@ class NetworkListener {
1007
1048
  // TTFB here costs one comparison and one clock read.
1008
1049
  if (this.readyState === 2) {
1009
1050
  const xhr = this;
1010
- if (xhr._ttfb === undefined && xhr._startTime) {
1011
- xhr._ttfb = Date.now() - xhr._startTime;
1051
+ if (xhr._buoyTtfb === undefined && xhr._buoyStartTime) {
1052
+ xhr._buoyTtfb = Date.now() - xhr._buoyStartTime;
1012
1053
  }
1013
1054
  }
1014
1055
  if (this.readyState === 4 && !processed) {
@@ -1021,6 +1062,10 @@ class NetworkListener {
1021
1062
  this.addEventListener("error", errorListener);
1022
1063
  this.addEventListener("abort", abortListener);
1023
1064
  this.addEventListener("readystatechange", readyStateListener);
1065
+ if (condition) {
1066
+ runConditionXhr(this, url, condition, outcome, () => passthroughSend.call(this, data));
1067
+ return;
1068
+ }
1024
1069
  if (outcome) {
1025
1070
  // Listeners are attached above FIRST: `runOverride` drives the same
1026
1071
  // readyState transitions a real response would, and the interceptor has
@@ -39,8 +39,8 @@ export const MAX_PINNED = 25;
39
39
  export const MAX_SAVED = 50;
40
40
  /**
41
41
  * @deprecated Read the live limit with `useLimit("network.saved")` — this only
42
- * reports the FREE tier's value and is blind to the anonymous tier. Kept
43
- * because it is part of the package's public exports.
42
+ * reports the FREE tier's value and ignores the Weekend Pass. Kept because it
43
+ * is part of the package's public exports.
44
44
  */
45
45
  export const FREE_TIER_SAVED_LIMIT = TIER_LIMITS["network.saved"].free;
46
46
  /** Per-body cap on a snapshot. */
@@ -15,8 +15,8 @@ import { MAX_SAVED } from "./networkSavedStore";
15
15
  export function selectSavedEvents(savedRecords,
16
16
  /**
17
17
  * How many saves this tier may see — `useLimit("network.saved")`. Takes a
18
- * number rather than `isPro` because there are now three tiers, and a
19
- * boolean cannot express the anonymous one.
18
+ * number rather than `isPro` because Pro's cap is 50, not unlimited, and a
19
+ * boolean cannot express that.
20
20
  */
21
21
  limit, search) {
22
22
  /**
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import { NetworkConditionsIcon } from "./network/conditions/NetworkConditionsIcon";
3
4
  /**
4
5
  * Pre-configured network monitoring tool for FloatingDevTools
5
6
  *
@@ -17,7 +18,7 @@
17
18
  * ```
18
19
  */
19
20
 
20
- import { NetworkIcon, createToolFactory, defineToolPreset } from "@buoy-gg/shared-ui";
21
+ import { createToolFactory, defineToolPreset } from "@buoy-gg/shared-ui";
21
22
  import { NetworkModal } from "./network/components/NetworkModal";
22
23
  import { overrideRulesStore } from "./network/overrides/overrideRulesStore";
23
24
  import { networkEventStore } from "./network/utils/networkEventStore";
@@ -70,7 +71,7 @@ export const networkToolPreset = defineToolPreset({
70
71
  slot: "both",
71
72
  icon: ({
72
73
  size
73
- }) => /*#__PURE__*/_jsx(NetworkIcon, {
74
+ }) => /*#__PURE__*/_jsx(NetworkConditionsIcon, {
74
75
  size: size
75
76
  }),
76
77
  component: NetworkModal,
@@ -45,4 +45,6 @@ export { networkSavedStore, flagsForEventId, FREE_TIER_SAVED_LIMIT, MAX_PINNED,
45
45
  export { generateCurl } from "./network/utils/generateCurl";
46
46
  /** @internal */
47
47
  export { networkListener, addNetworkListener, removeAllNetworkListeners, } from "./network/utils/networkListener";
48
+ export { NETWORK_CONDITIONS, getNetworkCondition, setNetworkCondition, subscribeNetworkConditions } from "./network/conditions/store";
49
+ export type { NetworkConditionProfile, NetworkConditionStamp } from "./network/conditions/store";
48
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAOhE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAClF,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wCAAwC,CAAC;AAKhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAIpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAI9E,OAAO,EACL,eAAe,EACf,KAAK,qBAAqB,GAC3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAIhF,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAKtF,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AAKpC,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EACL,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB;AACtB;;;GAGG;AACH,KAAK,mBAAmB,GACzB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,SAAS,IAAI,kBAAkB,EAC/B,oBAAoB,IAAI,wBAAwB,EAChD,UAAU,IAAI,mBAAmB,EACjC,UAAU,IAAI,mBAAmB,EACjC,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EACL,2BAA2B,EAC3B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,oCAAoC,CAAC;AAO5C,gBAAgB;AAChB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE;;;GAGG;AACH,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,gBAAgB;AAChB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
@@ -53,4 +53,6 @@ export { filterNetworkEvents, applyIgnoredPatterns, } from "./network/utils/filt
53
53
  export { splitPinned, type PinnedSplit } from "./network/utils/withPinnedFirst";
54
54
  export { extractOperationName } from "./network/utils/extractOperationName";
55
55
  export { generateCurl } from "./network/utils/generateCurl";
56
+ export { NETWORK_CONDITIONS, getNetworkCondition, setNetworkCondition, subscribeNetworkConditions } from "./network/conditions/store";
57
+ export type { NetworkConditionProfile, NetworkConditionStamp } from "./network/conditions/store";
56
58
  //# sourceMappingURL=index.web.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../src/index.web.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../src/index.web.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkEventDetailView.d.ts","sourceRoot":"","sources":["../../../../src/network/components/NetworkEventDetailView.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,UAAU,CAAC;AA0B7D,UAAU,2BAA2B;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkRD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,sBAAsB,mEAoiBjC,CAAC"}
1
+ {"version":3,"file":"NetworkEventDetailView.d.ts","sourceRoot":"","sources":["../../../../src/network/components/NetworkEventDetailView.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,UAAU,CAAC;AA0B7D,UAAU,2BAA2B;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkRD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,sBAAsB,mEAqiBjC,CAAC"}
@@ -36,11 +36,12 @@ export interface NetworkHeaderMenuProps {
36
36
  * from the ⋯ should appear.
37
37
  */
38
38
  export declare function NetworkHeaderMenu({ onClose, children }: NetworkHeaderMenuProps): import("react").JSX.Element;
39
- export declare function NetworkHeaderMenuItem({ icon, label, detail, onPress, }: {
39
+ export declare function NetworkHeaderMenuItem({ icon, label, detail, testID, onPress, }: {
40
40
  icon: ReactNode;
41
41
  label: string;
42
42
  /** Right-aligned state, e.g. the active filter count. */
43
43
  detail?: string;
44
+ testID?: string;
44
45
  onPress: () => void;
45
46
  }): import("react").JSX.Element;
46
47
  //# sourceMappingURL=NetworkHeaderMenu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkHeaderMenu.d.ts","sourceRoot":"","sources":["../../../../src/network/components/NetworkHeaderMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,MAAM,EACN,YAAY,GACb,EAAE;IACD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,+BAoBA;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,sBAAsB,+BAY9E;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,KAAK,EACL,MAAM,EACN,OAAO,GACR,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAYA"}
1
+ {"version":3,"file":"NetworkHeaderMenu.d.ts","sourceRoot":"","sources":["../../../../src/network/components/NetworkHeaderMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,MAAM,EACN,YAAY,GACb,EAAE;IACD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,+BAoBA;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,sBAAsB,+BAY9E;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,KAAK,EACL,MAAM,EACN,MAAM,EACN,OAAO,GACR,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAeA"}