@vxil/realtime 0.1.0 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -62,8 +62,13 @@ export interface PresenceEvent {
62
62
  type FrameListener = (frame: RealtimeFrame) => void;
63
63
  type StateListener = (state: ChannelState, detail?: {
64
64
  attempt?: number;
65
- error?: unknown;
65
+ error?: unknown; /** the server close code on a terminal close */
66
+ code?: number;
66
67
  }) => void;
68
+ /** Server close code: the end-user's auth session was revoked — terminal, the
69
+ * client never reconnects on it (a fresh subscribe() after sign-in does). The
70
+ * 24 h socket-lifetime close (4001) reconnects like any other close. */
71
+ export declare const CLOSE_SESSION_REVOKED = 4002;
67
72
  type PresenceListener = (d: PresenceEvent) => void;
68
73
  export declare class Channel {
69
74
  readonly name: string;
package/dist/index.js CHANGED
@@ -28,6 +28,10 @@
28
28
  // pass a constructor — `import WebSocket from 'ws'; new RealtimeClient({
29
29
  // ..., WebSocket })` — instead of failing with a silent `WebSocket is not
30
30
  // defined`. (The `ws` package is NOT a dependency of this package.)
31
+ /** Server close code: the end-user's auth session was revoked — terminal, the
32
+ * client never reconnects on it (a fresh subscribe() after sign-in does). The
33
+ * 24 h socket-lifetime close (4001) reconnects like any other close. */
34
+ export const CLOSE_SESSION_REVOKED = 4002;
31
35
  const DEFAULT_BASE = 'https://api.vxil.com';
32
36
  function resolveCtor(injected) {
33
37
  const WS = injected ?? globalThis.WebSocket;
@@ -293,7 +297,17 @@ export class Channel {
293
297
  clearTimeout(this.flushFallback);
294
298
  this.flushFallback = undefined;
295
299
  }
296
- this.scheduleReconnect(new Error(`websocket closed (code ${ev.code ?? 'unknown'})`));
300
+ const error = new Error(`websocket closed (code ${ev.code ?? 'unknown'})`);
301
+ if (ev.code === CLOSE_SESSION_REVOKED) {
302
+ // The end-user's auth session was revoked server-side (sign-out,
303
+ // revoke-all, erase). Reconnecting would loop forever against a mint
304
+ // that now 401s — terminal instead; subscribe() again after sign-in.
305
+ this.userClosed = true;
306
+ this.settleOpen(error);
307
+ this.setState('closed', { code: ev.code, error });
308
+ return;
309
+ }
310
+ this.scheduleReconnect(error);
297
311
  });
298
312
  // In browsers every 'error' is followed by 'close' — counting both would
299
313
  // double-step the backoff, so only 'close' drives the state machine.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxil/realtime",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,