@pylonsync/sync 0.3.213 → 0.3.216

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.
@@ -62,6 +62,11 @@ export interface CreateTestEnvOptions {
62
62
  * "poll" to disable the WS-onopen reconcile race in scenarios
63
63
  * that only want to pin the in-start pipeline. */
64
64
  transport?: "websocket" | "poll" | "sse";
65
+ /** Base delay (ms) for WS reconnect backoff. The default value used
66
+ * inside the harness (`undefined` → 1000) introduces seconds of
67
+ * wall-clock waiting on every reconnect scenario; pass a small
68
+ * value when the test specifically exercises the reconnect path. */
69
+ reconnectDelay?: number;
65
70
  }
66
71
 
67
72
  export interface TestEnv {
@@ -116,6 +121,7 @@ export function createTestEnv(opts: CreateTestEnvOptions = {}): TestEnv {
116
121
  persist: false,
117
122
  storage,
118
123
  transport: opts.transport ?? "websocket",
124
+ reconnectDelay: opts.reconnectDelay,
119
125
  // Tight timings so scenarios don't have to sleep seconds. The
120
126
  // engine's reconcile debounce is also relaxed so back-to-back
121
127
  // visibility-change triggers don't get coalesced away in tests.
@@ -19,6 +19,10 @@ export interface TransportHandle {
19
19
  fetchCount: () => number;
20
20
  /** Number of WS connections opened so far. */
21
21
  wsConnectCount: () => number;
22
+ /** Close the most-recently-opened mock WS so the engine sees a
23
+ * disconnect and schedules reconnect via its backoff. Returns
24
+ * true if a socket was actually closed, false otherwise. */
25
+ closeLatestWs: () => boolean;
22
26
  /** Tear down the global stubs. */
23
27
  restore: () => void;
24
28
  }
@@ -33,6 +37,12 @@ export function installTransport(server: TestServer): TransportHandle {
33
37
  let token: string | undefined;
34
38
  let fetchCount = 0;
35
39
  let wsConnectCount = 0;
40
+ // Track open mock sockets so a test that needs to simulate a
41
+ // server-side disconnect (cluster bounce, autostop) can grab the
42
+ // latest connection and close it. The engine's reconnect loop
43
+ // builds a fresh MockWebSocket on the next attempt; each shows up
44
+ // here in order so the list maps 1:1 to actual connect attempts.
45
+ const openSockets: MockWebSocket[] = [];
36
46
 
37
47
  const originalFetch = globalThis.fetch;
38
48
  const originalWS = (globalThis as { WebSocket?: unknown }).WebSocket;
@@ -87,6 +97,7 @@ export function installTransport(server: TestServer): TransportHandle {
87
97
  super();
88
98
  this.url = url;
89
99
  wsConnectCount += 1;
100
+ openSockets.push(this);
90
101
  // The engine encodes the token as `bearer.<percent-encoded>` in
91
102
  // the WS subprotocol when one is set. Decode it so the harness
92
103
  // can route this connection to the right subscriber bucket
@@ -144,6 +155,18 @@ export function installTransport(server: TestServer): TransportHandle {
144
155
  },
145
156
  fetchCount: () => fetchCount,
146
157
  wsConnectCount: () => wsConnectCount,
158
+ closeLatestWs: () => {
159
+ // Walk back from the most recent socket to find one that's
160
+ // still open. Older closed sockets get skipped silently.
161
+ for (let i = openSockets.length - 1; i >= 0; i--) {
162
+ const s = openSockets[i];
163
+ if (s.readyState !== 3) {
164
+ s.close();
165
+ return true;
166
+ }
167
+ }
168
+ return false;
169
+ },
147
170
  restore: () => {
148
171
  globalThis.fetch = originalFetch;
149
172
  if (originalWS) {