@avasapp/agent-bridge 0.4.2 → 0.6.0

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 (65) hide show
  1. package/README.md +36 -14
  2. package/dist/adapters/ably.cjs +79 -3
  3. package/dist/adapters/ably.d.cts +2 -1
  4. package/dist/adapters/async-storage.cjs +158 -0
  5. package/dist/adapters/async-storage.d.cts +14 -0
  6. package/dist/adapters/device.cjs +1110 -0
  7. package/dist/adapters/device.d.cts +49 -0
  8. package/dist/adapters/expo-router.cjs +112 -6
  9. package/dist/adapters/expo-router.d.cts +1 -1
  10. package/dist/adapters/jotai.cjs +266 -0
  11. package/dist/adapters/jotai.d.cts +19 -0
  12. package/dist/adapters/react-native-mmkv.cjs +80 -0
  13. package/dist/adapters/react-native-mmkv.d.cts +3 -1
  14. package/dist/adapters/react-native-webview.d.cts +1 -1
  15. package/dist/adapters/react-navigation.cjs +293 -0
  16. package/dist/adapters/react-navigation.d.cts +55 -0
  17. package/dist/adapters/redux.cjs +322 -0
  18. package/dist/adapters/redux.d.cts +28 -0
  19. package/dist/adapters/secure-store.cjs +169 -0
  20. package/dist/adapters/secure-store.d.cts +28 -0
  21. package/dist/adapters/socket-io.cjs +77 -3
  22. package/dist/adapters/socket-io.d.cts +2 -1
  23. package/dist/adapters/tanstack-query.cjs +3 -0
  24. package/dist/adapters/tanstack-query.d.cts +13 -4
  25. package/dist/adapters/zustand.cjs +193 -22
  26. package/dist/adapters/zustand.d.cts +11 -15
  27. package/dist/{chunk-TA2OLPPT.js → chunk-Y6QFU5ON.js} +477 -165
  28. package/dist/cli.js +2370 -103
  29. package/dist/client/index.cjs +441 -136
  30. package/dist/client/index.d.ts +67 -4
  31. package/dist/client/index.js +5 -3
  32. package/dist/expo/index.d.cts +1 -1
  33. package/dist/network/index.cjs +320 -73
  34. package/dist/network/index.d.cts +18 -3
  35. package/dist/noop/async-storage.cjs +26 -0
  36. package/dist/noop/device.cjs +26 -0
  37. package/dist/noop/jotai.cjs +26 -0
  38. package/dist/noop/react-navigation.cjs +26 -0
  39. package/dist/noop/realtime.cjs +6 -1
  40. package/dist/noop/redux.cjs +28 -0
  41. package/dist/noop/secure-store.cjs +26 -0
  42. package/dist/realtime/index.cjs +71 -4
  43. package/dist/realtime/index.d.cts +21 -2
  44. package/dist/runtime/index.cjs +838 -128
  45. package/dist/runtime/index.d.cts +4 -2
  46. package/dist/store-common-j0cHHvBr.d.cts +23 -0
  47. package/dist/{types-BmpykP1P.d.cts → types-qlwdcGjt.d.cts} +22 -0
  48. package/entries/async-storage.cjs +9 -0
  49. package/entries/device.cjs +9 -0
  50. package/entries/jotai.cjs +9 -0
  51. package/entries/react-navigation.cjs +9 -0
  52. package/entries/redux.cjs +9 -0
  53. package/entries/secure-store.cjs +9 -0
  54. package/package.json +34 -2
  55. package/skills/agent-bridge/SKILL.md +70 -22
  56. package/skills/agent-bridge/references/device.md +21 -0
  57. package/skills/agent-bridge/references/flows.md +19 -8
  58. package/skills/agent-bridge/references/large-data.md +6 -6
  59. package/skills/agent-bridge/references/network.md +25 -7
  60. package/skills/agent-bridge/references/realtime.md +5 -5
  61. package/skills/agent-bridge/references/restore.md +25 -7
  62. package/skills/agent-bridge/references/screen.md +25 -11
  63. package/skills/agent-bridge/references/state.md +31 -11
  64. package/skills/agent-bridge/references/webview.md +9 -9
  65. package/skills/agent-bridge/references/writing-scenarios.md +3 -3
@@ -1,14 +1,24 @@
1
- import { T as Tools } from '../types-BmpykP1P.cjs';
1
+ import { T as Tools } from '../types-qlwdcGjt.cjs';
2
2
 
3
- /** Which requests a mock answers. A bare string is a URL substring. */
3
+ /**
4
+ * Which requests a mock answers. A bare string is a URL substring. In the
5
+ * object form every key given must match, and at least one of `url`, `path`,
6
+ * `body` or `graphql` is needed.
7
+ */
4
8
  type MockMatch = string | {
5
9
  /** A substring of the URL, a RegExp, or `{ regex }` from JSON. */
6
- url: string | RegExp | {
10
+ url?: string | RegExp | {
7
11
  regex: string;
8
12
  flags?: string;
9
13
  };
14
+ /** The whole path of the URL on any host, query ignored: "/orders/:id" (one segment) or "/files/*" (the rest). "/orders" does not match "/orders/5/items". */
15
+ path?: string;
10
16
  /** Any method when left out. */
11
17
  method?: string;
18
+ /** A JSON request body must contain this: objects match key by key, arrays match in length and position, other values are equal. */
19
+ body?: Record<string, unknown> | unknown[];
20
+ /** The GraphQL operationName, from the JSON body or the `?operationName=` query. */
21
+ graphql?: string;
12
22
  };
13
23
  type MockResponse = {
14
24
  /** Defaults to 200. */
@@ -59,6 +69,9 @@ type LogEntry = {
59
69
  pending?: boolean;
60
70
  requestBody?: string;
61
71
  responseBody?: string;
72
+ /** From net.entry only; names are lower case. Credential values are cut unless `{ full: true }`. */
73
+ requestHeaders?: Record<string, string>;
74
+ responseHeaders?: Record<string, string>;
62
75
  /** From net.entry: a body shown is only a preview because the whole one was too large or is gone. */
63
76
  truncated?: boolean;
64
77
  error?: string;
@@ -128,6 +141,8 @@ declare function strictNetwork(options?: StrictOptions): () => void;
128
141
  type NetworkToolsOptions = {
129
142
  /** Extra URLs never to log or mock: substrings or RegExps. */
130
143
  skip?: Array<string | RegExp>;
144
+ /** How many requests `net.log` keeps. Default 100. */
145
+ logSize?: number;
131
146
  };
132
147
  /** Read the request log and mock responses: `net.*`. */
133
148
  declare function networkTools(options?: NetworkToolsOptions): Tools;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/noop/async-storage.ts
21
+ var async_storage_exports = {};
22
+ __export(async_storage_exports, {
23
+ asyncStorageTools: () => asyncStorageTools
24
+ });
25
+ module.exports = __toCommonJS(async_storage_exports);
26
+ var asyncStorageTools = () => ({});
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/noop/device.ts
21
+ var device_exports = {};
22
+ __export(device_exports, {
23
+ deviceTools: () => deviceTools
24
+ });
25
+ module.exports = __toCommonJS(device_exports);
26
+ var deviceTools = () => ({});
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/noop/jotai.ts
21
+ var jotai_exports = {};
22
+ __export(jotai_exports, {
23
+ jotaiTools: () => jotaiTools
24
+ });
25
+ module.exports = __toCommonJS(jotai_exports);
26
+ var jotaiTools = () => ({});
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/noop/react-navigation.ts
21
+ var react_navigation_exports = {};
22
+ __export(react_navigation_exports, {
23
+ navTools: () => navTools
24
+ });
25
+ module.exports = __toCommonJS(react_navigation_exports);
26
+ var navTools = () => ({});
@@ -23,7 +23,8 @@ __export(realtime_exports, {
23
23
  createRealtimeTap: () => createRealtimeTap,
24
24
  fakeableConnection: () => fakeableConnection,
25
25
  realtimeAdapter: () => realtimeAdapter,
26
- tapListeners: () => tapListeners
26
+ tapListeners: () => tapListeners,
27
+ tapOutgoing: () => tapOutgoing
27
28
  });
28
29
  module.exports = __toCommonJS(realtime_exports);
29
30
  var createRealtimeTap = () => ({
@@ -32,9 +33,13 @@ var createRealtimeTap = () => ({
32
33
  unsubscribe: () => {
33
34
  }
34
35
  }),
36
+ sent: () => {
37
+ },
35
38
  tools: {}
36
39
  });
37
40
  var tapListeners = () => {
38
41
  };
42
+ var tapOutgoing = () => {
43
+ };
39
44
  var fakeableConnection = () => void 0;
40
45
  var realtimeAdapter = () => () => ({});
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/noop/redux.ts
21
+ var redux_exports = {};
22
+ __export(redux_exports, {
23
+ bridgeReducer: () => bridgeReducer,
24
+ reduxTools: () => reduxTools
25
+ });
26
+ module.exports = __toCommonJS(redux_exports);
27
+ var reduxTools = () => ({});
28
+ var bridgeReducer = (reducer) => reducer;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/noop/secure-store.ts
21
+ var secure_store_exports = {};
22
+ __export(secure_store_exports, {
23
+ secureStoreTools: () => secureStoreTools
24
+ });
25
+ module.exports = __toCommonJS(secure_store_exports);
26
+ var secureStoreTools = () => ({});
@@ -23,7 +23,8 @@ __export(realtime_exports, {
23
23
  createRealtimeTap: () => createRealtimeTap,
24
24
  fakeableConnection: () => fakeableConnection,
25
25
  realtimeAdapter: () => realtimeAdapter,
26
- tapListeners: () => tapListeners
26
+ tapListeners: () => tapListeners,
27
+ tapOutgoing: () => tapOutgoing
27
28
  });
28
29
  module.exports = __toCommonJS(realtime_exports);
29
30
 
@@ -75,6 +76,21 @@ function tapListeners(tap, target, options) {
75
76
  };
76
77
  }
77
78
  }
79
+ function tapOutgoing(tap, target, options) {
80
+ const methods = target;
81
+ for (const name of list(options.methods)) {
82
+ const send = methods[name];
83
+ if (typeof send !== "function") continue;
84
+ methods[name] = function(...args) {
85
+ try {
86
+ const channel = options.skip?.(this) ? void 0 : options.channel(args);
87
+ if (channel !== void 0) tap.sent(channel, options.describe(args));
88
+ } catch {
89
+ }
90
+ return send.apply(this, args);
91
+ };
92
+ }
93
+ }
78
94
  function fakeableConnection(target, options) {
79
95
  const methods = target;
80
96
  const events = methods?.[options.events];
@@ -119,6 +135,46 @@ function realtimeAdapter(install) {
119
135
  };
120
136
  }
121
137
 
138
+ // src/network/headers.ts
139
+ var SECRET = /auth|cookie|token|secret|session|password|passwd|signature|api-?key|credential|jwt/i;
140
+
141
+ // src/realtime/snapshot.ts
142
+ var MAX_STRING = 2e3;
143
+ var MAX_ITEMS = 50;
144
+ var MAX_DEPTH = 5;
145
+ var isPlain = (v) => {
146
+ const proto = Object.getPrototypeOf(v);
147
+ return proto === Object.prototype || proto === null;
148
+ };
149
+ function snapshot(value, depth = 0) {
150
+ if (typeof value === "string")
151
+ return value.length > MAX_STRING ? `${value.slice(0, MAX_STRING)}\u2026 (+${value.length - MAX_STRING} chars)` : value;
152
+ if (typeof value === "function") return "[function]";
153
+ if (!value || typeof value !== "object") return value;
154
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer)
155
+ return `[${value.constructor.name} ${value.byteLength} bytes]`;
156
+ if (depth >= MAX_DEPTH) return "[\u2026]";
157
+ if (Array.isArray(value)) {
158
+ const items = value.slice(0, MAX_ITEMS).map((v) => snapshot(v, depth + 1));
159
+ if (value.length > MAX_ITEMS) items.push(`\u2026 (+${value.length - MAX_ITEMS} items)`);
160
+ return items;
161
+ }
162
+ if (value instanceof Date) return value.toISOString();
163
+ if (!isPlain(value)) return `[${value.constructor?.name ?? "object"}]`;
164
+ const out = {};
165
+ for (const key of Object.keys(value).slice(0, MAX_ITEMS))
166
+ out[key] = snapshot(value[key], depth + 1);
167
+ return out;
168
+ }
169
+ function redact(value, depth = 0) {
170
+ if (!value || typeof value !== "object" || depth >= MAX_DEPTH + 1) return value;
171
+ if (Array.isArray(value)) return value.map((v) => redact(v, depth + 1));
172
+ const out = {};
173
+ for (const [key, v] of Object.entries(value))
174
+ out[key] = SECRET.test(key) ? "[redacted]" : redact(v, depth + 1);
175
+ return out;
176
+ }
177
+
122
178
  // src/realtime/tap.ts
123
179
  var LOG_SIZE = 50;
124
180
  var ALL = "*";
@@ -162,6 +218,17 @@ function createRealtimeTap(options = {}) {
162
218
  }
163
219
  if (!dropped) entry.deliver(message, ...rest);
164
220
  }
221
+ const sent = (channel, summary) => {
222
+ log.push({
223
+ at: (/* @__PURE__ */ new Date()).toISOString(),
224
+ channel,
225
+ ...summary,
226
+ ..."data" in summary && { data: snapshot(summary.data) },
227
+ injected: false,
228
+ sent: true
229
+ });
230
+ if (log.length > LOG_SIZE) log.splice(0, log.length - LOG_SIZE);
231
+ };
165
232
  const wrap = (channel, listener, wrapOptions = {}) => {
166
233
  const entry = {
167
234
  deliver: listener,
@@ -211,11 +278,11 @@ function createRealtimeTap(options = {}) {
211
278
  }))
212
279
  },
213
280
  [`${ns}.log`]: {
214
- description: `Recent messages, real and injected, newest first (last ${LOG_SIZE}). Filter: { channel?, event?, limit? }; clear: true empties the log after reading.`,
281
+ description: `Recent messages, real, injected, and ones the app sent (sent: true) (socket.emit, Ably publish), newest first (last ${LOG_SIZE}). Filter: { channel?, event?, limit?, full? }; clear: true empties the log after reading. Sent messages are copied and cut, and keys like token, password or authorization show [redacted] unless full: true.`,
215
282
  run: (filter = {}) => {
216
283
  const entries = log.filter(
217
284
  (e) => (!filter.channel || e.channel === filter.channel) && (!filter.event || e.event === filter.event)
218
- ).reverse().slice(0, filter.limit ?? 20);
285
+ ).reverse().slice(0, filter.limit ?? 20).map((e) => e.sent && !filter.full && "data" in e ? { ...e, data: redact(e.data) } : e);
219
286
  if (filter.clear) log.length = 0;
220
287
  return entries;
221
288
  }
@@ -276,5 +343,5 @@ function createRealtimeTap(options = {}) {
276
343
  return { state: faked ?? connection.state(), real: connection.state(), faked: faked !== null };
277
344
  }
278
345
  };
279
- return { wrap, tools };
346
+ return { wrap, sent, tools };
280
347
  }
@@ -1,4 +1,4 @@
1
- import { T as Tools } from '../types-BmpykP1P.cjs';
1
+ import { T as Tools } from '../types-qlwdcGjt.cjs';
2
2
 
3
3
  /** How a message shows up in `realtime.log`. */
4
4
  type MessageSummary = {
@@ -58,6 +58,8 @@ type RealtimeTap<M> = {
58
58
  listener: (message: M, ...rest: unknown[]) => void;
59
59
  unsubscribe: () => void;
60
60
  };
61
+ /** Logs a message the app sent, so an agent can check "did the app send X". */
62
+ sent: (channel: string, summary: MessageSummary) => void;
61
63
  /** `realtime.*`, or `<namespace>.*`. */
62
64
  tools: Tools;
63
65
  };
@@ -67,6 +69,8 @@ type RealtimeLogEntry = MessageSummary & {
67
69
  injected: boolean;
68
70
  /** Why the app didn't get it. */
69
71
  dropped?: 'muted' | 'connection';
72
+ /** True for a message the app sent (`socket.emit`, an Ably `publish`), not one it received. */
73
+ sent?: true;
70
74
  };
71
75
  /**
72
76
  * Lets the agent see, fake and drop realtime messages, whatever library
@@ -98,6 +102,21 @@ type TapListenersOptions<M> = {
98
102
  * Removing works in every usual form: all, by key, by listener, or both.
99
103
  */
100
104
  declare function tapListeners<M>(tap: RealtimeTap<M>, target: object, options: TapListenersOptions<M>): void;
105
+ type TapOutgoingOptions = {
106
+ /** Methods that send, e.g. "emit" or "publish". */
107
+ methods: string | string[];
108
+ /** The channel a call is for, from its arguments. Return undefined to leave the call unlogged. */
109
+ channel: (args: unknown[]) => string | undefined;
110
+ /** What to log for the call. */
111
+ describe: (args: unknown[]) => MessageSummary;
112
+ /** True for a call that repeats one already logged, e.g. socket.io re-sending from its retry queue. */
113
+ skip?: (target: object) => boolean;
114
+ };
115
+ /**
116
+ * Logs what the app sends through `target`'s methods in `realtime.log`
117
+ * (`sent: true`). The call itself always goes through untouched.
118
+ */
119
+ declare function tapOutgoing(tap: Pick<RealtimeTap<never>, 'sent'>, target: object, options: TapOutgoingOptions): void;
101
120
  type FakeableConnectionOptions = {
102
121
  /** The property holding the state, e.g. "state" or "connected". */
103
122
  property: string;
@@ -137,4 +156,4 @@ declare function fakeableConnection(target: object | undefined, options: Fakeabl
137
156
  */
138
157
  declare function realtimeAdapter<C extends object, O extends object>(install: (client: C, options: O) => Pick<RealtimeTap<unknown>, 'tools'>): (client: C, options?: O) => Tools;
139
158
 
140
- export { type FakeableConnectionOptions, type MessageSummary, type RealtimeConnection, type RealtimeLogEntry, type RealtimeTap, type RealtimeTapOptions, type TapListenersOptions, type WrapOptions, createRealtimeTap, fakeableConnection, realtimeAdapter, tapListeners };
159
+ export { type FakeableConnectionOptions, type MessageSummary, type RealtimeConnection, type RealtimeLogEntry, type RealtimeTap, type RealtimeTapOptions, type TapListenersOptions, type TapOutgoingOptions, type WrapOptions, createRealtimeTap, fakeableConnection, realtimeAdapter, tapListeners, tapOutgoing };