@buoy-gg/network 7.0.78 → 7.0.80

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 (133) hide show
  1. package/README.md +76 -2
  2. package/lib/commonjs/expo-network.js +1 -0
  3. package/lib/commonjs/index.js +1 -1
  4. package/lib/commonjs/index.web.js +1 -1
  5. package/lib/commonjs/netinfo.js +1 -0
  6. package/lib/commonjs/network/components/NetworkEventDetailView.js +2 -2
  7. package/lib/commonjs/network/components/NetworkEventDetailView.web.js +2 -2
  8. package/lib/commonjs/network/components/NetworkEventItemCompact.js +2 -2
  9. package/lib/commonjs/network/components/NetworkEventItemCompact.web.js +1 -1
  10. package/lib/commonjs/network/components/NetworkModal.js +1 -1
  11. package/lib/commonjs/network/components/sockets/NetworkSocketsButton.js +1 -0
  12. package/lib/commonjs/network/components/sockets/NetworkSocketsScreen.js +1 -0
  13. package/lib/commonjs/network/components/sockets/SocketFrameView.js +1 -0
  14. package/lib/commonjs/network/components/sockets/SocketListView.js +1 -0
  15. package/lib/commonjs/network/components/sockets/SocketRows.js +1 -0
  16. package/lib/commonjs/network/components/sockets/SocketTricksView.js +1 -0
  17. package/lib/commonjs/network/conditions/NetworkConditionsControl.js +1 -1
  18. package/lib/commonjs/network/conditions/NetworkConditionsControl.test.js +1 -1
  19. package/lib/commonjs/network/conditions/NetworkConditionsIcon.js +1 -1
  20. package/lib/commonjs/network/conditions/NetworkFloatingTool.js +1 -1
  21. package/lib/commonjs/network/conditions/NetworkFloatingTool.test.js +1 -1
  22. package/lib/commonjs/network/conditions/connectivity/netInfoFacade.js +1 -0
  23. package/lib/commonjs/network/conditions/connectivity/patchNetwork.js +1 -0
  24. package/lib/commonjs/network/conditions/pacer.js +1 -0
  25. package/lib/commonjs/network/conditions/profiles.js +1 -0
  26. package/lib/commonjs/network/conditions/remoteState.js +1 -0
  27. package/lib/commonjs/network/conditions/store.js +1 -1
  28. package/lib/commonjs/network/conditions/wait.js +1 -1
  29. package/lib/commonjs/network/conditions/xhr.js +1 -1
  30. package/lib/commonjs/network/hooks/useSocketsState.js +1 -0
  31. package/lib/commonjs/network/overrides/engine.js +1 -1
  32. package/lib/commonjs/network/overrides/matchRule.js +1 -1
  33. package/lib/commonjs/network/overrides/overrideRulesStore.js +1 -1
  34. package/lib/commonjs/network/sockets/findProblems.js +1 -0
  35. package/lib/commonjs/network/sockets/foldFrames.js +1 -0
  36. package/lib/commonjs/network/sockets/format.js +1 -0
  37. package/lib/commonjs/network/sockets/readMessage.js +1 -0
  38. package/lib/commonjs/network/sockets/socketMoments.js +1 -0
  39. package/lib/commonjs/network/sockets/socketStore.js +1 -0
  40. package/lib/commonjs/network/sockets/socketsSyncAdapter.js +1 -0
  41. package/lib/commonjs/network/sockets/types.js +1 -0
  42. package/lib/commonjs/network/sockets/webSocketPatch.js +1 -0
  43. package/lib/commonjs/network/sync/networkSyncAdapter.js +1 -1
  44. package/lib/commonjs/network/utils/generateNetworkCopyText.js +1 -0
  45. package/lib/commonjs/network/utils/networkEventStore.js +1 -1
  46. package/lib/commonjs/network/utils/networkListener.js +4 -4
  47. package/lib/commonjs/network/utils/startNetworkCapture.js +1 -1
  48. package/lib/commonjs/preset.js +1 -1
  49. package/lib/module/expo-network.js +1 -0
  50. package/lib/module/index.js +1 -1
  51. package/lib/module/index.web.js +1 -1
  52. package/lib/module/netinfo.js +1 -0
  53. package/lib/module/network/components/NetworkEventDetailView.js +2 -2
  54. package/lib/module/network/components/NetworkEventDetailView.web.js +2 -2
  55. package/lib/module/network/components/NetworkEventItemCompact.js +2 -2
  56. package/lib/module/network/components/NetworkEventItemCompact.web.js +1 -1
  57. package/lib/module/network/components/NetworkModal.js +1 -1
  58. package/lib/module/network/components/sockets/NetworkSocketsButton.js +1 -0
  59. package/lib/module/network/components/sockets/NetworkSocketsScreen.js +1 -0
  60. package/lib/module/network/components/sockets/SocketFrameView.js +1 -0
  61. package/lib/module/network/components/sockets/SocketListView.js +1 -0
  62. package/lib/module/network/components/sockets/SocketRows.js +1 -0
  63. package/lib/module/network/components/sockets/SocketTricksView.js +1 -0
  64. package/lib/module/network/conditions/NetworkConditionsControl.js +1 -1
  65. package/lib/module/network/conditions/NetworkConditionsControl.test.js +1 -1
  66. package/lib/module/network/conditions/NetworkConditionsIcon.js +1 -1
  67. package/lib/module/network/conditions/NetworkFloatingTool.js +1 -1
  68. package/lib/module/network/conditions/NetworkFloatingTool.test.js +1 -1
  69. package/lib/module/network/conditions/connectivity/netInfoFacade.js +1 -0
  70. package/lib/module/network/conditions/connectivity/patchNetwork.js +1 -0
  71. package/lib/module/network/conditions/pacer.js +1 -0
  72. package/lib/module/network/conditions/profiles.js +1 -0
  73. package/lib/module/network/conditions/remoteState.js +1 -0
  74. package/lib/module/network/conditions/store.js +1 -1
  75. package/lib/module/network/conditions/wait.js +1 -1
  76. package/lib/module/network/conditions/xhr.js +1 -1
  77. package/lib/module/network/hooks/useSocketsState.js +1 -0
  78. package/lib/module/network/overrides/engine.js +1 -1
  79. package/lib/module/network/overrides/matchRule.js +1 -1
  80. package/lib/module/network/overrides/overrideRulesStore.js +1 -1
  81. package/lib/module/network/sockets/findProblems.js +1 -0
  82. package/lib/module/network/sockets/foldFrames.js +1 -0
  83. package/lib/module/network/sockets/format.js +1 -0
  84. package/lib/module/network/sockets/readMessage.js +1 -0
  85. package/lib/module/network/sockets/socketMoments.js +1 -0
  86. package/lib/module/network/sockets/socketStore.js +1 -0
  87. package/lib/module/network/sockets/socketsSyncAdapter.js +1 -0
  88. package/lib/module/network/sockets/types.js +1 -0
  89. package/lib/module/network/sockets/webSocketPatch.js +1 -0
  90. package/lib/module/network/sync/networkSyncAdapter.js +1 -1
  91. package/lib/module/network/utils/generateNetworkCopyText.js +23 -22
  92. package/lib/module/network/utils/networkEventStore.js +1 -1
  93. package/lib/module/network/utils/networkListener.js +4 -4
  94. package/lib/module/network/utils/startNetworkCapture.js +1 -1
  95. package/lib/module/preset.js +1 -1
  96. package/lib/typescript/expo-network.d.ts +2 -0
  97. package/lib/typescript/index.d.ts +14 -2
  98. package/lib/typescript/index.web.d.ts +7 -2
  99. package/lib/typescript/netinfo.d.ts +3 -0
  100. package/lib/typescript/network/components/sockets/NetworkSocketsButton.d.ts +17 -0
  101. package/lib/typescript/network/components/sockets/NetworkSocketsScreen.d.ts +19 -0
  102. package/lib/typescript/network/components/sockets/SocketFrameView.d.ts +9 -0
  103. package/lib/typescript/network/components/sockets/SocketListView.d.ts +9 -0
  104. package/lib/typescript/network/components/sockets/SocketRows.d.ts +19 -0
  105. package/lib/typescript/network/components/sockets/SocketTricksView.d.ts +23 -0
  106. package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts +5 -2
  107. package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts +4 -3
  108. package/lib/typescript/network/conditions/connectivity/netInfoFacade.d.ts +3 -0
  109. package/lib/typescript/network/conditions/connectivity/patchNetwork.d.ts +24 -0
  110. package/lib/typescript/network/conditions/pacer.d.ts +16 -0
  111. package/lib/typescript/network/conditions/profiles.d.ts +57 -0
  112. package/lib/typescript/network/conditions/remoteState.d.ts +4 -0
  113. package/lib/typescript/network/conditions/store.d.ts +45 -19
  114. package/lib/typescript/network/conditions/xhr.d.ts +1 -1
  115. package/lib/typescript/network/hooks/useSocketsState.d.ts +3 -0
  116. package/lib/typescript/network/overrides/engine.d.ts +14 -0
  117. package/lib/typescript/network/overrides/matchRule.d.ts +3 -0
  118. package/lib/typescript/network/overrides/overrideRulesStore.d.ts +22 -0
  119. package/lib/typescript/network/overrides/types.d.ts +33 -0
  120. package/lib/typescript/network/sockets/findProblems.d.ts +31 -0
  121. package/lib/typescript/network/sockets/foldFrames.d.ts +50 -0
  122. package/lib/typescript/network/sockets/format.d.ts +19 -0
  123. package/lib/typescript/network/sockets/readMessage.d.ts +41 -0
  124. package/lib/typescript/network/sockets/socketMoments.d.ts +24 -0
  125. package/lib/typescript/network/sockets/socketStore.d.ts +94 -0
  126. package/lib/typescript/network/sockets/socketsSyncAdapter.d.ts +66 -0
  127. package/lib/typescript/network/sockets/types.d.ts +139 -0
  128. package/lib/typescript/network/sockets/webSocketPatch.d.ts +57 -0
  129. package/lib/typescript/network/sync/networkSyncAdapter.d.ts +29 -12
  130. package/lib/typescript/network/types/index.d.ts +6 -0
  131. package/lib/typescript/network/utils/networkListener.d.ts +10 -0
  132. package/lib/web/index.mjs +60 -59
  133. package/package.json +26 -3
@@ -18,6 +18,10 @@ export { networkListener, startNetworkListener, stopNetworkListener, addNetworkL
18
18
  export type { NetworkingEvent, NetworkingEventListener, } from "./network/utils/networkListener";
19
19
  export { networkEventStore } from "./network/utils/networkEventStore";
20
20
  export { networkSavedStore, flagsForEventId, } from "./network/utils/networkSavedStore";
21
+ export { socketStore } from "./network/sockets/socketStore";
22
+ export { socketsSyncAdapter, querySockets } from "./network/sockets/socketsSyncAdapter";
23
+ export { onSocketMoment } from "./network/sockets/socketMoments";
24
+ export type { SocketConnection, SocketFrame, SocketProblem, SocketsState } from "./network/sockets/types";
21
25
  export type { NetworkEvent, NetworkStats, NetworkFilter, NetworkTimings, } from "./network/types";
22
26
  export { useNetworkEvents, FREE_TIER_REQUEST_LIMIT } from "./network/hooks/useNetworkEvents";
23
27
  export { useNetworkEventList } from "./network/hooks/useNetworkEventList";
@@ -53,6 +57,7 @@ export { filterNetworkEvents, applyIgnoredPatterns, } from "./network/utils/filt
53
57
  export { splitPinned, type PinnedSplit } from "./network/utils/withPinnedFirst";
54
58
  export { extractOperationName } from "./network/utils/extractOperationName";
55
59
  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";
60
+ export { NETWORK_CONDITIONS, getNetworkCondition, setNetworkCondition, subscribeNetworkConditions, getNetworkConditions, setNetworkConditions, getNetworkConnection, getConditionsRevision, networkConditionsActive } from "./network/conditions/store";
61
+ export type { NetworkConditionProfile, NetworkConditionStamp, NetworkConditionsState, NetworkConditionsChange, NetworkConnection } from "./network/conditions/store";
62
+ export { chooseConditionsSnapshot } from "./network/conditions/remoteState";
58
63
  //# sourceMappingURL=index.web.d.ts.map
@@ -0,0 +1,3 @@
1
+ /** Call before app imports that read NetInfo. No native code is added. */
2
+ export declare function installNetInfoConditions(): void;
3
+ //# sourceMappingURL=netinfo.d.ts.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Header button for the Sockets screen, and the live "a socket is open" light.
3
+ *
4
+ * A self-subscribing leaf like the Overrides button, so socket traffic never
5
+ * re-renders the modal shell. It stays hidden until the app opens its first
6
+ * socket: most apps have none, and the header is already full. The ⋯ menu
7
+ * always has a Sockets item.
8
+ *
9
+ * Green = a socket is open. A red count = problems Buoy found. Amber = a
10
+ * trick is on (frozen, blocked, offline), because a socket Buoy is breaking
11
+ * looks exactly like a real bug.
12
+ */
13
+ export declare function NetworkSocketsButton({ onPress, paused }: {
14
+ onPress: () => void;
15
+ paused: boolean;
16
+ }): import("react").JSX.Element | null;
17
+ //# sourceMappingURL=NetworkSocketsButton.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { type MutableRefObject } from "react";
2
+ /**
3
+ * The Sockets screen of the Network tool: the list, one message, and Tricks.
4
+ *
5
+ * A router only (rule3/rule4): it holds which of the three is showing and
6
+ * renders all three as stable siblings that gate themselves. Back steps out of
7
+ * a message or Tricks before it leaves the screen, through the same
8
+ * `backHandlerRef` hand-off the Overrides screen uses.
9
+ */
10
+ export declare function NetworkSocketsScreen({ visible, paused, isPro, onUpgradePress, backHandlerRef, onTitleChange, }: {
11
+ visible: boolean;
12
+ paused: boolean;
13
+ isPro: boolean;
14
+ onUpgradePress: () => void;
15
+ backHandlerRef?: MutableRefObject<(() => boolean) | null>;
16
+ /** The header's title for what's showing: "Sockets", "Message" or "Tricks". */
17
+ onTitleChange?: (title: string) => void;
18
+ }): import("react").JSX.Element | null;
19
+ //# sourceMappingURL=NetworkSocketsScreen.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { SocketFrame } from "../../sockets/types";
2
+ export declare function SocketFrameView({ visible, frameId, isPro, onUpgradePress, onEdit, }: {
3
+ visible: boolean;
4
+ frameId: string | null;
5
+ isPro: boolean;
6
+ onUpgradePress: () => void;
7
+ onEdit: (frame: SocketFrame) => void;
8
+ }): import("react").JSX.Element | null;
9
+ //# sourceMappingURL=SocketFrameView.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { SocketFrame } from "../../sockets/types";
2
+ export declare function SocketListView({ visible, paused, search, onOpenFrame, onOpenTricks, }: {
3
+ visible: boolean;
4
+ paused: boolean;
5
+ search: string;
6
+ onOpenFrame: (frame: SocketFrame) => void;
7
+ onOpenTricks: (socketId: string | null) => void;
8
+ }): import("react").JSX.Element | null;
9
+ //# sourceMappingURL=SocketListView.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { SocketRow } from "../../sockets/foldFrames";
2
+ import type { SocketFrame } from "../../sockets/types";
3
+ /**
4
+ * `onOpen`, not `onPress`: an agent's tap_element calls the first `onPress` it
5
+ * finds by name, and it must land on the touchable (which passes the frame),
6
+ * not on this component's prop with a touch event in place of the frame.
7
+ *
8
+ * A folded burst opens up on tap (`onExpand`) instead, one row per message.
9
+ */
10
+ export declare function SocketMessageRow({ row, onOpen, onExpand, }: {
11
+ row: SocketRow;
12
+ onOpen: (frame: SocketFrame) => void;
13
+ onExpand: (foldKey: string) => void;
14
+ }): import("react").JSX.Element;
15
+ export declare function SocketLifecycleRow({ row, attempt }: {
16
+ row: SocketRow;
17
+ attempt?: number;
18
+ }): import("react").JSX.Element;
19
+ //# sourceMappingURL=SocketRows.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Socket tricks: make the socket misbehave on purpose, and watch the app's own
3
+ * code deal with it.
4
+ *
5
+ * - Push a message into the app as if the server sent it, or send one to the
6
+ * server.
7
+ * - Drop it (1006, like lost signal), kick it out (1008, like a bad token),
8
+ * freeze it (looks open, says nothing), or block every new socket.
9
+ *
10
+ * Everything here is fake, so the screen says what is on, and Reset turns it
11
+ * all off. Pro, like response overrides.
12
+ */
13
+ export interface TricksDraft {
14
+ socketId: string | null;
15
+ data: string;
16
+ }
17
+ export declare function SocketTricksView({ visible, draft, isPro, onUpgradePress, }: {
18
+ visible: boolean;
19
+ draft: TricksDraft | null;
20
+ isPro: boolean;
21
+ onUpgradePress: () => void;
22
+ }): import("react").JSX.Element | null;
23
+ //# sourceMappingURL=SocketTricksView.d.ts.map
@@ -1,12 +1,15 @@
1
- import { type NetworkConditionProfile } from "./store";
1
+ import { type NetworkConditionProfile, type NetworkConditionsState, type NetworkConnection } from "./store";
2
2
  export interface RemoteNetworkConditions {
3
3
  /** Identity of the connected device session, used to ignore stale UI completions. */
4
4
  targetId?: string;
5
5
  profile: NetworkConditionProfile | null;
6
+ state?: NetworkConditionsState;
7
+ onConnectionChange?(connection: NetworkConnection): Promise<unknown>;
6
8
  available: boolean;
7
9
  onChange(profile: NetworkConditionProfile): Promise<unknown>;
8
10
  }
9
- export declare function NetworkConditionsControl({ remote }: {
11
+ export declare function NetworkConditionsControl({ remote, compact }: {
10
12
  remote?: RemoteNetworkConditions;
13
+ compact?: boolean;
11
14
  }): import("react").JSX.Element;
12
15
  //# sourceMappingURL=NetworkConditionsControl.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { type FloatingToolRenderContext } from "@buoy-gg/shared-ui";
2
- import type { RemoteNetworkConditions } from "./NetworkConditionsControl";
2
+ import { type RemoteNetworkConditions } from "./NetworkConditionsControl";
3
3
  /** A live source keeps the desktop strip current after its launching panel closes. */
4
4
  export declare function createRemoteConditionsSource(): {
5
5
  getSnapshot: () => RemoteNetworkConditions | undefined;
@@ -8,9 +8,10 @@ export declare function createRemoteConditionsSource(): {
8
8
  };
9
9
  type RemoteSource = ReturnType<typeof createRemoteConditionsSource>;
10
10
  export declare function registerLocalNetworkFloatingTool(): () => void;
11
- export declare function openNetworkFloatingTool(source?: RemoteSource): void;
12
- export declare function NetworkFloatingTool({ id, revealToken, dismiss, source }: FloatingToolRenderContext & {
11
+ export declare function openNetworkFloatingTool(source?: RemoteSource, showControls?: boolean): void;
12
+ export declare function NetworkFloatingTool({ id, revealToken, dismiss, source, showControls }: FloatingToolRenderContext & {
13
13
  source?: RemoteSource;
14
+ showControls?: boolean;
14
15
  }): import("react").JSX.Element;
15
16
  export {};
16
17
  //# sourceMappingURL=NetworkFloatingTool.d.ts.map
@@ -0,0 +1,3 @@
1
+ /** Public reads also need masking when a custom reachability probe updates the cache. */
2
+ export declare function wrapNetInfoApi(api: Record<string, any>): void;
3
+ //# sourceMappingURL=netInfoFacade.d.ts.map
@@ -0,0 +1,24 @@
1
+ import type { NetworkConnection } from "../profiles";
2
+ export interface ConnectionState {
3
+ type?: string;
4
+ details?: unknown;
5
+ isConnected?: boolean | null;
6
+ isInternetReachable?: boolean | null;
7
+ }
8
+ export interface ConnectivityModule {
9
+ getCurrentState(requestedInterface?: string): Promise<ConnectionState>;
10
+ eventEmitter: {
11
+ addListener(event: string, listener: (state: ConnectionState) => void): {
12
+ remove(): void;
13
+ };
14
+ listenerCount?(event: string): number;
15
+ };
16
+ }
17
+ export declare function maskConnection(state: ConnectionState, mode: NetworkConnection, expo?: boolean): ConnectionState;
18
+ /** Install before the library creates any state managers or app listeners. */
19
+ export declare function patchConnectionState(native: ConnectivityModule, mode: () => NetworkConnection, subscribe: (listener: () => void) => () => void, options?: {
20
+ eventName?: string;
21
+ expo?: boolean;
22
+ receiver?: object;
23
+ }): () => void;
24
+ //# sourceMappingURL=patchNetwork.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { UploadCap } from "./profiles";
2
+ export declare const chunkSize: (rate: number) => number;
3
+ export declare const utf8Length: (text: string) => number;
4
+ /** Returns null when the native encoder owns a body whose byte size is unknown. */
5
+ export declare function bodyByteLength(body: unknown): number | null;
6
+ /** The upload is a pre-send simulation. No bytes are sent during these ticks. */
7
+ export declare function paceByteCount(bytes: number, rate: number, signal?: AbortSignal | null, progress?: (loaded: number, total: number) => void): Promise<void>;
8
+ export declare function uploadBodySize(input: RequestInfo | URL, init?: RequestInit): UploadCap;
9
+ /** Inspect sizes only. Never read a stream, open a URI, or alter the body. */
10
+ export declare function uploadSize(body: unknown): UploadCap;
11
+ /** Carry timer overshoot forward, but never bank idle time between reads. */
12
+ export declare function createBytePacer(rate: number): (bytes: number, signal?: AbortSignal | null) => Promise<void>;
13
+ export declare function pacedStream(source: ReadableStream<Uint8Array>, rate: number, signal?: AbortSignal | null, observe?: (chunk: Uint8Array | null, error?: unknown) => void): ReadableStream<Uint8Array<ArrayBufferLike>>;
14
+ /** Wrap body delivery without assuming RN's Response constructor accepts streams. */
15
+ export declare function paceResponse(response: Response, rate: number, signal?: AbortSignal | null, observe?: (chunk: Uint8Array | null, error?: unknown) => void, noBody?: boolean): Response;
16
+ //# sourceMappingURL=pacer.d.ts.map
@@ -0,0 +1,57 @@
1
+ export declare const NETWORK_CONDITIONS: {
2
+ readonly normal: {
3
+ readonly label: "Normal";
4
+ readonly delayMs: 0;
5
+ };
6
+ readonly offline: {
7
+ readonly label: "Offline (requests)";
8
+ readonly delayMs: 0;
9
+ };
10
+ readonly slow: {
11
+ readonly label: "Slow (+500 ms)";
12
+ readonly delayMs: 500;
13
+ };
14
+ readonly verySlow: {
15
+ readonly label: "Very slow (+2000 ms)";
16
+ readonly delayMs: 2000;
17
+ };
18
+ readonly slow3g: {
19
+ readonly label: "Slow 3G";
20
+ readonly delayMs: 2000;
21
+ readonly downloadBytesPerSecond: 50000;
22
+ readonly uploadBytesPerSecond: 50000;
23
+ };
24
+ readonly slow4g: {
25
+ readonly label: "Slow 4G";
26
+ readonly delayMs: 562.5;
27
+ readonly downloadBytesPerSecond: 180000;
28
+ readonly uploadBytesPerSecond: 84375;
29
+ };
30
+ readonly fast4g: {
31
+ readonly label: "Fast 4G";
32
+ readonly delayMs: 165;
33
+ readonly downloadBytesPerSecond: 1012500;
34
+ readonly uploadBytesPerSecond: 168750;
35
+ };
36
+ };
37
+ export type NetworkConditionProfile = keyof typeof NETWORK_CONDITIONS;
38
+ export type NetworkConnection = "auto" | "real" | "offline" | "wifi" | "cellular" | "noInternet";
39
+ export declare const CONNECTIONS: NetworkConnection[];
40
+ export interface NetworkConditionStamp {
41
+ readonly profile: NetworkConditionProfile;
42
+ readonly delayMs: number;
43
+ readonly downloadBytesPerSecond?: number;
44
+ readonly uploadBytesPerSecond?: number;
45
+ readonly uploadCap?: UploadCap;
46
+ }
47
+ export interface UploadCap {
48
+ readonly knownBytes: number;
49
+ readonly status: "applied" | "partial" | "not-applied";
50
+ readonly note?: string;
51
+ }
52
+ export declare const CONDITIONS_SCOPE: {
53
+ download: string;
54
+ upload: string;
55
+ transports: string;
56
+ };
57
+ //# sourceMappingURL=profiles.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { NetworkConditionsState } from "./store";
2
+ /** A new runtime needs a fresh read; old snapshots cannot rearm its controls. */
3
+ export declare function chooseConditionsSnapshot(confirmed: NetworkConditionsState | null, snapshot?: NetworkConditionsState): NetworkConditionsState | null;
4
+ //# sourceMappingURL=remoteState.d.ts.map
@@ -1,26 +1,52 @@
1
- export declare const NETWORK_CONDITIONS: {
2
- readonly normal: {
3
- readonly label: "Normal";
4
- readonly delayMs: 0;
5
- };
6
- readonly offline: {
7
- readonly label: "Offline (requests)";
8
- readonly delayMs: 0;
9
- };
10
- readonly slow: {
11
- readonly label: "Slow (+500 ms)";
12
- readonly delayMs: 500;
1
+ import { type NetworkConditionProfile, type NetworkConnection, type NetworkConditionStamp } from "./profiles";
2
+ export { NETWORK_CONDITIONS, CONDITIONS_SCOPE } from "./profiles";
3
+ export type { NetworkConditionProfile, NetworkConnection, NetworkConditionStamp } from "./profiles";
4
+ export interface ConnectionSupport {
5
+ supported: boolean;
6
+ reason?: string;
7
+ }
8
+ declare const connectionSupport: {
9
+ netInfo: ConnectionSupport;
10
+ expoNetwork: ConnectionSupport;
11
+ };
12
+ export declare const getNetworkConnection: () => NetworkConnection;
13
+ export declare const getConditionsRevision: () => number;
14
+ export declare const getEffectiveNetworkConnection: () => "real" | "offline" | "wifi" | "cellular" | "noInternet";
15
+ export declare const networkConditionsActive: () => boolean;
16
+ export declare function setConnectionSupport(key: keyof typeof connectionSupport, value: ConnectionSupport): void;
17
+ export declare function getNetworkConditions(): {
18
+ version: 2;
19
+ runtimeId: string;
20
+ revision: number;
21
+ profile: "offline" | "normal" | "slow" | "verySlow" | "slow3g" | "slow4g" | "fast4g";
22
+ connection: NetworkConnection;
23
+ available: boolean;
24
+ active: boolean;
25
+ delayMs: number;
26
+ downloadBytesPerSecond: number | null;
27
+ uploadBytesPerSecond: number | null;
28
+ capabilities: {
29
+ fetch: string;
30
+ xhr: string;
31
+ upload: string;
32
+ webSocket: string;
33
+ nativeImages: boolean;
34
+ nativeModules: boolean;
35
+ netInfo: ConnectionSupport;
36
+ expoNetwork: ConnectionSupport;
13
37
  };
14
- readonly verySlow: {
15
- readonly label: "Very slow (+2000 ms)";
16
- readonly delayMs: 2000;
38
+ scope: {
39
+ download: string;
40
+ upload: string;
41
+ transports: string;
17
42
  };
18
43
  };
19
- export type NetworkConditionProfile = keyof typeof NETWORK_CONDITIONS;
20
- export interface NetworkConditionStamp {
21
- readonly profile: NetworkConditionProfile;
22
- readonly delayMs: number;
44
+ export type NetworkConditionsState = ReturnType<typeof getNetworkConditions>;
45
+ export interface NetworkConditionsChange {
46
+ profile?: NetworkConditionProfile;
47
+ connection?: NetworkConnection;
23
48
  }
49
+ export declare function setNetworkConditions(value?: unknown): NetworkConditionsState;
24
50
  export declare const networkConditionsRuntimeId: string;
25
51
  export declare const conditionsCanApply: () => boolean;
26
52
  export declare const getNetworkCondition: () => NetworkConditionProfile;
@@ -1,5 +1,5 @@
1
1
  import type { OverrideOutcome } from "../overrides/types";
2
2
  import type { NetworkConditionStamp } from "./store";
3
3
  /** Active simulation uses a send-to-completion deadline, including the wait. */
4
- export declare function runConditionXhr(target: XMLHttpRequest, url: string, condition: NetworkConditionStamp, outcome: OverrideOutcome | null, dispatch: () => void): void;
4
+ export declare function runConditionXhr(target: XMLHttpRequest, url: string, condition: NetworkConditionStamp, outcome: OverrideOutcome | null, dispatch: () => void, body?: unknown): void;
5
5
  //# sourceMappingURL=xhr.d.ts.map
@@ -0,0 +1,3 @@
1
+ import type { SocketsState } from "../sockets/types";
2
+ export declare function useSocketsState(paused?: boolean): SocketsState;
3
+ //# sourceMappingURL=useSocketsState.d.ts.map
@@ -3,6 +3,10 @@ export interface OverrideHooks {
3
3
  getRules: () => readonly OverrideRule[];
4
4
  /** The rule APPLIED to a request. */
5
5
  recordHit: (ruleId: string) => void;
6
+ /** Resolves once saved rules are loaded (a request at app start waits for it). */
7
+ ready?: () => Promise<void>;
8
+ /** True once saved rules are loaded, for callers that can't wait on a promise first. */
9
+ isReady?: () => boolean;
6
10
  /**
7
11
  * The rule MATCHED a request, whether or not it applied.
8
12
  *
@@ -12,6 +16,16 @@ export interface OverrideHooks {
12
16
  recordMatch: (ruleId: string) => void;
13
17
  }
14
18
  export declare function setOverrideHooks(next: OverrideHooks | null): void;
19
+ /**
20
+ * Wait for saved rules before an async request decides. At app start the
21
+ * rules are still loading; a loaded bug case's sandbox would otherwise miss
22
+ * the app's first calls and let them reach real servers.
23
+ */
24
+ export declare function overrideRulesReady(): Promise<void>;
25
+ /** Whether saved rules are loaded yet. */
26
+ export declare function overrideRulesLoaded(): boolean;
27
+ /** Whether any rule reads the request body (a body match or a GraphQL operation). */
28
+ export declare function overrideRulesNeedBody(): boolean;
15
29
  /**
16
30
  * Whether a rule stored right now could ever be applied to a request.
17
31
  *
@@ -17,6 +17,9 @@ import type { OverrideRule } from "./types";
17
17
  */
18
18
  export declare function escapeRegex(pattern: string): string;
19
19
  export declare function compilePattern(pattern: string): RegExp;
20
+ /** A GraphQL JSON body (one operation or a batch) that names `operation`. */
21
+ /** JSON with object keys sorted at every level, so equal values give equal text. */
22
+ export declare function canonicalJson(value: unknown): string;
20
23
  /** Does this rule apply to this request? Ignores `enabled` — callers check it. */
21
24
  export declare function ruleMatches(rule: OverrideRule, url: string, method: string, headers?: Record<string, string>, body?: string): boolean;
22
25
  //# sourceMappingURL=matchRule.d.ts.map
@@ -111,6 +111,12 @@ declare class OverrideRulesStore {
111
111
  * needs no second check.
112
112
  */
113
113
  getRules(): readonly OverrideRule[];
114
+ /** Another tab loaded a bug case, and this tab hasn't got its block yet. */
115
+ private otherTabCase;
116
+ /** At page load, or another tab wrote or removed its loaded case. */
117
+ caseLockChanged(): void;
118
+ private sandboxCache;
119
+ private sandboxOnly;
114
120
  /**
115
121
  * The rule's real body, fetching it from the device when this surface only
116
122
  * has the stripped copy (see `OverrideRule.bodyOmitted`).
@@ -172,6 +178,7 @@ declare class OverrideRulesStore {
172
178
  * because a rule has to fire from app boot — with the Network tool closed and
173
179
  * nothing capturing. On the web `loadNow` has usually done it already.
174
180
  */
181
+ isLoaded(): boolean;
175
182
  ensureLoaded(): Promise<void>;
176
183
  /**
177
184
  * Web only: read the saved rules from localStorage right now.
@@ -216,7 +223,22 @@ declare class OverrideRulesStore {
216
223
  * morning") and not the failure mode it was built for.
217
224
  */
218
225
  noteHealthyLaunch(): void;
226
+ private persisted;
227
+ /**
228
+ * Writes go to disk one at a time, in order. Otherwise an older save still
229
+ * in flight could land after a newer one and put old rules back (a loaded
230
+ * case's block gone after a reload, Codex review round 10).
231
+ */
232
+ private writes;
219
233
  private persist;
234
+ /**
235
+ * Save the rules now and say whether they reached disk. A loaded bug case
236
+ * needs this: if its block rules only live in memory, a reload brings the
237
+ * case's state back with nothing blocking real calls (Codex review round 9).
238
+ * Waits for every earlier write, so none can land after it, and gives up
239
+ * (false) after SAVE_CHECK_MS.
240
+ */
241
+ saveChecked(): Promise<boolean>;
220
242
  private emit;
221
243
  }
222
244
  /** Singleton — one rule list per JS runtime. */
@@ -89,6 +89,39 @@ export interface OverrideRule {
89
89
  * asked first. A body that isn't text (FormData, a Blob) never matches.
90
90
  */
91
91
  bodyIncludes?: string;
92
+ /**
93
+ * Only GraphQL requests whose JSON body names this `operationName` (or a
94
+ * batch that holds it). Parsed, not matched as text, so spacing and key
95
+ * order in the body don't matter.
96
+ */
97
+ graphqlOperation?: string;
98
+ /**
99
+ * With graphqlOperation: only when that operation's `variables` equal this,
100
+ * written as JSON with its keys sorted (see canonicalJson). Parsed, so
101
+ * spacing and key order don't matter. Missing variables count as {}.
102
+ */
103
+ graphqlVariables?: string;
104
+ /**
105
+ * Only requests whose body is JSON equal to this, written with its keys
106
+ * sorted (see canonicalJson). Parsed, so spacing and key order don't matter.
107
+ * For REST calls that share one URL but differ by body, like
108
+ * `POST /search {"q":"fries"}` and `{"q":"pie"}`: a bug case's replay gives
109
+ * each body its own answer.
110
+ */
111
+ bodyJson?: string;
112
+ /**
113
+ * With `graphqlOperation`: only a single operation, never a batch (an
114
+ * array body). A bug case recorded the call alone, so its answer is one
115
+ * result, and a batch would get the wrong shape back.
116
+ */
117
+ graphqlSingle?: boolean;
118
+ /**
119
+ * Part of a loaded bug case's sandbox (bug links). Such a rule keeps
120
+ * applying while Buoy's account access is off, because the case's data is
121
+ * in the app either way and must not reach a real server, and it is never
122
+ * auto-paused at launch. Release builds still never apply any rule.
123
+ */
124
+ sandbox?: boolean;
92
125
  kind: OverrideRuleKind;
93
126
  /** `respond` only. Clamped to [STATUS_MIN, STATUS_MAX]. Defaults to 200. */
94
127
  status?: number;
@@ -0,0 +1,31 @@
1
+ import type { SocketConnection, SocketFrame, SocketProblem } from "./types";
2
+ /**
3
+ * The problems the Sockets screen turns red, and the MCP reports. Pure: the
4
+ * same frames give the same answer on the phone, on Desktop and in a test.
5
+ *
6
+ * Every rule here needs PROOF in the frames, because a false alarm teaches
7
+ * people to ignore the red. That is why "no reply" only fires for a message
8
+ * type that has been answered before: Haiven puts a `requestId` on typing
9
+ * messages too, and the server never answers those.
10
+ */
11
+ /** A request with no reply after this long is flagged. Haiven's own timeout. */
12
+ export declare const REPLY_TIMEOUT_MS = 10000;
13
+ /** More than this many opens to one URL inside STORM_WINDOW_MS is a storm. */
14
+ export declare const STORM_OPENS = 3;
15
+ export declare const STORM_WINDOW_MS = 15000;
16
+ /** This many sockets in a row to one URL that never opened: the app can't connect. */
17
+ export declare const CANT_CONNECT_TRIES = 3;
18
+ /** This many sign-in failures to one URL inside AUTH_WINDOW_MS is a loop. */
19
+ export declare const AUTH_FAILURES = 3;
20
+ export declare const AUTH_WINDOW_MS = 120000;
21
+ /** A socket open this long without a sign-in failure signed in: it ends a run of failures. */
22
+ export declare const SIGNED_IN_MS = 30000;
23
+ /**
24
+ * The message types that have been answered at least once, per socket URL.
25
+ * Built from the frames, so it survives nothing and needs no setup.
26
+ */
27
+ export declare function answeredTypes(frames: SocketFrame[], connections: Map<string, SocketConnection>): Map<string, Set<string>>;
28
+ export declare function findProblems(frames: SocketFrame[], connectionList: SocketConnection[], now: number,
29
+ /** Types answered before this capture's frames were cut (kept by the store). */
30
+ knownAnswered?: Map<string, Set<string>>): SocketProblem[];
31
+ //# sourceMappingURL=findProblems.d.ts.map
@@ -0,0 +1,50 @@
1
+ import type { SocketFrame, SocketProblem, SocketsState } from "./types";
2
+ /**
3
+ * What the Sockets list shows, from the store's frames. Pure.
4
+ *
5
+ * Two kinds of noise fold away so a chat socket reads like a conversation:
6
+ * heartbeats (counted on the socket card instead) and a burst of the same
7
+ * message (`chat.typing` ×18 becomes one row; a tap shows each one).
8
+ */
9
+ /** Same-type messages closer together than this fold into one row... */
10
+ export declare const BURST_GAP_MS = 1500;
11
+ /** ...when there are at least this many. Two chats a second apart are a conversation. */
12
+ export declare const FOLD_MIN = 3;
13
+ export interface SocketRow {
14
+ /** The newest frame of the row. Tapping the row opens it. */
15
+ frame: SocketFrame;
16
+ /** How many frames the row stands for (1 unless it's a burst). */
17
+ count: number;
18
+ /** A burst's oldest frame id. It stays the same as the burst grows, so it names the burst for `expanded`. */
19
+ foldKey?: string;
20
+ /** The first problem any of its frames is part of. */
21
+ problem?: SocketProblem;
22
+ }
23
+ export type SocketListFilter = {
24
+ kind: "all";
25
+ } | {
26
+ kind: "problems";
27
+ } | {
28
+ kind: "direction";
29
+ direction: "in" | "out";
30
+ } | {
31
+ kind: "type";
32
+ prefix: string;
33
+ };
34
+ export interface FoldOptions {
35
+ socketId?: string | null;
36
+ filter?: SocketListFilter;
37
+ showPings?: boolean;
38
+ search?: string;
39
+ /** Bursts (by `foldKey`) shown one row per message. */
40
+ expanded?: ReadonlySet<string>;
41
+ }
42
+ export declare function foldFrames(state: Pick<SocketsState, "frames" | "problems">, opts?: FoldOptions): SocketRow[];
43
+ /**
44
+ * A chip's prefix matches its family: `auth.` matches `auth.success` and the
45
+ * bare `auth` too, so one chip covers both.
46
+ */
47
+ export declare function matchesPrefix(type: string | undefined, prefix: string): boolean;
48
+ /** The busiest message names, for the filter chips: `chat.*`, `presence.*`. */
49
+ export declare function topTypePrefixes(frames: SocketFrame[], max?: number): string[];
50
+ //# sourceMappingURL=foldFrames.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { SocketConnection, SocketFrame } from "./types";
2
+ /** `10:14:52` */
3
+ export declare function clockTime(ms: number): string;
4
+ /** `42ms`, `3.2s`, `2m 14s`, `1h 3m` */
5
+ export declare function shortDuration(ms: number): string;
6
+ /** `wss://api.x/v0/ws` → `api.x/v0/ws` */
7
+ export declare function shortUrl(url: string): string;
8
+ /**
9
+ * `Closed 1006 · lost connection`. A 1006 on a socket that never opened was
10
+ * refused or turned away, so it says `couldn't connect` instead.
11
+ */
12
+ export declare function closeLabel(code: number | undefined, neverOpened?: boolean): string;
13
+ /** The connection card's status line, e.g. `Open 2m 14s`. */
14
+ export declare function connectionStatus(conn: SocketConnection, now: number): string;
15
+ /** A one-line preview of a message for a row. */
16
+ export declare function previewText(frame: SocketFrame): string;
17
+ /** Pretty JSON for the detail view, or the text as it came. */
18
+ export declare function prettyData(frame: SocketFrame): string;
19
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Turn one raw socket message into what the list shows: its name, the id that
3
+ * ties it to a reply, whether it's a heartbeat, and its text with secrets
4
+ * hidden. Pure, so the rules can be argued with in a unit test.
5
+ *
6
+ * Secrets are hidden BEFORE the message is stored, because the store feeds the
7
+ * Desktop mirror and the MCP: a token that reaches the store has already left.
8
+ */
9
+ /** Longest message text kept. Longer ones are cut and marked `truncated`. */
10
+ export declare const MAX_FRAME_CHARS: number;
11
+ export declare const HIDDEN = "[hidden]";
12
+ /**
13
+ * Longer messages are not parsed: parsing, hiding and printing 5 MB on every
14
+ * message would stall the app. Their first MAX_FRAME_CHARS are scrubbed as text.
15
+ */
16
+ export declare const MAX_PARSE_CHARS: number;
17
+ export interface ReadMessage {
18
+ data: string;
19
+ size: number;
20
+ binary?: boolean;
21
+ truncated?: boolean;
22
+ json?: boolean;
23
+ type?: string;
24
+ correlationId?: string;
25
+ ping?: boolean;
26
+ /** Carries a field only replies have (see REPLY_KEYS). */
27
+ replyShaped?: boolean;
28
+ }
29
+ /** Hide every value under a secret key, and any JWT anywhere. */
30
+ export declare function hideSecrets(value: unknown, depth?: number): unknown;
31
+ /**
32
+ * Text that couldn't be parsed, with secrets hidden as well as text allows:
33
+ * every JWT, and the value after any secret-looking key (`"token":"x"`, `pass=x`).
34
+ */
35
+ export declare function scrubText(text: string, depth?: number): string;
36
+ /** A URL with secret query values hidden: `wss://x/ws?token=[hidden]`. */
37
+ export declare function hideUrlSecrets(rawUrl: string): string;
38
+ /** `/v0/ws` part of a URL: what makes two sockets "the same socket". */
39
+ export declare function socketKey(url: string): string;
40
+ export declare function readMessage(raw: unknown): ReadMessage;
41
+ //# sourceMappingURL=readMessage.d.ts.map