@buoy-gg/network 7.0.79 → 7.0.81

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 +8 -0
  2. package/lib/commonjs/index.js +1 -1
  3. package/lib/commonjs/index.web.js +1 -1
  4. package/lib/commonjs/network/components/NetworkEventDetailView.js +1 -1
  5. package/lib/commonjs/network/components/NetworkEventDetailView.web.js +1 -1
  6. package/lib/commonjs/network/components/NetworkModal.js +1 -1
  7. package/lib/commonjs/network/components/sockets/NetworkSocketsButton.js +1 -0
  8. package/lib/commonjs/network/components/sockets/NetworkSocketsScreen.js +1 -0
  9. package/lib/commonjs/network/components/sockets/SocketFrameView.js +1 -0
  10. package/lib/commonjs/network/components/sockets/SocketListView.js +1 -0
  11. package/lib/commonjs/network/components/sockets/SocketRows.js +1 -0
  12. package/lib/commonjs/network/components/sockets/SocketTricksView.js +1 -0
  13. package/lib/commonjs/network/conditions/NetworkConditionsControl.js +1 -1
  14. package/lib/commonjs/network/conditions/profiles.js +1 -1
  15. package/lib/commonjs/network/conditions/store.js +1 -1
  16. package/lib/commonjs/network/hooks/useSocketsState.js +1 -0
  17. package/lib/commonjs/network/overrides/engine.js +1 -1
  18. package/lib/commonjs/network/overrides/matchRule.js +1 -1
  19. package/lib/commonjs/network/overrides/overrideRulesStore.js +1 -1
  20. package/lib/commonjs/network/sockets/findProblems.js +1 -0
  21. package/lib/commonjs/network/sockets/foldFrames.js +1 -0
  22. package/lib/commonjs/network/sockets/format.js +1 -0
  23. package/lib/commonjs/network/sockets/readMessage.js +1 -0
  24. package/lib/commonjs/network/sockets/socketMoments.js +1 -0
  25. package/lib/commonjs/network/sockets/socketStore.js +1 -0
  26. package/lib/commonjs/network/sockets/socketsSyncAdapter.js +1 -0
  27. package/lib/commonjs/network/sockets/types.js +1 -0
  28. package/lib/commonjs/network/sockets/webSocketPatch.js +1 -0
  29. package/lib/commonjs/network/sync/networkSyncAdapter.js +1 -1
  30. package/lib/commonjs/network/utils/networkEventStore.js +1 -1
  31. package/lib/commonjs/network/utils/networkListener.js +4 -4
  32. package/lib/commonjs/network/utils/startNetworkCapture.js +1 -1
  33. package/lib/commonjs/preset.js +1 -1
  34. package/lib/module/index.js +1 -1
  35. package/lib/module/index.web.js +1 -1
  36. package/lib/module/network/components/NetworkEventDetailView.js +1 -1
  37. package/lib/module/network/components/NetworkEventDetailView.web.js +1 -1
  38. package/lib/module/network/components/NetworkModal.js +1 -1
  39. package/lib/module/network/components/sockets/NetworkSocketsButton.js +1 -0
  40. package/lib/module/network/components/sockets/NetworkSocketsScreen.js +1 -0
  41. package/lib/module/network/components/sockets/SocketFrameView.js +1 -0
  42. package/lib/module/network/components/sockets/SocketListView.js +1 -0
  43. package/lib/module/network/components/sockets/SocketRows.js +1 -0
  44. package/lib/module/network/components/sockets/SocketTricksView.js +1 -0
  45. package/lib/module/network/conditions/NetworkConditionsControl.js +1 -1
  46. package/lib/module/network/conditions/profiles.js +1 -1
  47. package/lib/module/network/conditions/store.js +1 -1
  48. package/lib/module/network/hooks/useSocketsState.js +1 -0
  49. package/lib/module/network/overrides/engine.js +1 -1
  50. package/lib/module/network/overrides/matchRule.js +1 -1
  51. package/lib/module/network/overrides/overrideRulesStore.js +1 -1
  52. package/lib/module/network/sockets/findProblems.js +1 -0
  53. package/lib/module/network/sockets/foldFrames.js +1 -0
  54. package/lib/module/network/sockets/format.js +1 -0
  55. package/lib/module/network/sockets/readMessage.js +1 -0
  56. package/lib/module/network/sockets/socketMoments.js +1 -0
  57. package/lib/module/network/sockets/socketStore.js +1 -0
  58. package/lib/module/network/sockets/socketsSyncAdapter.js +1 -0
  59. package/lib/module/network/sockets/types.js +1 -0
  60. package/lib/module/network/sockets/webSocketPatch.js +1 -0
  61. package/lib/module/network/sync/networkSyncAdapter.js +1 -1
  62. package/lib/module/network/utils/networkEventStore.js +1 -1
  63. package/lib/module/network/utils/networkListener.js +4 -4
  64. package/lib/module/network/utils/startNetworkCapture.js +1 -1
  65. package/lib/module/preset.js +1 -1
  66. package/lib/typescript/index.d.ts +11 -0
  67. package/lib/typescript/index.web.d.ts +4 -0
  68. package/lib/typescript/network/components/sockets/NetworkSocketsButton.d.ts +17 -0
  69. package/lib/typescript/network/components/sockets/NetworkSocketsScreen.d.ts +19 -0
  70. package/lib/typescript/network/components/sockets/SocketFrameView.d.ts +9 -0
  71. package/lib/typescript/network/components/sockets/SocketListView.d.ts +9 -0
  72. package/lib/typescript/network/components/sockets/SocketRows.d.ts +19 -0
  73. package/lib/typescript/network/components/sockets/SocketTricksView.d.ts +23 -0
  74. package/lib/typescript/network/conditions/store.d.ts +1 -1
  75. package/lib/typescript/network/hooks/useSocketsState.d.ts +3 -0
  76. package/lib/typescript/network/overrides/overrideRulesStore.d.ts +19 -0
  77. package/lib/typescript/network/overrides/types.d.ts +14 -0
  78. package/lib/typescript/network/sockets/findProblems.d.ts +31 -0
  79. package/lib/typescript/network/sockets/foldFrames.d.ts +50 -0
  80. package/lib/typescript/network/sockets/format.d.ts +19 -0
  81. package/lib/typescript/network/sockets/readMessage.d.ts +41 -0
  82. package/lib/typescript/network/sockets/socketMoments.d.ts +24 -0
  83. package/lib/typescript/network/sockets/socketStore.d.ts +94 -0
  84. package/lib/typescript/network/sockets/socketsSyncAdapter.d.ts +66 -0
  85. package/lib/typescript/network/sockets/types.d.ts +139 -0
  86. package/lib/typescript/network/sockets/webSocketPatch.d.ts +57 -0
  87. package/lib/typescript/network/sync/networkSyncAdapter.d.ts +3 -1
  88. package/lib/typescript/network/types/index.d.ts +6 -0
  89. package/lib/typescript/network/utils/networkListener.d.ts +6 -0
  90. package/lib/web/index.mjs +58 -58
  91. package/package.json +2 -2
@@ -0,0 +1,66 @@
1
+ import type { SocketFrame, SocketsState } from "./types";
2
+ /**
3
+ * External-sync adapter for the Sockets screen, under its own `sockets` key.
4
+ *
5
+ * Its own key, not part of `network`'s snapshot: a chat app sends messages all
6
+ * day, and every message would otherwise re-send the HTTP list (and its 1.25 MB
7
+ * budget) with it. Split, a busy socket only re-sends the socket snapshot.
8
+ *
9
+ * The snapshot carries the newest SNAPSHOT_FRAMES frames with short text, for
10
+ * Desktop's list. Whole messages and the full history come from actions:
11
+ * `getFrame` for one, `query` for a filtered page (what the MCP uses).
12
+ */
13
+ export declare const SNAPSHOT_FRAMES = 300;
14
+ /** Text kept per frame in the snapshot. The rest is fetched by `getFrame`. */
15
+ export declare const SNAPSHOT_TEXT = 1000;
16
+ /** With bodies, a list still cuts each one here: 50 big messages would flood an agent. `frameId` gets one whole. */
17
+ export declare const LIST_BODY_TEXT = 4000;
18
+ export interface SocketQuery {
19
+ socketId?: string;
20
+ frameId?: string;
21
+ /** `chat.*` matches by prefix; anything else matches part of the name. */
22
+ type?: string;
23
+ direction?: "in" | "out" | "lifecycle";
24
+ /** Only frames that are part of a problem. */
25
+ problems?: boolean;
26
+ /** Only frames at or after this time (ms since epoch). */
27
+ since?: number;
28
+ limit?: number;
29
+ includeBodies?: boolean;
30
+ includePings?: boolean;
31
+ }
32
+ export declare function matchesType(type: string | undefined, pattern: string): boolean;
33
+ export declare function querySockets(state: SocketsState, q?: SocketQuery): {
34
+ connections: import("./types").SocketConnection[];
35
+ problems: import("./types").SocketProblem[];
36
+ tests: import("./types").SocketTestState;
37
+ capturingSince: number | null;
38
+ frames: SocketFrame[];
39
+ total: number;
40
+ flagged: string[];
41
+ };
42
+ export declare const socketsSyncAdapter: {
43
+ version: number;
44
+ getSnapshot: () => SocketsState;
45
+ subscribe: (onChange: () => void) => () => void;
46
+ actions: {
47
+ /** One whole frame, with its reply or request beside it. */
48
+ getFrame: (params?: unknown) => {
49
+ frame: SocketFrame;
50
+ partner: SocketFrame | null;
51
+ } | null;
52
+ /** A filtered page of frames plus every socket and problem. See SocketQuery. */
53
+ query: (params?: unknown) => {
54
+ connections: import("./types").SocketConnection[];
55
+ problems: import("./types").SocketProblem[];
56
+ tests: import("./types").SocketTestState;
57
+ capturingSince: number | null;
58
+ frames: SocketFrame[];
59
+ total: number;
60
+ flagged: string[];
61
+ };
62
+ /** inject | send | close | freeze | block | reset | clear. Says what really happened. */
63
+ act: (params?: unknown) => import("./types").SocketActionResult;
64
+ };
65
+ };
66
+ //# sourceMappingURL=socketsSyncAdapter.d.ts.map
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Socket capture types — the Sockets screen of the Network tool.
3
+ *
4
+ * One list holds everything that happened on every socket, newest first:
5
+ * messages both ways AND the open/close/error moments, so a reconnect shows up
6
+ * between the messages around it instead of on a separate screen.
7
+ */
8
+ export type SocketState = "connecting" | "open" | "closing" | "closed";
9
+ export interface SocketConnection {
10
+ /** `s1`, `s2`, ... in the order the app created them. */
11
+ id: string;
12
+ /** The URL with secret query values hidden (`?token=[hidden]`). */
13
+ url: string;
14
+ protocols?: string[];
15
+ /** Nth socket this app made to the same URL (its path, query ignored). 1 = first. */
16
+ attempt: number;
17
+ state: SocketState;
18
+ createdAt: number;
19
+ openedAt?: number;
20
+ closedAt?: number;
21
+ closeCode?: number;
22
+ closeReason?: string;
23
+ /** Buoy closed it (Drop / Kick out / offline), not the app or the server. */
24
+ closedByBuoy?: boolean;
25
+ /** Freeze is on: messages both ways are held back while it still looks open. */
26
+ frozen?: boolean;
27
+ sent: number;
28
+ received: number;
29
+ bytesSent: number;
30
+ bytesReceived: number;
31
+ /** Heartbeat messages, counted here and folded out of the list. */
32
+ pings: number;
33
+ lastMessageAt?: number;
34
+ }
35
+ export type SocketFrameKind = "message" | "open" | "close" | "error";
36
+ export interface SocketFrame {
37
+ /** `f1`, `f2`, ... unique for this app run. */
38
+ id: string;
39
+ socketId: string;
40
+ kind: SocketFrameKind;
41
+ timestamp: number;
42
+ /** Messages only: `out` = the app sent it, `in` = the app got it. */
43
+ direction?: "in" | "out";
44
+ /** The message as text, secrets hidden, cut at MAX_FRAME_CHARS. Binary shows as a short note. */
45
+ data?: string;
46
+ /** Length of the original message in bytes (or characters for text). */
47
+ size?: number;
48
+ binary?: boolean;
49
+ /** `data` was cut at MAX_FRAME_CHARS when captured: the rest is gone. */
50
+ truncated?: boolean;
51
+ /** `data` is a short preview for a list. `getFrame` has the whole text. */
52
+ dataCut?: boolean;
53
+ /** `data` is JSON. */
54
+ json?: boolean;
55
+ /** The message's name, read from `type`, `event`, `op`, `action` or `method`. */
56
+ type?: string;
57
+ /** The id that ties a request to its reply: `requestId`, `id`, `ref`, ... */
58
+ correlationId?: string;
59
+ /** A heartbeat (`ping`, `pong`, `heartbeat`, engine.io `2`/`3`). */
60
+ ping?: boolean;
61
+ /** Buoy made this message: `inject` = pushed into the app, `send` = sent to the server. */
62
+ fake?: "inject" | "send";
63
+ /** Held back by Freeze, Block or offline mode: the other side never got it. */
64
+ held?: boolean;
65
+ /** The app sent this while the socket was not open. */
66
+ sentWhileClosed?: boolean;
67
+ /** For a request: the id of its reply, and how long the reply took. */
68
+ replyId?: string;
69
+ replyMs?: number;
70
+ /** For a reply: the id of the request it answers. */
71
+ replyTo?: string;
72
+ /** close / error */
73
+ code?: number;
74
+ reason?: string;
75
+ byBuoy?: boolean;
76
+ /** close: the socket never opened (refused, bad response, no server). */
77
+ neverOpened?: boolean;
78
+ }
79
+ export type SocketProblemKind = "no-reply" | "reconnect-storm" | "auth-loop" | "cant-connect" | "two-sockets" | "sent-while-closed";
80
+ export interface SocketProblem {
81
+ kind: SocketProblemKind;
82
+ /** Plain words, ready for a row, a chip or an agent. */
83
+ message: string;
84
+ socketId?: string;
85
+ url?: string;
86
+ /** The frames that prove it. */
87
+ frameIds: string[];
88
+ at: number;
89
+ }
90
+ /** What Buoy is doing to sockets right now — every one of these is fake behavior. */
91
+ export interface SocketTestState {
92
+ /** New sockets fail at once, like a server that is down. */
93
+ blocked: boolean;
94
+ /** Network's offline mode is on, so sockets act offline too. */
95
+ offline: boolean;
96
+ /** Sockets with Freeze on. */
97
+ frozen: string[];
98
+ }
99
+ export interface SocketsState {
100
+ connections: SocketConnection[];
101
+ frames: SocketFrame[];
102
+ problems: SocketProblem[];
103
+ tests: SocketTestState;
104
+ /** When capture began. Sockets opened before this are not seen. */
105
+ capturingSince: number | null;
106
+ }
107
+ /** What the Tricks screen, Desktop and the MCP can do. */
108
+ export type SocketAction = {
109
+ action: "inject";
110
+ socketId: string;
111
+ data: string;
112
+ } | {
113
+ action: "send";
114
+ socketId: string;
115
+ data: string;
116
+ } | {
117
+ action: "close";
118
+ socketId: string;
119
+ code?: number;
120
+ reason?: string;
121
+ } | {
122
+ action: "freeze";
123
+ socketId: string;
124
+ frozen: boolean;
125
+ } | {
126
+ action: "block";
127
+ blocked: boolean;
128
+ } | {
129
+ action: "reset";
130
+ } | {
131
+ action: "clear";
132
+ };
133
+ export interface SocketActionResult {
134
+ ok: boolean;
135
+ /** What really happened, in plain words. */
136
+ message: string;
137
+ frameId?: string;
138
+ }
139
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The WebSocket wrapper behind the Sockets screen.
3
+ *
4
+ * `globalThis.WebSocket` is replaced by a subclass, so every socket the app
5
+ * makes after this runs is seen with no setup. The subclass is still a real
6
+ * WebSocket (`instanceof` holds, the constants are inherited), and it talks to
7
+ * the network through the real one.
8
+ *
9
+ * WHY THE APP'S HANDLERS ARE KEPT HERE. To push a fake message into the app,
10
+ * freeze a socket, or fake a 1006 close, Buoy has to decide what reaches the
11
+ * app's own `onmessage`/`addEventListener` code. So the wrapper keeps the
12
+ * app's handlers in its own list and registers ONE listener per event with the
13
+ * real socket. That listener records the event, then hands it to the app's
14
+ * handlers unless a test is holding it back. React Native's WebSocket and the
15
+ * browser's both deliver through those listeners, so one path covers both.
16
+ *
17
+ * Fake closes: a browser refuses `close(1006)`, and Android ignores `close()`
18
+ * before the socket opens. So Buoy gives the app the close it asked for right
19
+ * away, closes the real socket with its own code, and hides the real close
20
+ * when it comes later.
21
+ */
22
+ interface MessageFlags {
23
+ fake?: "inject" | "send";
24
+ held?: boolean;
25
+ sentWhileClosed?: boolean;
26
+ }
27
+ /** What the store learns from a socket. Implemented by socketStore. */
28
+ export interface SocketRecorder {
29
+ /** null = don't track this socket (Buoy's own, Metro's, or capture is off). */
30
+ register(url: string, protocols: string[] | undefined, control: SocketControl): string | null;
31
+ open(socketId: string): void;
32
+ message(socketId: string, direction: "in" | "out", raw: unknown, flags?: MessageFlags): string | undefined;
33
+ close(socketId: string, code: number | undefined, reason: string | undefined, byBuoy: boolean): void;
34
+ error(socketId: string): void;
35
+ /** Why new sockets fail and messages are held (block or offline), or null. */
36
+ cutOff(): string | null;
37
+ isFrozen(socketId: string): boolean;
38
+ }
39
+ /** What the store can do to one socket. */
40
+ export interface SocketControl {
41
+ /** Hand the app a message as if the server sent it. */
42
+ inject(data: string): string | undefined;
43
+ /** Send a message to the server. */
44
+ send(data: string): string | undefined;
45
+ /** Close as if the network (1006) or the server (1008, ...) did it. */
46
+ fakeClose(code: number, reason: string): void;
47
+ isOpen(): boolean;
48
+ }
49
+ /** Whether the wrapper is installed in this runtime. */
50
+ export declare function isWebSocketPatched(): boolean;
51
+ /**
52
+ * Install the wrapper once. Returns false when there is no WebSocket here or
53
+ * it is already installed.
54
+ */
55
+ export declare function installWebSocketPatch(recorder: SocketRecorder): boolean;
56
+ export {};
57
+ //# sourceMappingURL=webSocketPatch.d.ts.map
@@ -69,7 +69,7 @@ export declare const networkSyncAdapter: {
69
69
  fetch: string;
70
70
  xhr: string;
71
71
  upload: string;
72
- webSocket: boolean;
72
+ webSocket: string;
73
73
  nativeImages: boolean;
74
74
  nativeModules: boolean;
75
75
  netInfo: import("../conditions/store").ConnectionSupport;
@@ -239,11 +239,13 @@ export declare const networkSyncAdapter: {
239
239
  ok: boolean;
240
240
  count: number;
241
241
  enabled: boolean;
242
+ saved: boolean;
242
243
  error?: undefined;
243
244
  } | {
244
245
  ok: boolean;
245
246
  count: number;
246
247
  enabled: boolean;
248
+ saved: boolean;
247
249
  error?: undefined;
248
250
  }>;
249
251
  /**
@@ -40,6 +40,12 @@ export interface NetworkEvent {
40
40
  responseHeaders: Record<string, string>;
41
41
  requestData?: unknown;
42
42
  responseData?: unknown;
43
+ /** `responseData` was parsed from JSON text (so a string was a JSON string). */
44
+ responseJson?: boolean;
45
+ /** `responseData` was cut at the size cap (or left out as too large): not the real answer. */
46
+ responseTruncated?: boolean;
47
+ /** `responseData` wasn't read (still streaming, or unreadable): a placeholder. */
48
+ responseUnread?: boolean;
43
49
  responseSize?: number;
44
50
  requestSize?: number;
45
51
  timestamp: number;
@@ -27,6 +27,12 @@ export interface NetworkingEvent {
27
27
  headers?: Record<string, string>;
28
28
  body?: unknown;
29
29
  size?: number;
30
+ /** The body was parsed from JSON text (so a string body was a JSON string). */
31
+ json?: boolean;
32
+ /** The body was cut at the size cap (or left out as too large): not the real answer. */
33
+ truncated?: boolean;
34
+ /** The body wasn't read (still streaming, or unreadable): what's there is a placeholder. */
35
+ unread?: boolean;
30
36
  };
31
37
  error?: {
32
38
  message: string;