@bytesocket/client
Advanced tools
+190
-142
@@ -5,9 +5,5 @@ import { MsgpackrOptions, AnyCallback, LifecycleTypes, SocketEvents, ErrorContext, StringNumberKeys, EventsForRooms, LifecycleMessage, UserMessage, StringKeys } from '@bytesocket/types'; | ||
| /** | ||
| * Signature of a callback that receives event data. | ||
| */ | ||
| /** Signature of a callback that receives event data. */ | ||
| type EventCallback<D> = (data: D) => void; | ||
| /** | ||
| * Internal state tracking for a single room. | ||
| */ | ||
| /** Internal state tracking for a single room. */ | ||
| interface RoomState { | ||
@@ -33,4 +29,4 @@ /** Current pending operation (join/leave) or null. */ | ||
| * const socket = new ByteSocket('ws://localhost:8080', { | ||
| * auth: (cb) => { | ||
| * fetch('/api/token').then(res => res.json()).then(cb); | ||
| * auth: (callback) => { | ||
| * fetch('/api/token').then(res => res.json()).then(callback); | ||
| * } | ||
@@ -41,18 +37,25 @@ * }); | ||
| data: D; | ||
| } | ((cb: (data: D) => void) => void); | ||
| /** | ||
| * Configuration options for ByteSocket. | ||
| */ | ||
| } | ((callback: (data: D) => void) => void); | ||
| /** Configuration options for ByteSocket. */ | ||
| type ByteSocketOptions = { | ||
| /** Automatically call `connect()` in the constructor. Default `true`. */ | ||
| /** Automatically call `connect()` in the constructor. @default true */ | ||
| autoConnect?: boolean; | ||
| /** Enable automatic reconnection on unexpected close. Default `true`. */ | ||
| /** Enable automatic reconnection on unexpected close. @default true */ | ||
| reconnection?: boolean; | ||
| /** Maximum number of reconnection attempts. Default `Infinity`. */ | ||
| /** Maximum number of reconnection attempts. @default Infinity */ | ||
| maxReconnectionAttempts?: number; | ||
| /** Base delay in milliseconds before first reconnection attempt. Default `1000`. */ | ||
| /** Base delay in milliseconds before first reconnection attempt. @default 1000 */ | ||
| reconnectionDelay?: number; | ||
| /** Maximum reconnection delay after exponential backoff. Default `5000`. */ | ||
| /** Maximum reconnection delay after exponential backoff. @default 5000 */ | ||
| reconnectionDelayMax?: number; | ||
| /** Randomization factor for reconnection delay (0 to 1). Default `0.5`. */ | ||
| /** | ||
| * Whether to attempt reconnection after the server sends a normal closure | ||
| * (close codes `1000` or `1001`). @default true | ||
| * | ||
| * Normal closures are typically graceful shutdowns (e.g., server restart, | ||
| * idle timeout, load balancer termination). Setting this to `false` will | ||
| * prevent automatic reconnection in these cases. | ||
| */ | ||
| reconnectOnNormalClosure?: boolean; | ||
| /** Randomization factor for reconnection delay (0 to 1). @default 0.5 */ | ||
| randomizationFactor?: number; | ||
@@ -65,17 +68,17 @@ /** WebSocket subprotocols. */ | ||
| queryParams?: Record<string, string>; | ||
| /** Enable internal ping/pong heartbeat. Default `true`. */ | ||
| /** Enable internal ping/pong heartbeat. @default true */ | ||
| heartbeatEnabled?: boolean; | ||
| /** Interval between ping messages in ms. Default `25000`. */ | ||
| /** Interval between ping messages in ms. @default 25000 */ | ||
| pingInterval?: number; | ||
| /** Time to wait for pong response before closing connection. Default `20000`. */ | ||
| /** Time to wait for pong response before closing connection. @default 20000 */ | ||
| pingTimeout?: number; | ||
| /** Authentication configuration. */ | ||
| auth?: AuthConfig; | ||
| /** Timeout for authentication response in ms. Default `5000`. */ | ||
| /** Timeout for authentication response in ms. @default 5000 */ | ||
| authTimeout?: number; | ||
| /** Maximum number of outgoing messages to queue while offline. Default `100`. */ | ||
| /** Maximum number of outgoing messages to queue while offline. @default 100 */ | ||
| maxQueueSize?: number; | ||
| /** Serialization format: `"json"` or `"binary"` (msgpack). Default `"binary"`. */ | ||
| /** Serialization format: `"json"` or `"binary"` (msgpack). @default "binary" */ | ||
| serialization?: "json" | "binary"; | ||
| /** Enable debug logging to console. Default `false`. */ | ||
| /** Enable debug logging to console. @default false */ | ||
| debug?: boolean; | ||
@@ -99,21 +102,11 @@ /** Options passed directly to the underlying msgpackr Packr instance. */ | ||
| protected onceLifecycleCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>; | ||
| /** | ||
| * Adds a callback to a given event in the provided map. | ||
| */ | ||
| /** Adds a callback to a given event in the provided map. */ | ||
| protected addCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callback: EventCallback<D>): void; | ||
| /** | ||
| * Registers a one‑time callback by storing the wrapper in a separate map. | ||
| */ | ||
| /** Registers a one‑time callback by storing the wrapper in a separate map. */ | ||
| protected addOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void; | ||
| /** | ||
| * Removes a callback from an event map. | ||
| */ | ||
| /** Removes a callback from an event map. */ | ||
| protected deleteCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callbackWrapper: EventCallback<D>): void; | ||
| /** | ||
| * Removes a one‑time callback and its associated wrapper. | ||
| */ | ||
| /** Removes a one‑time callback and its associated wrapper. */ | ||
| protected deleteOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void; | ||
| /** | ||
| * Registers a permanent listener for a lifecycle event. | ||
| */ | ||
| /** Registers a permanent listener for a lifecycle event. */ | ||
| protected onLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void; | ||
@@ -130,5 +123,3 @@ /** | ||
| protected onceLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void; | ||
| /** | ||
| * Safely invokes a set of callbacks, catching and logging errors if debug is enabled. | ||
| */ | ||
| /** Safely invokes a set of callbacks, catching and logging errors if debug is enabled. */ | ||
| protected triggerCallback<Args extends Array<unknown>>(callbackWrappers?: Set<AnyCallback>, ...args: Args): void; | ||
@@ -406,16 +397,48 @@ } | ||
| * | ||
| * @example | ||
| * // Define your event schema | ||
| * interface MyEvents extends SocketEvents<{ | ||
| * emit: { ping: void }; | ||
| * listen: { pong: number }; | ||
| * @example Symmetric events (most common) | ||
| * ```ts | ||
| * // Define your event map | ||
| * type MyEvents = SocketEvents<{ | ||
| * "chat:message": { text: string }; | ||
| * "user:joined": { userId: string }; | ||
| * }>; | ||
| * | ||
| * // Create a typed socket instance | ||
| * const socket = new ByteSocket<MyEvents>('wss://example.com/socket', { | ||
| * debug: true, | ||
| * auth: { token: 'abc123' } | ||
| * }); | ||
| * | ||
| * // Use typed methods (emit and listen share the same event map) | ||
| * socket.emit('chat:message', { text: 'Hello!' }); | ||
| * socket.on('user:joined', (data) => console.log(data.userId)); | ||
| * | ||
| * socket.rooms.join('lobby'); | ||
| * socket.rooms.emit('lobby', 'chat:message', { text: 'Hi everyone' }); | ||
| * socket.rooms.on('lobby', 'chat:message', (data) => { | ||
| * console.log(`Message: ${data.text}`); | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @example Asymmetric events (full control via interface extension) | ||
| * ```ts | ||
| * // Extend SocketEvents to differentiate emit/listen/room maps | ||
| * interface MyEvents extends SocketEvents { | ||
| * emit: { | ||
| * "message:send": { text: string }; | ||
| * "ping": void; | ||
| * }; | ||
| * listen: { | ||
| * "message:receive": { text: string; sender: string }; | ||
| * "pong": number; | ||
| * }; | ||
| * emitRoom: { | ||
| * chat: { message: string }; | ||
| * chat: { "message": { text: string } }; | ||
| * dm: { "message": { text: string; recipient: string } }; | ||
| * }; | ||
| * listenRoom: { | ||
| * chat: { message: string; sender: string }; | ||
| * chat: { "message": { text: string; sender: string } }; | ||
| * }; | ||
| * }> {} | ||
| * } | ||
| * | ||
| * // Create a typed socket instance | ||
| * const socket = new ByteSocket<MyEvents>('wss://example.com/socket', { | ||
@@ -426,11 +449,13 @@ * debug: true, | ||
| * | ||
| * // Use typed methods | ||
| * // Global emits/listens | ||
| * socket.emit('ping', undefined); | ||
| * socket.on('pong', (timestamp) => console.log(timestamp)); | ||
| * socket.on('message:receive', (data) => console.log(`${data.sender}: ${data.text}`)); | ||
| * | ||
| * // Room‑specific emits/listens | ||
| * socket.rooms.join('chat'); | ||
| * socket.rooms.emit('chat', 'message', { message: 'Hello!' }); | ||
| * socket.rooms.emit('chat', 'message', { text: 'Hello!' }); | ||
| * socket.rooms.on('chat', 'message', (data) => { | ||
| * console.log(`${data.sender}: ${data.message}`); | ||
| * console.log(`${data.sender}: ${data.text}`); | ||
| * }); | ||
| * ``` | ||
| */ | ||
@@ -448,86 +473,55 @@ declare class ByteSocket<TEvents extends SocketEvents = SocketEvents> extends SocketBase { | ||
| readonly lifecycle: { | ||
| /** Register a listener for socket open. */ | ||
| onOpen: (callback: () => void) => void; | ||
| /** Remove a listener for socket open. */ | ||
| offOpen: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for socket open. */ | ||
| onceOpen: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for socket open. | ||
| * Register a listener for raw incoming WebSocket messages. | ||
| * Called immediately when a message is received, before any internal processing. | ||
| * | ||
| * @param callback - Receives the raw data and a boolean indicating if it's binary. | ||
| */ | ||
| readonly onOpen: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for socket open. | ||
| */ | ||
| readonly offOpen: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for socket open. | ||
| */ | ||
| readonly onceOpen: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for socket close. | ||
| */ | ||
| readonly onClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** | ||
| * Remove a listener for socket close. | ||
| */ | ||
| readonly offClose: (callback?: (event: CloseEvent) => void) => void; | ||
| /** | ||
| * Register a one‑time listener for socket close. | ||
| */ | ||
| readonly onceClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** | ||
| * Register a listener for WebSocket errors. | ||
| */ | ||
| readonly onError: (callback: (event: Event) => void) => void; | ||
| /** | ||
| * Remove a listener for WebSocket errors. | ||
| */ | ||
| readonly offError: (callback?: (event: Event) => void) => void; | ||
| /** | ||
| * Register a one‑time listener for WebSocket errors. | ||
| */ | ||
| readonly onceError: (callback: (event: Event) => void) => void; | ||
| /** | ||
| * Register a listener for authentication success. | ||
| */ | ||
| readonly onAuthSuccess: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for authentication success. | ||
| */ | ||
| readonly offAuthSuccess: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for authentication success. | ||
| */ | ||
| readonly onceAuthSuccess: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for authentication errors. | ||
| */ | ||
| readonly onAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** | ||
| * Remove a listener for authentication errors. | ||
| */ | ||
| readonly offAuthError: (callback?: (ctx: ErrorContext) => void) => void; | ||
| /** | ||
| * Register a one‑time listener for authentication errors. | ||
| */ | ||
| readonly onceAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** | ||
| * Register a listener for when the message queue becomes full and a message is dropped. | ||
| */ | ||
| readonly onQueueFull: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for queue‑full events. | ||
| */ | ||
| readonly offQueueFull: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for queue‑full events. | ||
| */ | ||
| readonly onceQueueFull: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for when reconnection fails after all attempts. | ||
| */ | ||
| readonly onReconnectFailed: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for reconnect‑failed events. | ||
| */ | ||
| readonly offReconnectFailed: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for reconnect‑failed events. | ||
| */ | ||
| readonly onceReconnectFailed: (callback: () => void) => void; | ||
| onMessage: (callback: (data: string | ArrayBuffer) => void) => void; | ||
| /** Remove a listener for raw messages. */ | ||
| offMessage: (callback?: (data: string | ArrayBuffer) => void) => void; | ||
| /** Register a one‑time listener for raw incoming WebSocket messages. */ | ||
| onceMessage: (callback: (data: string | ArrayBuffer) => void) => void; | ||
| /** Register a listener for socket close. */ | ||
| onClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** Remove a listener for socket close. */ | ||
| offClose: (callback?: (event: CloseEvent) => void) => void; | ||
| /** Register a one‑time listener for socket close. */ | ||
| onceClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** Register a listener for WebSocket errors. */ | ||
| onError: (callback: (event: Event) => void) => void; | ||
| /** Remove a listener for WebSocket errors. */ | ||
| offError: (callback?: (event: Event) => void) => void; | ||
| /** Register a one‑time listener for WebSocket errors. */ | ||
| onceError: (callback: (event: Event) => void) => void; | ||
| /** Register a listener for authentication success. */ | ||
| onAuthSuccess: (callback: () => void) => void; | ||
| /** Remove a listener for authentication success. */ | ||
| offAuthSuccess: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for authentication success. */ | ||
| onceAuthSuccess: (callback: () => void) => void; | ||
| /** Register a listener for authentication errors. */ | ||
| onAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** Remove a listener for authentication errors. */ | ||
| offAuthError: (callback?: (ctx: ErrorContext) => void) => void; | ||
| /** Register a one‑time listener for authentication errors. */ | ||
| onceAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** Register a listener for when the message queue becomes full and a message is dropped. */ | ||
| onQueueFull: (callback: () => void) => void; | ||
| /** Remove a listener for queue‑full events. */ | ||
| offQueueFull: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for queue‑full events. */ | ||
| onceQueueFull: (callback: () => void) => void; | ||
| /** Register a listener for when reconnection fails after all attempts. */ | ||
| onReconnectFailed: (callback: () => void) => void; | ||
| /** Remove a listener for reconnect‑failed events. */ | ||
| offReconnectFailed: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for reconnect‑failed events. */ | ||
| onceReconnectFailed: (callback: () => void) => void; | ||
| }; | ||
@@ -556,3 +550,57 @@ /** | ||
| /** | ||
| * Send a raw message (string, Blob, or BufferSource) directly over the WebSocket. | ||
| * Whether the socket is currently able to send messages. | ||
| * Returns `true` if the WebSocket is open and authentication (if configured) has succeeded. | ||
| * Useful for checking readiness before calling `sendRaw()` | ||
| * No need to use it with `emit()` or `send()` because they already use it under the hood. | ||
| * | ||
| * @example | ||
| * if (socket.canSend) { | ||
| * socket.sendRaw('PROTOCOL: custom-v1'); | ||
| * } | ||
| */ | ||
| get canSend(): boolean; | ||
| /** | ||
| * Encode a structured payload into a format suitable for sending over the WebSocket. | ||
| * Uses the configured serialization (`"json"` or `"binary"`). | ||
| * | ||
| * **Advanced usage only.** Prefer `emit()` or `send()` for type‑safe communication. | ||
| * | ||
| * @param payload - A lifecycle message or user event object. | ||
| * @returns Encoded string (JSON) or Uint8Array (MessagePack). | ||
| * | ||
| * @example | ||
| * // Pre‑encode a payload for repeated use | ||
| * const encoded = socket.encode({ event: 'chat', data: { text: 'Hello' } }); | ||
| * socket.sendRaw(encoded); | ||
| */ | ||
| encode<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): any; | ||
| /** | ||
| * Decode a raw WebSocket message into a structured payload. | ||
| * Automatically detects JSON or MessagePack based on the binary flag and message content. | ||
| * | ||
| * **Advanced usage only.** Normally you should use `on()` listeners to receive typed data. | ||
| * | ||
| * @param message - Raw string (JSON) or Uint8Array (MessagePack). | ||
| * @param isBinary - Whether the message is binary. If omitted, format is detected from the message type. | ||
| * @returns Decoded lifecycle or user message object. | ||
| */ | ||
| decode(message: string | ArrayBuffer, isBinary?: boolean): any; | ||
| /** | ||
| * Send a pre‑serialized payload (LifecycleMessage or UserMessage) over the WebSocket. | ||
| * If the socket is not ready, the payload is queued and sent when the connection | ||
| * becomes operational and authentication (if required) has succeeded. | ||
| * | ||
| * @param payload - The structured payload to encode and send. | ||
| * | ||
| * @example | ||
| * // Send a custom lifecycle message (advanced) | ||
| * socket.send({ type: LifecycleTypes.ping }); | ||
| * | ||
| * @example | ||
| * // Send a raw user event (equivalent to socket.emit('chat', data)) | ||
| * socket.send({ event: 'chat', data: { text: 'Hello' } }); | ||
| */ | ||
| send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void; | ||
| /** | ||
| * Send a raw message (string or BufferSource) directly over the WebSocket. | ||
| * Bypasses serialization and auth checks. If the socket is not open, the message | ||
@@ -563,3 +611,3 @@ * is queued and sent when possible (auth state is ignored). | ||
| */ | ||
| sendRaw(message: string | Blob | BufferSource): void; | ||
| sendRaw(message: string | BufferSource): void; | ||
| /** | ||
@@ -632,4 +680,4 @@ * Emit a global event. | ||
| * | ||
| * @param code - Close code (default none). | ||
| * @param reason - Close reason (default none). | ||
| * @param code - Close code. @default undefined | ||
| * @param reason - Close reason. @default undefined | ||
| */ | ||
@@ -636,0 +684,0 @@ close(code?: number, reason?: string): void; |
+190
-142
@@ -5,9 +5,5 @@ import { MsgpackrOptions, AnyCallback, LifecycleTypes, SocketEvents, ErrorContext, StringNumberKeys, EventsForRooms, LifecycleMessage, UserMessage, StringKeys } from '@bytesocket/types'; | ||
| /** | ||
| * Signature of a callback that receives event data. | ||
| */ | ||
| /** Signature of a callback that receives event data. */ | ||
| type EventCallback<D> = (data: D) => void; | ||
| /** | ||
| * Internal state tracking for a single room. | ||
| */ | ||
| /** Internal state tracking for a single room. */ | ||
| interface RoomState { | ||
@@ -33,4 +29,4 @@ /** Current pending operation (join/leave) or null. */ | ||
| * const socket = new ByteSocket('ws://localhost:8080', { | ||
| * auth: (cb) => { | ||
| * fetch('/api/token').then(res => res.json()).then(cb); | ||
| * auth: (callback) => { | ||
| * fetch('/api/token').then(res => res.json()).then(callback); | ||
| * } | ||
@@ -41,18 +37,25 @@ * }); | ||
| data: D; | ||
| } | ((cb: (data: D) => void) => void); | ||
| /** | ||
| * Configuration options for ByteSocket. | ||
| */ | ||
| } | ((callback: (data: D) => void) => void); | ||
| /** Configuration options for ByteSocket. */ | ||
| type ByteSocketOptions = { | ||
| /** Automatically call `connect()` in the constructor. Default `true`. */ | ||
| /** Automatically call `connect()` in the constructor. @default true */ | ||
| autoConnect?: boolean; | ||
| /** Enable automatic reconnection on unexpected close. Default `true`. */ | ||
| /** Enable automatic reconnection on unexpected close. @default true */ | ||
| reconnection?: boolean; | ||
| /** Maximum number of reconnection attempts. Default `Infinity`. */ | ||
| /** Maximum number of reconnection attempts. @default Infinity */ | ||
| maxReconnectionAttempts?: number; | ||
| /** Base delay in milliseconds before first reconnection attempt. Default `1000`. */ | ||
| /** Base delay in milliseconds before first reconnection attempt. @default 1000 */ | ||
| reconnectionDelay?: number; | ||
| /** Maximum reconnection delay after exponential backoff. Default `5000`. */ | ||
| /** Maximum reconnection delay after exponential backoff. @default 5000 */ | ||
| reconnectionDelayMax?: number; | ||
| /** Randomization factor for reconnection delay (0 to 1). Default `0.5`. */ | ||
| /** | ||
| * Whether to attempt reconnection after the server sends a normal closure | ||
| * (close codes `1000` or `1001`). @default true | ||
| * | ||
| * Normal closures are typically graceful shutdowns (e.g., server restart, | ||
| * idle timeout, load balancer termination). Setting this to `false` will | ||
| * prevent automatic reconnection in these cases. | ||
| */ | ||
| reconnectOnNormalClosure?: boolean; | ||
| /** Randomization factor for reconnection delay (0 to 1). @default 0.5 */ | ||
| randomizationFactor?: number; | ||
@@ -65,17 +68,17 @@ /** WebSocket subprotocols. */ | ||
| queryParams?: Record<string, string>; | ||
| /** Enable internal ping/pong heartbeat. Default `true`. */ | ||
| /** Enable internal ping/pong heartbeat. @default true */ | ||
| heartbeatEnabled?: boolean; | ||
| /** Interval between ping messages in ms. Default `25000`. */ | ||
| /** Interval between ping messages in ms. @default 25000 */ | ||
| pingInterval?: number; | ||
| /** Time to wait for pong response before closing connection. Default `20000`. */ | ||
| /** Time to wait for pong response before closing connection. @default 20000 */ | ||
| pingTimeout?: number; | ||
| /** Authentication configuration. */ | ||
| auth?: AuthConfig; | ||
| /** Timeout for authentication response in ms. Default `5000`. */ | ||
| /** Timeout for authentication response in ms. @default 5000 */ | ||
| authTimeout?: number; | ||
| /** Maximum number of outgoing messages to queue while offline. Default `100`. */ | ||
| /** Maximum number of outgoing messages to queue while offline. @default 100 */ | ||
| maxQueueSize?: number; | ||
| /** Serialization format: `"json"` or `"binary"` (msgpack). Default `"binary"`. */ | ||
| /** Serialization format: `"json"` or `"binary"` (msgpack). @default "binary" */ | ||
| serialization?: "json" | "binary"; | ||
| /** Enable debug logging to console. Default `false`. */ | ||
| /** Enable debug logging to console. @default false */ | ||
| debug?: boolean; | ||
@@ -99,21 +102,11 @@ /** Options passed directly to the underlying msgpackr Packr instance. */ | ||
| protected onceLifecycleCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>; | ||
| /** | ||
| * Adds a callback to a given event in the provided map. | ||
| */ | ||
| /** Adds a callback to a given event in the provided map. */ | ||
| protected addCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callback: EventCallback<D>): void; | ||
| /** | ||
| * Registers a one‑time callback by storing the wrapper in a separate map. | ||
| */ | ||
| /** Registers a one‑time callback by storing the wrapper in a separate map. */ | ||
| protected addOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void; | ||
| /** | ||
| * Removes a callback from an event map. | ||
| */ | ||
| /** Removes a callback from an event map. */ | ||
| protected deleteCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callbackWrapper: EventCallback<D>): void; | ||
| /** | ||
| * Removes a one‑time callback and its associated wrapper. | ||
| */ | ||
| /** Removes a one‑time callback and its associated wrapper. */ | ||
| protected deleteOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void; | ||
| /** | ||
| * Registers a permanent listener for a lifecycle event. | ||
| */ | ||
| /** Registers a permanent listener for a lifecycle event. */ | ||
| protected onLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void; | ||
@@ -130,5 +123,3 @@ /** | ||
| protected onceLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void; | ||
| /** | ||
| * Safely invokes a set of callbacks, catching and logging errors if debug is enabled. | ||
| */ | ||
| /** Safely invokes a set of callbacks, catching and logging errors if debug is enabled. */ | ||
| protected triggerCallback<Args extends Array<unknown>>(callbackWrappers?: Set<AnyCallback>, ...args: Args): void; | ||
@@ -406,16 +397,48 @@ } | ||
| * | ||
| * @example | ||
| * // Define your event schema | ||
| * interface MyEvents extends SocketEvents<{ | ||
| * emit: { ping: void }; | ||
| * listen: { pong: number }; | ||
| * @example Symmetric events (most common) | ||
| * ```ts | ||
| * // Define your event map | ||
| * type MyEvents = SocketEvents<{ | ||
| * "chat:message": { text: string }; | ||
| * "user:joined": { userId: string }; | ||
| * }>; | ||
| * | ||
| * // Create a typed socket instance | ||
| * const socket = new ByteSocket<MyEvents>('wss://example.com/socket', { | ||
| * debug: true, | ||
| * auth: { token: 'abc123' } | ||
| * }); | ||
| * | ||
| * // Use typed methods (emit and listen share the same event map) | ||
| * socket.emit('chat:message', { text: 'Hello!' }); | ||
| * socket.on('user:joined', (data) => console.log(data.userId)); | ||
| * | ||
| * socket.rooms.join('lobby'); | ||
| * socket.rooms.emit('lobby', 'chat:message', { text: 'Hi everyone' }); | ||
| * socket.rooms.on('lobby', 'chat:message', (data) => { | ||
| * console.log(`Message: ${data.text}`); | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @example Asymmetric events (full control via interface extension) | ||
| * ```ts | ||
| * // Extend SocketEvents to differentiate emit/listen/room maps | ||
| * interface MyEvents extends SocketEvents { | ||
| * emit: { | ||
| * "message:send": { text: string }; | ||
| * "ping": void; | ||
| * }; | ||
| * listen: { | ||
| * "message:receive": { text: string; sender: string }; | ||
| * "pong": number; | ||
| * }; | ||
| * emitRoom: { | ||
| * chat: { message: string }; | ||
| * chat: { "message": { text: string } }; | ||
| * dm: { "message": { text: string; recipient: string } }; | ||
| * }; | ||
| * listenRoom: { | ||
| * chat: { message: string; sender: string }; | ||
| * chat: { "message": { text: string; sender: string } }; | ||
| * }; | ||
| * }> {} | ||
| * } | ||
| * | ||
| * // Create a typed socket instance | ||
| * const socket = new ByteSocket<MyEvents>('wss://example.com/socket', { | ||
@@ -426,11 +449,13 @@ * debug: true, | ||
| * | ||
| * // Use typed methods | ||
| * // Global emits/listens | ||
| * socket.emit('ping', undefined); | ||
| * socket.on('pong', (timestamp) => console.log(timestamp)); | ||
| * socket.on('message:receive', (data) => console.log(`${data.sender}: ${data.text}`)); | ||
| * | ||
| * // Room‑specific emits/listens | ||
| * socket.rooms.join('chat'); | ||
| * socket.rooms.emit('chat', 'message', { message: 'Hello!' }); | ||
| * socket.rooms.emit('chat', 'message', { text: 'Hello!' }); | ||
| * socket.rooms.on('chat', 'message', (data) => { | ||
| * console.log(`${data.sender}: ${data.message}`); | ||
| * console.log(`${data.sender}: ${data.text}`); | ||
| * }); | ||
| * ``` | ||
| */ | ||
@@ -448,86 +473,55 @@ declare class ByteSocket<TEvents extends SocketEvents = SocketEvents> extends SocketBase { | ||
| readonly lifecycle: { | ||
| /** Register a listener for socket open. */ | ||
| onOpen: (callback: () => void) => void; | ||
| /** Remove a listener for socket open. */ | ||
| offOpen: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for socket open. */ | ||
| onceOpen: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for socket open. | ||
| * Register a listener for raw incoming WebSocket messages. | ||
| * Called immediately when a message is received, before any internal processing. | ||
| * | ||
| * @param callback - Receives the raw data and a boolean indicating if it's binary. | ||
| */ | ||
| readonly onOpen: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for socket open. | ||
| */ | ||
| readonly offOpen: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for socket open. | ||
| */ | ||
| readonly onceOpen: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for socket close. | ||
| */ | ||
| readonly onClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** | ||
| * Remove a listener for socket close. | ||
| */ | ||
| readonly offClose: (callback?: (event: CloseEvent) => void) => void; | ||
| /** | ||
| * Register a one‑time listener for socket close. | ||
| */ | ||
| readonly onceClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** | ||
| * Register a listener for WebSocket errors. | ||
| */ | ||
| readonly onError: (callback: (event: Event) => void) => void; | ||
| /** | ||
| * Remove a listener for WebSocket errors. | ||
| */ | ||
| readonly offError: (callback?: (event: Event) => void) => void; | ||
| /** | ||
| * Register a one‑time listener for WebSocket errors. | ||
| */ | ||
| readonly onceError: (callback: (event: Event) => void) => void; | ||
| /** | ||
| * Register a listener for authentication success. | ||
| */ | ||
| readonly onAuthSuccess: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for authentication success. | ||
| */ | ||
| readonly offAuthSuccess: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for authentication success. | ||
| */ | ||
| readonly onceAuthSuccess: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for authentication errors. | ||
| */ | ||
| readonly onAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** | ||
| * Remove a listener for authentication errors. | ||
| */ | ||
| readonly offAuthError: (callback?: (ctx: ErrorContext) => void) => void; | ||
| /** | ||
| * Register a one‑time listener for authentication errors. | ||
| */ | ||
| readonly onceAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** | ||
| * Register a listener for when the message queue becomes full and a message is dropped. | ||
| */ | ||
| readonly onQueueFull: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for queue‑full events. | ||
| */ | ||
| readonly offQueueFull: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for queue‑full events. | ||
| */ | ||
| readonly onceQueueFull: (callback: () => void) => void; | ||
| /** | ||
| * Register a listener for when reconnection fails after all attempts. | ||
| */ | ||
| readonly onReconnectFailed: (callback: () => void) => void; | ||
| /** | ||
| * Remove a listener for reconnect‑failed events. | ||
| */ | ||
| readonly offReconnectFailed: (callback?: () => void) => void; | ||
| /** | ||
| * Register a one‑time listener for reconnect‑failed events. | ||
| */ | ||
| readonly onceReconnectFailed: (callback: () => void) => void; | ||
| onMessage: (callback: (data: string | ArrayBuffer) => void) => void; | ||
| /** Remove a listener for raw messages. */ | ||
| offMessage: (callback?: (data: string | ArrayBuffer) => void) => void; | ||
| /** Register a one‑time listener for raw incoming WebSocket messages. */ | ||
| onceMessage: (callback: (data: string | ArrayBuffer) => void) => void; | ||
| /** Register a listener for socket close. */ | ||
| onClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** Remove a listener for socket close. */ | ||
| offClose: (callback?: (event: CloseEvent) => void) => void; | ||
| /** Register a one‑time listener for socket close. */ | ||
| onceClose: (callback: (event: CloseEvent) => void) => void; | ||
| /** Register a listener for WebSocket errors. */ | ||
| onError: (callback: (event: Event) => void) => void; | ||
| /** Remove a listener for WebSocket errors. */ | ||
| offError: (callback?: (event: Event) => void) => void; | ||
| /** Register a one‑time listener for WebSocket errors. */ | ||
| onceError: (callback: (event: Event) => void) => void; | ||
| /** Register a listener for authentication success. */ | ||
| onAuthSuccess: (callback: () => void) => void; | ||
| /** Remove a listener for authentication success. */ | ||
| offAuthSuccess: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for authentication success. */ | ||
| onceAuthSuccess: (callback: () => void) => void; | ||
| /** Register a listener for authentication errors. */ | ||
| onAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** Remove a listener for authentication errors. */ | ||
| offAuthError: (callback?: (ctx: ErrorContext) => void) => void; | ||
| /** Register a one‑time listener for authentication errors. */ | ||
| onceAuthError: (callback: (ctx: ErrorContext) => void) => void; | ||
| /** Register a listener for when the message queue becomes full and a message is dropped. */ | ||
| onQueueFull: (callback: () => void) => void; | ||
| /** Remove a listener for queue‑full events. */ | ||
| offQueueFull: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for queue‑full events. */ | ||
| onceQueueFull: (callback: () => void) => void; | ||
| /** Register a listener for when reconnection fails after all attempts. */ | ||
| onReconnectFailed: (callback: () => void) => void; | ||
| /** Remove a listener for reconnect‑failed events. */ | ||
| offReconnectFailed: (callback?: () => void) => void; | ||
| /** Register a one‑time listener for reconnect‑failed events. */ | ||
| onceReconnectFailed: (callback: () => void) => void; | ||
| }; | ||
@@ -556,3 +550,57 @@ /** | ||
| /** | ||
| * Send a raw message (string, Blob, or BufferSource) directly over the WebSocket. | ||
| * Whether the socket is currently able to send messages. | ||
| * Returns `true` if the WebSocket is open and authentication (if configured) has succeeded. | ||
| * Useful for checking readiness before calling `sendRaw()` | ||
| * No need to use it with `emit()` or `send()` because they already use it under the hood. | ||
| * | ||
| * @example | ||
| * if (socket.canSend) { | ||
| * socket.sendRaw('PROTOCOL: custom-v1'); | ||
| * } | ||
| */ | ||
| get canSend(): boolean; | ||
| /** | ||
| * Encode a structured payload into a format suitable for sending over the WebSocket. | ||
| * Uses the configured serialization (`"json"` or `"binary"`). | ||
| * | ||
| * **Advanced usage only.** Prefer `emit()` or `send()` for type‑safe communication. | ||
| * | ||
| * @param payload - A lifecycle message or user event object. | ||
| * @returns Encoded string (JSON) or Uint8Array (MessagePack). | ||
| * | ||
| * @example | ||
| * // Pre‑encode a payload for repeated use | ||
| * const encoded = socket.encode({ event: 'chat', data: { text: 'Hello' } }); | ||
| * socket.sendRaw(encoded); | ||
| */ | ||
| encode<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): any; | ||
| /** | ||
| * Decode a raw WebSocket message into a structured payload. | ||
| * Automatically detects JSON or MessagePack based on the binary flag and message content. | ||
| * | ||
| * **Advanced usage only.** Normally you should use `on()` listeners to receive typed data. | ||
| * | ||
| * @param message - Raw string (JSON) or Uint8Array (MessagePack). | ||
| * @param isBinary - Whether the message is binary. If omitted, format is detected from the message type. | ||
| * @returns Decoded lifecycle or user message object. | ||
| */ | ||
| decode(message: string | ArrayBuffer, isBinary?: boolean): any; | ||
| /** | ||
| * Send a pre‑serialized payload (LifecycleMessage or UserMessage) over the WebSocket. | ||
| * If the socket is not ready, the payload is queued and sent when the connection | ||
| * becomes operational and authentication (if required) has succeeded. | ||
| * | ||
| * @param payload - The structured payload to encode and send. | ||
| * | ||
| * @example | ||
| * // Send a custom lifecycle message (advanced) | ||
| * socket.send({ type: LifecycleTypes.ping }); | ||
| * | ||
| * @example | ||
| * // Send a raw user event (equivalent to socket.emit('chat', data)) | ||
| * socket.send({ event: 'chat', data: { text: 'Hello' } }); | ||
| */ | ||
| send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void; | ||
| /** | ||
| * Send a raw message (string or BufferSource) directly over the WebSocket. | ||
| * Bypasses serialization and auth checks. If the socket is not open, the message | ||
@@ -563,3 +611,3 @@ * is queued and sent when possible (auth state is ignored). | ||
| */ | ||
| sendRaw(message: string | Blob | BufferSource): void; | ||
| sendRaw(message: string | BufferSource): void; | ||
| /** | ||
@@ -632,4 +680,4 @@ * Emit a global event. | ||
| * | ||
| * @param code - Close code (default none). | ||
| * @param reason - Close reason (default none). | ||
| * @param code - Close code. @default undefined | ||
| * @param reason - Close reason. @default undefined | ||
| */ | ||
@@ -636,0 +684,0 @@ close(code?: number, reason?: string): void; |
+2
-2
| { | ||
| "name": "@bytesocket/client", | ||
| "version": "0.1.7", | ||
| "version": "0.1.8", | ||
| "description": "High-performance WebSocket client for browsers", | ||
@@ -45,3 +45,3 @@ "keywords": [ | ||
| "msgpackr": "1.11.10", | ||
| "@bytesocket/types": "0.1.7" | ||
| "@bytesocket/types": "0.1.8" | ||
| }, | ||
@@ -48,0 +48,0 @@ "engines": { |
+99
-24
| # ByteSocket | ||
| A modern WebSocket client for [ByteSocket](https://github.com/a7med3ouda/bytesocket/tree/main/packages/client) with automatic reconnection, room management, authentication, heartbeat, and pluggable serialization — fully typed with TypeScript. | ||
| A modern WebSocket client for [ByteSocket](https://github.com/a7med3ouda/bytesocket/tree/main/packages/client) with automatic reconnection, room management, authentication, heartbeat, and pluggable serialization -- fully typed with TypeScript. | ||
@@ -18,8 +18,8 @@ ```bash | ||
| - **Automatic reconnection** with exponential backoff and jitter | ||
| - **Room management** — join/leave rooms, scoped event listeners, bulk operations | ||
| - **Authentication** — static or async token injection with timeout | ||
| - **Heartbeat** — configurable ping/pong keepalive | ||
| - **Message queue** — outgoing messages are buffered while offline and flushed on reconnect | ||
| - **Dual serialization** — JSON or binary MessagePack (`msgpackr`) out of the box | ||
| - **Fully typed** — generic event maps for compile-time safety on all emit/listen calls | ||
| - **Room management** -- join/leave rooms, scoped event listeners, bulk operations | ||
| - **Authentication** -- static or async token injection with timeout | ||
| - **Heartbeat** -- configurable ping/pong keepalive | ||
| - **Message queue** -- outgoing messages are buffered while offline and flushed on reconnect | ||
| - **Dual serialization** -- JSON or binary MessagePack (`msgpackr`) out of the box | ||
| - **Fully typed** -- generic event maps for compile-time safety on all emit/listen calls | ||
| - **Zero runtime dependencies** beyond `msgpackr` (for binary mode) | ||
@@ -56,11 +56,41 @@ | ||
| Define your event schema once and get full inference everywhere: | ||
| Define your event schema once and get full inference everywhere. You can use **symmetric events** (emit and listen share the same map) or **asymmetric events** (full control via interface extension). | ||
| ### Symmetric usage (most common) | ||
| Use `SocketEvents<T>` directly with a single event map: | ||
| ```typescript | ||
| import { ByteSocket, SocketEvents } from "@bytesocket/client"; | ||
| export type MyEvents = SocketEvents<{ | ||
| type MyEvents = SocketEvents<{ | ||
| "chat:message": { text: string }; | ||
| "user:joined": { userId: string }; | ||
| }>; | ||
| const socket = new ByteSocket<MyEvents>("wss://example.com/socket"); | ||
| // Emit and listen share the same typed events | ||
| socket.emit("chat:message", { text: "Hello!" }); | ||
| socket.on("user:joined", (data) => console.log(data.userId)); | ||
| // Rooms also use the same map | ||
| socket.rooms.join("lobby"); | ||
| socket.rooms.emit("lobby", "chat:message", { text: "Hi room!" }); | ||
| socket.rooms.on("lobby", "chat:message", (data) => { | ||
| console.log(`Message: ${data.text}`); | ||
| }); | ||
| ``` | ||
| ### Asymmetric usage (full control) | ||
| Extend `SocketEvents` and override specific properties to differentiate emit/listen/room maps: | ||
| ```typescript | ||
| import { ByteSocket, SocketEvents } from "@bytesocket/client"; | ||
| interface MyEvents extends SocketEvents { | ||
| emit: { | ||
| "user:message": { text: string }; | ||
| "user:typing": { userId: string }; | ||
| "room:created": { roomId: string }; | ||
| }; | ||
@@ -81,13 +111,19 @@ listen: { | ||
| }; | ||
| }>; | ||
| } | ||
| const socket = new ByteSocket<MyEvents>("wss://example.com/socket"); | ||
| // All of these are fully typed — wrong event names or payload shapes are compile errors | ||
| socket.emit("user:message", { text: "Hello!" }); | ||
| socket.on("user:joined", (data) => console.log(data.name)); // data is typed | ||
| socket.rooms.emit("chat", "message", { text: "Hi room!" }); | ||
| socket.rooms.on("chat", "message", (data) => console.log(data.sender)); | ||
| // Global emits/listens | ||
| socket.emit("room:created", { roomId: "abc" }); | ||
| socket.on("user:joined", (data) => console.log(data.name)); | ||
| // Room‑specific emits/listens (different maps per room) | ||
| socket.rooms.emit("chat", "message", { text: "Hello!" }); | ||
| socket.rooms.on("chat", "message", (data) => { | ||
| console.log(`${data.sender}: ${data.text}`); | ||
| }); | ||
| ``` | ||
| All methods (`emit`, `on`, `off`, `once`, `rooms.emit`, `rooms.on`, etc.) are fully typed -- wrong event names or payload shapes become compile‑time errors. | ||
| --- | ||
@@ -112,5 +148,5 @@ | ||
| const socket = new ByteSocket("wss://example.com/socket", { | ||
| auth: async (cb) => { | ||
| auth: async (callback) => { | ||
| const { token } = await fetch("/api/token").then((r) => r.json()); | ||
| cb({ token }); | ||
| callback({ token }); | ||
| }, | ||
@@ -121,3 +157,3 @@ authTimeout: 8000, // ms to wait for server to confirm auth | ||
| > When auth is configured, `onOpen` fires only after the server confirms authentication — your callbacks and queued messages are safe. | ||
| > When auth is configured, `onOpen` fires only after the server confirms authentication -- your callbacks and queued messages are safe. | ||
@@ -211,2 +247,3 @@ --- | ||
| randomizationFactor: 0.5, // ±50% jitter | ||
| reconnectOnNormalClosure: true, // default true – reconnect after server sends 1000/1001 | ||
| }); | ||
@@ -219,2 +256,6 @@ | ||
| ### reconnectOnNormalClosure | ||
| By default, ByteSocket will attempt to reconnect even when the server closes the connection gracefully (close codes `1000` or `1001`). This is useful when the server restarts or a load balancer terminates the connection for maintenance. Set `reconnectOnNormalClosure: false` to disable reconnection for normal closures. | ||
| ### Manual reconnect | ||
@@ -229,3 +270,3 @@ | ||
| Rooms you joined are automatically re-joined after reconnection — no extra code needed. The server is assumed to clear room membership on disconnect, and ByteSocket handles the rejoin handshake transparently. | ||
| Rooms you joined are automatically re-joined after reconnection -- no extra code needed. The server is assumed to clear room membership on disconnect, and ByteSocket handles the rejoin handshake transparently. | ||
@@ -260,3 +301,3 @@ --- | ||
| socket.lifecycle.onQueueFull(() => { | ||
| console.warn("Queue full — some messages will be dropped"); | ||
| console.warn("Queue full -- some messages will be dropped"); | ||
| }); | ||
@@ -270,3 +311,3 @@ ``` | ||
| ```typescript | ||
| // Binary (default) — uses msgpackr, smaller payloads | ||
| // Binary (default) -- uses msgpackr, smaller payloads | ||
| const socket = new ByteSocket("wss://example.com/socket", { | ||
@@ -276,3 +317,3 @@ serialization: "binary", | ||
| // JSON — plain text, easier to inspect | ||
| // JSON -- plain text, easier to inspect | ||
| const socket = new ByteSocket("wss://example.com/socket", { | ||
@@ -297,2 +338,30 @@ serialization: "json", | ||
| ## Advanced: Manual Serialization | ||
| If you need to inspect, pre‑encode, or bypass the automatic serialization, you can use the `encode()` and `decode()` methods. | ||
| > ⚠️ **These are advanced APIs.** Prefer `emit()` and `on()` for type‑safe, automatic encoding/decoding. | ||
| ```typescript | ||
| // Encode a structured payload (returns a string or Uint8Array) | ||
| const encoded = socket.encode({ event: "chat", data: { text: "Hello" } }); | ||
| socket.sendRaw(encoded); | ||
| // Decode a raw incoming message (auto‑detects format) | ||
| socket.lifecycle.onMessage((raw) => { | ||
| const decoded = socket.decode(raw); | ||
| console.log("Decoded message:", decoded); | ||
| }); | ||
| // You can also pass the binary flag explicitly | ||
| const decoded = socket.decode(someArrayBuffer, true); | ||
| ``` | ||
| - `encode(payload)` – uses the configured `serialization` (`"json"` or `"binary"`). Returns a `string` (JSON) or `Uint8Array` (MessagePack). | ||
| - `decode(message, isBinary?)` – parses a raw WebSocket message back into an object. If `isBinary` is omitted, the format is auto‑detected. | ||
| These methods give you full control when integrating with external systems or debugging the wire format. | ||
| --- | ||
| ## URL Options | ||
@@ -352,2 +421,7 @@ | ||
| // Raw incoming message (before parsing) | ||
| socket.lifecycle.onMessage((raw) => { | ||
| console.log("Raw message received", raw); | ||
| }); | ||
| // Queue | ||
@@ -412,2 +486,3 @@ socket.lifecycle.onQueueFull(() => {}); | ||
| reconnectionDelayMax: 5000, | ||
| reconnectOnNormalClosure: true, // default true – reconnect after server‑initiated 1000/1001 | ||
| randomizationFactor: 0.5, // 0 = no jitter, 1 = maximum jitter | ||
@@ -421,3 +496,3 @@ | ||
| // Auth | ||
| auth: { token: "abc" }, // or async (cb) => cb(data) | ||
| auth: { token: "abc" }, // or async (callback) => callback(data) | ||
| authTimeout: 5000, | ||
@@ -424,0 +499,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
464812
6.55%3714
2.71%514
17.08%17
750%+ Added
- Removed
Updated