@tonytomo/gosocket-client 0.0.0-stage → 1.0.1

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.
@@ -0,0 +1,880 @@
1
+ /**
2
+ * Clock abstraction for deterministic time testing.
3
+ *
4
+ * NOTE: This is the ONLY file in src/ permitted to invoke the platform's
5
+ * global setTimeout / clearTimeout primitives. All SDK timers must be
6
+ * scheduled via a Clock instance.
7
+ */
8
+ interface Timer {
9
+ stop(): void;
10
+ }
11
+ interface Clock {
12
+ now(): number;
13
+ setTimeout(fn: () => void, ms: number): Timer;
14
+ clearTimeout(t: Timer): void;
15
+ }
16
+ declare class RealClock implements Clock {
17
+ now(): number;
18
+ setTimeout(fn: () => void, ms: number): Timer;
19
+ clearTimeout(t: Timer): void;
20
+ }
21
+
22
+ /**
23
+ * Wire protocol types mirroring PROTOCOL.md and Go client/types.go.
24
+ */
25
+ type ErrorCode = 'UNAUTHORIZED' | 'FORBIDDEN_SCOPE' | 'NOT_ROOM_OWNER' | 'BAD_REQUEST' | 'ROOM_NOT_FOUND' | 'ROOM_ALREADY_EXISTS' | 'ROOM_FULL' | 'INVALID_PASSCODE' | 'PASSCODE_RATE_LIMITED' | 'MAX_ROOMS_REACHED' | 'BINARY_NOT_ALLOWED' | 'CHANNEL_NOT_RELIABLE' | 'CHANNEL_NOT_FOUND' | 'RESERVED_CHANNEL_NAME' | 'CHANNEL_READ_ONLY' | 'RATE_LIMITED' | 'INTERNAL_ERROR';
26
+ interface ChannelConfig {
27
+ name: string;
28
+ reliable: boolean;
29
+ max_rate: number;
30
+ }
31
+ interface ChannelConfigInput {
32
+ reliable?: boolean;
33
+ max_rate?: number;
34
+ }
35
+ interface RoomSummary {
36
+ name: string;
37
+ members: number;
38
+ protected: boolean;
39
+ kind?: string;
40
+ channels?: string[];
41
+ channel_configs?: Record<string, ChannelConfig>;
42
+ max_members?: number;
43
+ created_at: number;
44
+ metadata?: unknown;
45
+ }
46
+ type BinaryChannelMap$1 = Record<string, number>;
47
+ interface CapabilityLimits {
48
+ max_rooms: number;
49
+ max_members_per_room: number | null;
50
+ max_message_bytes: number;
51
+ max_rooms_per_key: number | null;
52
+ max_channels_per_room: number | null;
53
+ max_metadata_bytes: number | null;
54
+ list_rooms_max_limit: number | null;
55
+ list_rooms_default_limit: number | null;
56
+ }
57
+ interface ListRoomsFeatures {
58
+ pagination?: boolean;
59
+ detail_levels?: string[];
60
+ filters?: string[];
61
+ }
62
+ interface CapabilityFeatures {
63
+ binary_frames?: boolean;
64
+ room_kinds?: string[];
65
+ list_rooms?: ListRoomsFeatures;
66
+ }
67
+ interface Capabilities {
68
+ limits?: CapabilityLimits;
69
+ features?: CapabilityFeatures;
70
+ }
71
+ interface CreateRoomRequest {
72
+ type?: 'create_room';
73
+ room: string;
74
+ kind?: 'chat' | 'game' | 'custom' | string;
75
+ passcode?: string;
76
+ max_members?: number;
77
+ ephemeral?: boolean;
78
+ channels?: Record<string, ChannelConfigInput>;
79
+ metadata?: unknown;
80
+ }
81
+ interface JoinRoomRequest {
82
+ type?: 'join_room';
83
+ room: string;
84
+ passcode?: string;
85
+ binary_channels?: BinaryChannelMap$1;
86
+ }
87
+ interface LeaveRoomRequest {
88
+ type?: 'leave_room';
89
+ room: string;
90
+ }
91
+ interface DeleteRoomRequest {
92
+ type?: 'delete_room';
93
+ room: string;
94
+ }
95
+ interface ListRoomsRequest {
96
+ type?: 'list_rooms';
97
+ limit?: number;
98
+ cursor?: string;
99
+ filters?: unknown;
100
+ detail?: string;
101
+ }
102
+ interface PublishRequest$1 {
103
+ type?: 'publish';
104
+ room: string;
105
+ channel?: string;
106
+ reliable?: boolean;
107
+ payload?: unknown;
108
+ include_sender?: boolean;
109
+ }
110
+ interface PingRequest {
111
+ type?: 'ping';
112
+ }
113
+ type ClientFrame = CreateRoomRequest | JoinRoomRequest | LeaveRoomRequest | DeleteRoomRequest | ListRoomsRequest | PublishRequest$1 | PingRequest;
114
+ interface WelcomeFrame {
115
+ type: 'welcome';
116
+ client_id: string;
117
+ label: string;
118
+ server_version: string;
119
+ capabilities?: Capabilities;
120
+ }
121
+ interface RoomCreatedFrame {
122
+ type: 'room_created';
123
+ room: string;
124
+ channels: string[];
125
+ }
126
+ interface RoomJoinedFrame {
127
+ type: 'room_joined';
128
+ room: string;
129
+ channels: string[];
130
+ members: number;
131
+ }
132
+ interface RoomLeftFrame {
133
+ type: 'room_left';
134
+ room: string;
135
+ }
136
+ interface RoomListFrame {
137
+ type: 'room_list';
138
+ rooms: RoomSummary[];
139
+ next_cursor?: string;
140
+ truncated?: boolean;
141
+ filters_applied?: unknown;
142
+ detail?: string;
143
+ }
144
+ interface MessageFrame {
145
+ type: 'message';
146
+ room: string;
147
+ channel: string;
148
+ from: string;
149
+ seq: number;
150
+ ts: number;
151
+ payload: unknown;
152
+ }
153
+ interface ErrorFrame {
154
+ type: 'error';
155
+ code: ErrorCode;
156
+ message: string;
157
+ channel?: string;
158
+ retry_after_ms?: number;
159
+ room?: string;
160
+ }
161
+ interface PongFrame {
162
+ type: 'pong';
163
+ }
164
+ type ServerFrame = WelcomeFrame | RoomCreatedFrame | RoomJoinedFrame | RoomLeftFrame | RoomListFrame | MessageFrame | ErrorFrame | PongFrame;
165
+ declare function isErrorFrame(x: unknown): x is ErrorFrame;
166
+ declare function isMessageFrame(x: unknown): x is MessageFrame;
167
+ declare function isWelcomeFrame(x: unknown): x is WelcomeFrame;
168
+
169
+ interface ChannelPolicy {
170
+ reliable: boolean;
171
+ maxRate: number;
172
+ coalesce: boolean;
173
+ coalesceDriver?: 'timer' | 'raf';
174
+ merge?: (prev: unknown, next: unknown) => {
175
+ value: unknown;
176
+ skip: boolean;
177
+ };
178
+ }
179
+ interface PolicyProvider {
180
+ channelPolicy(room: string, channel: string): ChannelPolicy | undefined;
181
+ }
182
+ type RoomKind = 'chat' | 'game' | 'custom';
183
+ declare function presetsFor(kind: RoomKind, overrides?: Record<string, Partial<ChannelPolicy>>): Record<string, ChannelPolicy>;
184
+ declare function resolvePolicy(room: string, channel: string, provider: PolicyProvider | undefined, overrides: Record<string, ChannelPolicy>): ChannelPolicy;
185
+
186
+ type BinaryChannelMap = Readonly<Record<string, number>>;
187
+ declare class BinaryMapBuilder {
188
+ private readonly byChannel;
189
+ private readonly byId;
190
+ set(channel: string, id: number): this;
191
+ autoSet(channel: string): this;
192
+ build(): BinaryChannelMap;
193
+ }
194
+ declare function validateBinaryMap(map: BinaryChannelMap): void;
195
+
196
+ type ErrorAction = 'ignore' | 'drop_intent' | 'retry_backoff' | 'reconnect' | 'fatal' | 'app_prompt';
197
+ interface ErrorClassification {
198
+ action: ErrorAction;
199
+ retryAfterMs?: number;
200
+ }
201
+ interface ErrorPolicyConfig {
202
+ overrides?: Partial<Record<ErrorCode, ErrorClassification>>;
203
+ }
204
+ /**
205
+ * Pure function that maps an ErrorCode and optional ErrorFrame to the SDK's
206
+ * recommended recovery action based on PROTOCOL.md §4.7.
207
+ */
208
+ declare function classifyError(code: ErrorCode, frame?: Partial<Pick<ErrorFrame, 'message' | 'channel' | 'retry_after_ms'>>, overrides?: ErrorPolicyConfig['overrides']): ErrorClassification;
209
+
210
+ interface RttStats {
211
+ last: number;
212
+ min: number;
213
+ max: number;
214
+ mean: number;
215
+ samples: number;
216
+ }
217
+ interface RttEvent$1 {
218
+ sample: number;
219
+ source: 'heartbeat' | 'on_demand';
220
+ stats: RttStats;
221
+ }
222
+ declare class RttTracker {
223
+ private stats;
224
+ getStats(): RttStats | undefined;
225
+ recordSample(sampleMs: number): RttStats;
226
+ reset(): void;
227
+ }
228
+
229
+ type State = 'idle' | 'connecting' | 'awaiting_welcome' | 'ready' | 'reconnecting' | 'closed';
230
+ interface StateChangeEvent {
231
+ from: State;
232
+ to: State;
233
+ }
234
+ interface ConnectedEvent {
235
+ welcome: WelcomeFrame;
236
+ }
237
+ interface DisconnectedEvent {
238
+ code: number;
239
+ reason: string;
240
+ wasClean: boolean;
241
+ }
242
+ interface ReconnectingEvent {
243
+ attempt: number;
244
+ delayMs: number;
245
+ }
246
+ interface ErrorEvent {
247
+ error: Error;
248
+ phase: 'connect' | 'runtime';
249
+ }
250
+ interface ErrorClassifiedEvent {
251
+ code: ErrorCode;
252
+ message: string;
253
+ room?: string;
254
+ channel?: string;
255
+ action: ErrorAction;
256
+ retryAfterMs?: number;
257
+ rawFrame?: ErrorFrame;
258
+ }
259
+ interface FatalEvent {
260
+ code: 'AUTH_FAILED' | 'POLICY_VIOLATION' | 'CLOSED';
261
+ message: string;
262
+ }
263
+ interface HeartbeatTimeoutEvent {
264
+ elapsedMs: number;
265
+ }
266
+ interface RttEvent {
267
+ sample: number;
268
+ source: 'heartbeat' | 'on_demand';
269
+ stats: RttStats;
270
+ }
271
+ interface SessionRestoredEvent {
272
+ restored: string[];
273
+ failed: Array<{
274
+ room: string;
275
+ code: ErrorCode;
276
+ }>;
277
+ }
278
+ interface IntentFailedEvent {
279
+ room: string;
280
+ code: ErrorCode;
281
+ }
282
+ interface CapabilitiesChangedEvent {
283
+ previous?: Capabilities;
284
+ current: Capabilities;
285
+ previousVersion?: string;
286
+ currentVersion?: string;
287
+ }
288
+ interface RateLimitedEvent {
289
+ source: 'local' | 'server';
290
+ room: string;
291
+ channel: string;
292
+ retryAfterMs: number;
293
+ }
294
+ interface ReliableOverflowEvent {
295
+ room: string;
296
+ channel: string;
297
+ depth: number;
298
+ action: 'dropped' | 'closed';
299
+ }
300
+ interface UnreliableDroppedEvent {
301
+ room: string;
302
+ channel: string;
303
+ depth: number;
304
+ }
305
+ interface CoalescedEvent {
306
+ room: string;
307
+ channel: string;
308
+ merged: boolean;
309
+ skipped: boolean;
310
+ }
311
+ interface QueuesDiscardedEvent {
312
+ reliable: number;
313
+ unreliable: number;
314
+ coalesced: number;
315
+ }
316
+ interface BackpressureEvent {
317
+ state: 'high' | 'low';
318
+ bufferedAmount: number;
319
+ }
320
+ interface PolicyAppliedEvent {
321
+ room: string;
322
+ channel: string;
323
+ policy: ChannelPolicy;
324
+ }
325
+ interface BinaryMessageEvent {
326
+ room: string;
327
+ channel: string;
328
+ payload: Uint8Array;
329
+ }
330
+ interface BinaryUnknownChannelEvent {
331
+ id: number;
332
+ }
333
+ interface BinaryIdCollisionEvent {
334
+ id: number;
335
+ existing: string[];
336
+ rejected: string[];
337
+ }
338
+ interface BinaryMappingChangedEvent {
339
+ room: string;
340
+ map: BinaryChannelMap;
341
+ }
342
+ interface PresenceJoinEvent {
343
+ room: string;
344
+ who: string;
345
+ }
346
+ interface PresenceLeaveEvent {
347
+ room: string;
348
+ who: string;
349
+ }
350
+ interface PresenceInvalidatedEvent {
351
+ room: string;
352
+ reason: string;
353
+ }
354
+ interface RoomDeletedEvent {
355
+ room: string;
356
+ who: string;
357
+ }
358
+ interface SequenceGapEvent {
359
+ room: string;
360
+ channel: string;
361
+ prev: number;
362
+ current: number;
363
+ missed: number;
364
+ reliable: boolean;
365
+ }
366
+ interface ProtocolViolationEvent {
367
+ room: string;
368
+ reason: string;
369
+ }
370
+ interface EventMap {
371
+ stateChange: StateChangeEvent;
372
+ connected: ConnectedEvent;
373
+ disconnected: DisconnectedEvent;
374
+ reconnecting: ReconnectingEvent;
375
+ error: ErrorEvent;
376
+ errorClassified: ErrorClassifiedEvent;
377
+ fatal: FatalEvent;
378
+ heartbeatTimeout: HeartbeatTimeoutEvent;
379
+ rtt: RttEvent;
380
+ sessionRestored: SessionRestoredEvent;
381
+ intentFailed: IntentFailedEvent;
382
+ capabilitiesChanged: CapabilitiesChangedEvent;
383
+ message: MessageFrame;
384
+ rateLimited: RateLimitedEvent;
385
+ reliableOverflow: ReliableOverflowEvent;
386
+ unreliableDropped: UnreliableDroppedEvent;
387
+ coalesced: CoalescedEvent;
388
+ queuesDiscarded: QueuesDiscardedEvent;
389
+ backpressure: BackpressureEvent;
390
+ policyApplied: PolicyAppliedEvent;
391
+ binaryMessage: BinaryMessageEvent;
392
+ binaryUnknownChannel: BinaryUnknownChannelEvent;
393
+ binaryIdCollision: BinaryIdCollisionEvent;
394
+ binaryMappingChanged: BinaryMappingChangedEvent;
395
+ presenceJoin: PresenceJoinEvent;
396
+ presenceLeave: PresenceLeaveEvent;
397
+ presenceInvalidated: PresenceInvalidatedEvent;
398
+ roomDeleted: RoomDeletedEvent;
399
+ sequenceGap: SequenceGapEvent;
400
+ protocolViolation: ProtocolViolationEvent;
401
+ }
402
+ type EventName = keyof EventMap;
403
+ type EventPayload<E extends EventName> = EventMap[E];
404
+
405
+ interface HeartbeatConfig {
406
+ enabled?: boolean;
407
+ intervalMs?: number;
408
+ timeoutMs?: number;
409
+ trackRtt?: boolean;
410
+ }
411
+
412
+ /**
413
+ * Structured logger interface and redaction utilities.
414
+ */
415
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
416
+ type Logger = (level: LogLevel, msg: string, fields?: Record<string, unknown>) => void;
417
+ declare function redactUrl(rawUrl: string): string;
418
+ declare function redactString(str: string, secrets: Iterable<string>): string;
419
+ declare function redactValue(value: unknown, secrets: Iterable<string>): unknown;
420
+
421
+ /**
422
+ * Reconnection backoff curves and jitter algorithms.
423
+ */
424
+ type JitterMode = 'full' | 'equal' | 'none';
425
+ interface ReconnectConfig {
426
+ baseDelayMs?: number;
427
+ maxDelayMs?: number;
428
+ maxAttempts?: number;
429
+ jitter?: JitterMode;
430
+ shouldReconnect?: (ctx: {
431
+ closeCode: number;
432
+ firstConnect: boolean;
433
+ }) => boolean;
434
+ }
435
+ declare function computeReconnectDelay(attempt: number, config?: {
436
+ baseDelayMs?: number;
437
+ maxDelayMs?: number;
438
+ jitter?: JitterMode;
439
+ random?: () => number;
440
+ }): number;
441
+
442
+ interface RoomIntent {
443
+ room: string;
444
+ passcode: string;
445
+ binaryChannels?: BinaryChannelMap$1;
446
+ }
447
+ type RoomFullPolicy = 'drop' | 'retry';
448
+ interface RestoreConfig {
449
+ roomFullPolicy?: RoomFullPolicy;
450
+ restorePerRoomTimeoutMs?: number;
451
+ }
452
+ interface FailedIntent {
453
+ room: string;
454
+ code: ErrorCode;
455
+ }
456
+
457
+ interface Transport {
458
+ connect(url: string): Promise<void>;
459
+ send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
460
+ close(code?: number, reason?: string): void;
461
+ readonly readyState: number;
462
+ bufferedAmount(): number;
463
+ onopen: (() => void) | null;
464
+ onmessage: (ev: {
465
+ data: unknown;
466
+ }) => void;
467
+ onclose: (ev: {
468
+ code: number;
469
+ reason: string;
470
+ wasClean: boolean;
471
+ }) => void;
472
+ onerror: (ev: unknown) => void;
473
+ }
474
+ declare class BrowserWebSocketTransport implements Transport {
475
+ private ws;
476
+ onopen: (() => void) | null;
477
+ onmessage: (ev: {
478
+ data: unknown;
479
+ }) => void;
480
+ onclose: (ev: {
481
+ code: number;
482
+ reason: string;
483
+ wasClean: boolean;
484
+ }) => void;
485
+ onerror: (ev: unknown) => void;
486
+ bufferedAmount(): number;
487
+ get readyState(): number;
488
+ connect(url: string): Promise<void>;
489
+ private cleanupPreOpen;
490
+ send(data: string | ArrayBufferLike | Blob): void;
491
+ close(code?: number, reason?: string): void;
492
+ }
493
+
494
+ interface BackpressureConfig {
495
+ enabled?: boolean;
496
+ highWaterMarkBytes?: number;
497
+ lowWaterMarkBytes?: number;
498
+ pollIntervalMs?: number;
499
+ }
500
+ type BackpressureEventCallback = (ev: {
501
+ state: 'high' | 'low';
502
+ bufferedAmount: number;
503
+ }) => void;
504
+ declare class BackpressureManager {
505
+ readonly enabled: boolean;
506
+ readonly highWaterMarkBytes: number;
507
+ readonly lowWaterMarkBytes: number;
508
+ readonly pollIntervalMs: number;
509
+ private blocked;
510
+ private pollTimer;
511
+ private readonly transport;
512
+ private readonly clock;
513
+ private readonly onStateChange;
514
+ private readonly onWakeWriter;
515
+ constructor(transport: Transport, clock: Clock, config: BackpressureConfig | undefined, onStateChange: BackpressureEventCallback, onWakeWriter: () => void);
516
+ start(): void;
517
+ private scheduleNextPoll;
518
+ stop(): void;
519
+ isBlocked(): boolean;
520
+ check(): boolean;
521
+ }
522
+
523
+ interface OutboundConfig {
524
+ reliableQueueSize?: number;
525
+ unreliableQueueSize?: number;
526
+ reliableOverflow?: 'drop' | 'close';
527
+ reliableBurst?: number;
528
+ unreliableBurst?: number;
529
+ policyProvider?: PolicyProvider;
530
+ enableClientRateLimit?: boolean;
531
+ }
532
+ interface OutboundFrame {
533
+ room: string;
534
+ channel: string;
535
+ reliable: boolean;
536
+ wire: string | ArrayBufferLike | Uint8Array;
537
+ frameType?: 'text' | 'binary';
538
+ coalesceKey?: string;
539
+ }
540
+ /**
541
+ * Bounded FIFO queue utilizing a sliding head index to maintain O(1) dequeue
542
+ * performance without invoking Array.prototype.shift() which incurs O(n) re-indexing.
543
+ */
544
+ declare class OutboundQueue<T> {
545
+ private items;
546
+ private head;
547
+ readonly capacity: number;
548
+ constructor(capacity: number);
549
+ get size(): number;
550
+ enqueue(item: T): void;
551
+ dequeue(): T | undefined;
552
+ dropOldest(): T | undefined;
553
+ peek(): T | undefined;
554
+ clear(): number;
555
+ }
556
+
557
+ interface PresenceState {
558
+ known: Set<string>;
559
+ serverCount: number;
560
+ invalidated: boolean;
561
+ invalidReason: 'reconnected' | 'reliable presence gap' | '';
562
+ }
563
+ interface PresenceConfig {
564
+ autoInvalidateOnReliableGap?: boolean;
565
+ }
566
+ declare class PresenceManager {
567
+ private readonly states;
568
+ readonly autoInvalidateOnReliableGap: boolean;
569
+ constructor(config?: PresenceConfig);
570
+ get(room: string): PresenceState | undefined;
571
+ init(room: string, members: number): void;
572
+ remove(room: string): void;
573
+ clear(): void;
574
+ invalidateAll(): string[];
575
+ knownMembers(room: string, selfLabel: string): string[];
576
+ lastServerMemberCount(room: string): {
577
+ count: number;
578
+ ok: boolean;
579
+ };
580
+ presenceInvalidated(room: string): boolean;
581
+ resetPresence(room: string): void;
582
+ }
583
+
584
+ declare class SdkError extends Error {
585
+ constructor(message: string, options?: ErrorOptions);
586
+ }
587
+
588
+ declare const ROOM_NAME_RE: RegExp;
589
+ declare const CHANNEL_NAME_RE: RegExp;
590
+ interface ValidationConfig {
591
+ enabled?: boolean;
592
+ maxTextPayloadBytes?: number;
593
+ maxBinaryPayloadBytes?: number;
594
+ }
595
+ type ValidationField = 'room' | 'channel' | 'payload' | 'binary_payload';
596
+ type ValidationRule = 'name_syntax' | 'reserved_channel' | 'too_large';
597
+ declare class ValidationError extends SdkError {
598
+ readonly field: ValidationField;
599
+ readonly rule: ValidationRule;
600
+ readonly value: string;
601
+ readonly limit?: number;
602
+ constructor(field: ValidationField, rule: ValidationRule, value: string, limit?: number);
603
+ }
604
+ declare class BinaryPayloadTooLargeError extends ValidationError {
605
+ readonly byteLength: number;
606
+ readonly maxBytes: number;
607
+ constructor(byteLength: number, maxBytes: number);
608
+ }
609
+ declare function validateRoomName(room: string, config?: ValidationConfig): void;
610
+ declare function validateChannelName(channel: string, config?: ValidationConfig): void;
611
+ declare function validateTextPayloadSize(marshaledLength: number, config?: ValidationConfig): void;
612
+ declare function validateBinaryPayloadSize(byteLength: number, config?: ValidationConfig): void;
613
+
614
+ type AuthFailureMode = 'heuristic' | 'never-fatal' | 'always-fatal';
615
+ type AuthMode = 'query';
616
+ interface PublishRequest {
617
+ room: string;
618
+ channel?: string;
619
+ payload: unknown;
620
+ reliable?: boolean;
621
+ includeSender?: boolean;
622
+ }
623
+ interface ClientConfig {
624
+ url: string;
625
+ apiKey: string;
626
+ authFailureMode?: AuthFailureMode;
627
+ onAmbiguousAuth?: (closeCode: number, reason: string) => 'fatal' | 'retry';
628
+ reconnect?: ReconnectConfig;
629
+ heartbeat?: HeartbeatConfig;
630
+ restore?: RestoreConfig;
631
+ outbound?: OutboundConfig;
632
+ backpressure?: BackpressureConfig;
633
+ presence?: PresenceConfig;
634
+ errorPolicy?: ErrorPolicyConfig;
635
+ validation?: ValidationConfig;
636
+ maxBinaryPayloadBytes?: number;
637
+ welcomeTimeoutMs?: number;
638
+ requestTimeoutMs?: number;
639
+ logger?: Logger;
640
+ clock?: Clock;
641
+ transport?: Transport;
642
+ }
643
+ declare function buildWsUrl(baseUrl: string, apiKey: string): string;
644
+ declare class Client {
645
+ private readonly config;
646
+ private readonly clock;
647
+ private readonly emitter;
648
+ private readonly logger;
649
+ private transport;
650
+ private _state;
651
+ private _capabilities;
652
+ private serverVersion;
653
+ private firstConnectDone;
654
+ private currentConnWelcomeReceived;
655
+ private isRestoringSession;
656
+ private reconnectAttempts;
657
+ private reconnectTimer;
658
+ private welcomeTimer;
659
+ private readonly intents;
660
+ private readonly waiters;
661
+ private listRoomsLock;
662
+ private heartbeatManager;
663
+ private readonly reliableQueue;
664
+ private readonly unreliableQueue;
665
+ private readonly coalesceManager;
666
+ private readonly backpressureManager;
667
+ private readonly rateLimiters;
668
+ private readonly writer;
669
+ private readonly policyOverrides;
670
+ private readonly appliedPolicies;
671
+ private _selfLabel;
672
+ private readonly binaryOwner;
673
+ private readonly presenceManager;
674
+ private readonly seqTracker;
675
+ private readonly rttTracker;
676
+ private readonly createdRooms;
677
+ private pingChain;
678
+ private pendingConnectResolve;
679
+ private pendingConnectReject;
680
+ constructor(config: ClientConfig);
681
+ get state(): State;
682
+ get capabilities(): Readonly<Capabilities> | undefined;
683
+ get selfLabel(): string;
684
+ knownMembers(room: string): string[];
685
+ lastServerMemberCount(room: string): {
686
+ count: number;
687
+ ok: boolean;
688
+ };
689
+ presenceInvalidated(room: string): boolean;
690
+ resetPresence(room: string): void;
691
+ lastSeq(room: string, channel: string): {
692
+ seq: number;
693
+ ok: boolean;
694
+ };
695
+ rttStats(): RttStats | undefined;
696
+ ping(timeoutMs?: number): Promise<number>;
697
+ private clearRoomState;
698
+ private isClosed;
699
+ on<E extends EventName>(event: E, handler: (payload: EventPayload<E>) => void): () => void;
700
+ connect(): Promise<WelcomeFrame>;
701
+ close(): Promise<void>;
702
+ createRoom(req: CreateRoomRequest): Promise<RoomCreatedFrame>;
703
+ joinRoomWithBinary(roomOrReq: string | (JoinRoomRequest & {
704
+ binaryChannels?: BinaryChannelMap;
705
+ }), passcodeOrNothing?: string, binaryChannelsOrNothing?: BinaryChannelMap): Promise<RoomJoinedFrame>;
706
+ joinRoom(req: JoinRoomRequest): Promise<RoomJoinedFrame>;
707
+ leaveRoom(room: string): Promise<RoomLeftFrame>;
708
+ deleteRoom(room: string): Promise<void>;
709
+ listRooms(): Promise<RoomListFrame>;
710
+ send(frame: ClientFrame): void;
711
+ publish(req: PublishRequest): Promise<void>;
712
+ publishBinary(roomOrReq: string | {
713
+ room: string;
714
+ channel: string;
715
+ payload: ArrayBuffer | Uint8Array;
716
+ reliable?: boolean;
717
+ }, channelOrNothing?: string, payloadOrNothing?: ArrayBuffer | Uint8Array): Promise<void>;
718
+ setChannelPolicy(room: string, channel: string, policy: ChannelPolicy): void;
719
+ queueDepth(): {
720
+ reliable: number;
721
+ unreliable: number;
722
+ coalesced: number;
723
+ };
724
+ bufferedAmount(): number;
725
+ __flushNow(): Promise<void>;
726
+ private getPolicy;
727
+ private discardOutboundQueues;
728
+ getRoomIntents(): RoomIntent[];
729
+ forgetRoom(room: string): void;
730
+ private transitionState;
731
+ private initiateConnect;
732
+ private setupTransportHandlers;
733
+ private handleIncomingData;
734
+ private handlePresenceMessage;
735
+ private handleWelcome;
736
+ private handleWelcomeTimeout;
737
+ private handlePreOpenFailure;
738
+ private handleSocketClose;
739
+ private classifyAndDispatch;
740
+ private triggerReconnect;
741
+ private restoreSession;
742
+ private sendWithCorrelation;
743
+ private handleErrorFrame;
744
+ private failPendingWaiters;
745
+ private clearTimers;
746
+ private rejectPendingConnect;
747
+ }
748
+
749
+ declare class TokenBucket {
750
+ readonly ratePerSec: number;
751
+ readonly burst: number;
752
+ private tokens;
753
+ private lastRefillMs;
754
+ private readonly clock;
755
+ constructor(ratePerSec: number, burst: number, clock: Clock);
756
+ advanceTo(now: number): void;
757
+ tryConsume(): boolean;
758
+ retryAfterMs(now: number): number;
759
+ }
760
+ declare class RateLimiterRegistry {
761
+ private readonly limiters;
762
+ private readonly serverBackoffs;
763
+ private readonly recentRoomByChan;
764
+ private readonly clock;
765
+ constructor(clock: Clock);
766
+ private makeKey;
767
+ get(room: string, channel: string, ratePerSec: number): TokenBucket;
768
+ recordPublish(room: string, channel: string): void;
769
+ getRecentRoom(channel: string): string | undefined;
770
+ pause(room: string, channel: string, untilMs: number): void;
771
+ isPaused(room: string, channel: string, now: number): {
772
+ paused: boolean;
773
+ retryAfterMs: number;
774
+ };
775
+ clearRoom(room: string): void;
776
+ clearAll(): void;
777
+ }
778
+
779
+ declare class CapabilityLimitError extends SdkError {
780
+ readonly limit: 'max_metadata_bytes' | 'max_channels_per_room' | 'max_rooms_per_key';
781
+ readonly requested: number;
782
+ readonly allowed: number;
783
+ constructor(limit: 'max_metadata_bytes' | 'max_channels_per_room' | 'max_rooms_per_key', requested: number, allowed: number);
784
+ }
785
+ declare function checkCapabilityPreflight(capabilities: Capabilities | undefined, req: CreateRoomRequest, ownedRoomsCount: number): void;
786
+
787
+ declare class AuthError extends SdkError {
788
+ readonly code: "AUTH_FAILED";
789
+ constructor(message?: string, options?: ErrorOptions);
790
+ }
791
+ interface ConnectErrorCause {
792
+ closeCode?: number;
793
+ reason?: string;
794
+ [key: string]: unknown;
795
+ }
796
+ declare class ConnectError extends SdkError {
797
+ readonly cause?: ConnectErrorCause | unknown;
798
+ constructor(message: string, cause?: ConnectErrorCause | unknown);
799
+ get closeCode(): number | undefined;
800
+ get reason(): string | undefined;
801
+ }
802
+ declare class PolicyViolationError extends SdkError {
803
+ readonly code: "POLICY_VIOLATION";
804
+ readonly closeCode: number;
805
+ readonly reason?: string;
806
+ constructor(message?: string, closeCode?: number, reason?: string);
807
+ }
808
+ declare class RequestTimeoutError extends SdkError {
809
+ constructor(message?: string);
810
+ }
811
+ declare class ConcurrentRequestError extends SdkError {
812
+ constructor(message?: string);
813
+ }
814
+ declare class ServerError extends SdkError {
815
+ readonly code: ErrorCode;
816
+ readonly channel?: string;
817
+ readonly retryAfterMs?: number;
818
+ constructor(code: ErrorCode, message: string, channel?: string, retryAfterMs?: number);
819
+ }
820
+ declare class NotReadyError extends SdkError {
821
+ constructor(message?: string);
822
+ }
823
+ declare class ChannelNotReliableError extends SdkError {
824
+ readonly channel: string;
825
+ constructor(channel: string, message?: string);
826
+ }
827
+ declare class RateLimitedError extends SdkError {
828
+ readonly retryAfterMs: number;
829
+ readonly channel: string;
830
+ readonly source: 'local' | 'server';
831
+ constructor(retryAfterMs: number, channel: string, source: 'local' | 'server', message?: string);
832
+ }
833
+ type BinaryMapValidationReason = 'out_of_range' | 'reserved_channel' | 'duplicate_id' | 'duplicate_channel';
834
+ declare class BinaryMapValidationError extends SdkError {
835
+ readonly channel: string;
836
+ readonly id: number;
837
+ readonly reason: BinaryMapValidationReason;
838
+ constructor(channel: string, id: number, reason: BinaryMapValidationReason);
839
+ }
840
+ declare class BinaryMapExhaustedError extends SdkError {
841
+ constructor(message?: string);
842
+ }
843
+ declare class BinaryIdCollisionError extends SdkError {
844
+ readonly id: number;
845
+ readonly existing: string[];
846
+ readonly rejected: string[];
847
+ constructor(id: number, existing: string[], rejected: string[]);
848
+ }
849
+ declare class BinaryChannelUnmappedError extends SdkError {
850
+ readonly room: string;
851
+ readonly channel: string;
852
+ constructor(room: string, channel: string);
853
+ }
854
+
855
+ interface SeqState {
856
+ last: number;
857
+ hasBase: boolean;
858
+ }
859
+ interface SequenceGapResult {
860
+ prev: number;
861
+ current: number;
862
+ missed: number;
863
+ reliable: boolean;
864
+ }
865
+ declare class SeqTracker {
866
+ private readonly states;
867
+ private makeKey;
868
+ lastSeq(room: string, channel: string): {
869
+ seq: number;
870
+ ok: boolean;
871
+ };
872
+ process(room: string, channel: string, seq: number, reliable: boolean): {
873
+ gap?: SequenceGapResult;
874
+ };
875
+ rebaselineAll(): void;
876
+ clearRoom(room: string): void;
877
+ clear(): void;
878
+ }
879
+
880
+ export { AuthError, type AuthFailureMode, type AuthMode, type BackpressureConfig, type BackpressureEvent, BackpressureManager, type BinaryChannelMap$1 as BinaryChannelMap, BinaryChannelUnmappedError, BinaryIdCollisionError, type BinaryIdCollisionEvent, BinaryMapBuilder, BinaryMapExhaustedError, BinaryMapValidationError, type BinaryMapValidationReason, type BinaryMappingChangedEvent, type BinaryMessageEvent, BinaryPayloadTooLargeError, type BinaryUnknownChannelEvent, BrowserWebSocketTransport, CHANNEL_NAME_RE, type Capabilities, type CapabilitiesChangedEvent, type CapabilityFeatures, CapabilityLimitError, type CapabilityLimits, type ChannelConfig, type ChannelConfigInput, ChannelNotReliableError, type ChannelPolicy, Client, type ClientConfig, type ClientFrame, type Clock, type CoalescedEvent, ConcurrentRequestError, ConnectError, type ConnectErrorCause, type ConnectedEvent, type CreateRoomRequest, type DeleteRoomRequest, type DisconnectedEvent, type ErrorAction, type ErrorClassification, type ErrorClassifiedEvent, type ErrorCode, type ErrorEvent, type ErrorFrame, type ErrorPolicyConfig, type EventMap, type EventName, type EventPayload, type FailedIntent, type FatalEvent, type HeartbeatConfig, type HeartbeatTimeoutEvent, type IntentFailedEvent, type JitterMode, type JoinRoomRequest, type LeaveRoomRequest, type ListRoomsFeatures, type ListRoomsRequest, type LogLevel, type Logger, type MessageFrame, NotReadyError, type OutboundConfig, type OutboundFrame, OutboundQueue, type PingRequest, type PolicyAppliedEvent, type PolicyProvider, PolicyViolationError, type PongFrame, type PresenceConfig, type PresenceInvalidatedEvent, type PresenceJoinEvent, type PresenceLeaveEvent, PresenceManager, type PresenceState, type ProtocolViolationEvent, type PublishRequest, type QueuesDiscardedEvent, ROOM_NAME_RE, RateLimitedError, type RateLimitedEvent, RateLimiterRegistry, RealClock, type ReconnectConfig, type ReconnectingEvent, type ReliableOverflowEvent, RequestTimeoutError, type RestoreConfig, type RoomCreatedFrame, type RoomDeletedEvent, type RoomFullPolicy, type RoomIntent, type RoomJoinedFrame, type RoomKind, type RoomLeftFrame, type RoomListFrame, type RoomSummary, type RttEvent$1 as RttEvent, type RttStats, RttTracker, SdkError, type SeqState, SeqTracker, type SequenceGapEvent, type SequenceGapResult, ServerError, type ServerFrame, type SessionRestoredEvent, type State, type StateChangeEvent, type Timer, TokenBucket, type Transport, type UnreliableDroppedEvent, type ValidationConfig, ValidationError, type ValidationField, type ValidationRule, type WelcomeFrame, type PublishRequest$1 as WirePublishRequest, buildWsUrl, checkCapabilityPreflight, classifyError, computeReconnectDelay, isErrorFrame, isMessageFrame, isWelcomeFrame, presetsFor, redactString, redactUrl, redactValue, resolvePolicy, validateBinaryMap, validateBinaryPayloadSize, validateChannelName, validateRoomName, validateTextPayloadSize };