{"version":3,"sources":["../src/backoff.ts","../src/codec.ts","../src/fsm.ts","../src/heartbeat.ts","../src/helpers/event-bus.ts","../src/pipeline.ts","../src/queue.ts","../src/schema.ts","../src/client.ts","../src/middleware.ts","../src/index.ts"],"names":["promise"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ReconnectOptions } from \"@/types\";\n\n/** `ReconnectOptions` with every field filled in. */\nexport type ResolvedReconnect = Required<ReconnectOptions>;\n\n/**\n * The durable-by-default reconnection policy: full-jitter exponential backoff,\n * never give up. See the RFC's M3 decisions for the rationale behind each value.\n */\nexport const RECONNECT_DEFAULTS: ResolvedReconnect = {\n    baseDelay: 500,\n    factor: 2,\n    maxDelay: 30_000,\n    jitter: true,\n    maxRetries: Number.POSITIVE_INFINITY,\n    shouldReconnect: () => true\n};\n\n/**\n * Resolve the user's `reconnect` config: `false` disables reconnection\n * entirely (`null`), anything else is merged over the defaults.\n */\nexport function resolveReconnect(\n    option: false | ReconnectOptions | undefined\n): ResolvedReconnect | null {\n    if (option === false) {\n        return null;\n    }\n    return { ...RECONNECT_DEFAULTS, ...option };\n}\n\n/**\n * Compute the backoff delay for a retry.\n *\n * The exponential delay is `baseDelay × factorᵃᵗᵗᵉᵐᵖᵗ`, capped at `maxDelay`.\n * With jitter (the default), the actual delay is drawn uniformly from\n * `[0, exponential]` — \"full jitter\", which spreads a fleet of simultaneously\n * dropped clients across the whole window instead of letting them retry in\n * synchronized waves.\n *\n * @param attempt - 0-based: the first retry is attempt `0`.\n * @param random - injectable for deterministic tests; defaults to `Math.random`.\n */\nexport function computeDelay(\n    attempt: number,\n    options: ResolvedReconnect,\n    random: () => number = Math.random\n): number {\n    const exponential = Math.min(\n        options.maxDelay,\n        options.baseDelay * options.factor ** attempt\n    );\n    return options.jitter ? random() * exponential : exponential;\n}\n","import type { Codec } from \"@/types\";\n\n/**\n * Parse a string as JSON, falling back to the raw string when it isn't valid\n * JSON. Lets text protocols that mix JSON and plain strings work unchanged.\n */\nfunction safeJSONParse(data: string): unknown {\n    try {\n        return JSON.parse(data);\n    } catch {\n        return data;\n    }\n}\n\n/**\n * Whether a value is already a WebSocket-sendable binary frame and should be\n * passed through rather than JSON-encoded (`ArrayBuffer`, any typed array or\n * `DataView`, or a `Blob`).\n *\n * The predicate claims `BufferSource` (what `WebSocket.send` accepts), which\n * asserts the view is not backed by a `SharedArrayBuffer` — `send` rejects\n * those at runtime, so they were never sendable anyway.\n */\nfunction isBinary(data: unknown): data is BufferSource | Blob {\n    return (\n        data instanceof ArrayBuffer ||\n        ArrayBuffer.isView(data) ||\n        (typeof Blob !== \"undefined\" && data instanceof Blob)\n    );\n}\n\n/**\n * The default codec: JSON over text frames, binary passed through.\n *\n * - `encode` — strings and binary frames (`ArrayBuffer`/typed arrays/`Blob`)\n *   are sent verbatim; everything else is `JSON.stringify`d.\n * - `decode` — text frames are JSON-parsed (falling back to the raw string);\n *   binary frames are passed through untouched.\n */\nexport const jsonCodec: Codec = {\n    encode(data: unknown) {\n        if (typeof data === \"string\" || isBinary(data)) {\n            return data;\n        }\n        return JSON.stringify(data);\n    },\n    decode(data: unknown) {\n        return typeof data === \"string\" ? safeJSONParse(data) : data;\n    }\n};\n","import type { ConnectionEvent, ConnectionState } from \"@/types\";\n\n/**\n * The connection lifecycle as an explicit finite state machine.\n *\n * A connection has a small, fixed set of legal states and transitions. Modelling\n * it as a table — rather than a free-form reducer — means an illegal transition\n * (e.g. a `CLOSED` event arriving while already `closed`) is *representable as the\n * absence of an entry* and can be rejected, instead of silently doing nothing.\n * That silent no-op is exactly what allowed the original close/error bug.\n *\n * `ERROR` is deliberately absent from the table: a transport error does not by\n * itself change the connection state (the browser/runtime fires `error` and then\n * `close`), so it is handled out-of-band by the client (record + emit) and the\n * following `CLOSED` event performs the actual transition.\n */\nconst TRANSITIONS: Record<\n    ConnectionState,\n    Partial<Record<ConnectionEvent, ConnectionState>>\n> = {\n    idle: { CONNECT: \"connecting\" },\n    connecting: {\n        OPEN: \"open\",\n        CLOSE_REQUESTED: \"closing\",\n        CLOSED: \"closed\",\n        RETRY: \"reconnecting\"\n    },\n    open: {\n        CLOSE_REQUESTED: \"closing\",\n        CLOSED: \"closed\",\n        RETRY: \"reconnecting\"\n    },\n    closing: { CLOSED: \"closed\" },\n    // `reconnecting` = waiting out the backoff delay; no socket exists, so\n    // CLOSE_REQUESTED goes straight to `closed` (there is nothing to wait for)\n    // and OPEN/CLOSED cannot legally occur.\n    reconnecting: {\n        CONNECT: \"connecting\",\n        CLOSE_REQUESTED: \"closed\"\n    },\n    closed: { CONNECT: \"connecting\" }\n};\n\n/**\n * Resolve the next state for an `(state, event)` pair.\n *\n * @returns the destination state, or `null` if the transition is illegal.\n */\nexport function nextState(\n    state: ConnectionState,\n    event: ConnectionEvent\n): ConnectionState | null {\n    return TRANSITIONS[state][event] ?? null;\n}\n\n/**\n * Whether `(state, event)` is a legal transition.\n */\nexport function canTransition(\n    state: ConnectionState,\n    event: ConnectionEvent\n): boolean {\n    return nextState(state, event) !== null;\n}\n","import type { HeartbeatOptions } from \"@/types\";\n\n/** `HeartbeatOptions` with every field filled in. */\nexport interface ResolvedHeartbeat {\n    readonly interval: number;\n    readonly message: unknown;\n    readonly timeout: number;\n}\n\n/**\n * The close code used when the heartbeat declares the link dead (app-reserved\n * 4xxx range, mnemonic for HTTP 408 Request Timeout). Useful in a custom\n * `shouldReconnect` to distinguish heartbeat closes from server closes.\n */\nexport const HEARTBEAT_TIMEOUT_CODE = 4408;\n\n/**\n * Resolve the user's `heartbeat` config. Heartbeat is **opt-in**: absence means\n * off (`null`) — a naive \"no traffic → reconnect\" would kill legitimately\n * quiet-but-healthy connections, and any ping depends on app-level semantics\n * the library can't assume (see the RFC's M3 decisions).\n */\nexport function resolveHeartbeat(\n    option: HeartbeatOptions | undefined\n): ResolvedHeartbeat | null {\n    if (option === undefined) {\n        return null;\n    }\n    return {\n        interval: option.interval,\n        message: option.message ?? \"ping\",\n        timeout: option.timeout ?? option.interval\n    };\n}\n","import type { EventBus } from \"@/types\";\n\n/**\n * Creates an event bus for managing event subscriptions and emissions.\n * Provides a simple pub/sub pattern with type-safe event handling.\n *\n * @returns EventBus instance with on, off, emit, and once methods\n *\n * @example\n * ```typescript\n * const eventBus = defineEventBus();\n *\n * // Subscribe to events\n * eventBus.on('user-login', (user) => {\n *   console.log('User logged in:', user);\n * });\n *\n * // Emit events\n * eventBus.emit('user-login', { id: 1, name: 'John' });\n *\n * // One-time subscription\n * eventBus.once('app-ready', () => {\n *   console.log('App is ready!');\n * });\n * ```\n */\nexport function defineEventBus(): EventBus {\n    const listeners = new Map<string, Array<(payload: unknown) => void>>();\n\n    /**\n     * Subscribes to an event with a handler function.\n     *\n     * @template T - The type of the event payload\n     * @param eventName - The name of the event to listen for\n     * @param handler - Function to call when the event is emitted\n     */\n    function on<T = unknown>(\n        eventName: string,\n        handler: (payload: T) => void\n    ): void {\n        const handlers = listeners.get(eventName) ?? [];\n        handlers.push(handler as (payload: unknown) => void);\n        listeners.set(eventName, handlers);\n    }\n\n    /**\n     * Unsubscribes a handler from an event.\n     *\n     * @template T - The type of the event payload\n     * @param eventName - The name of the event to stop listening for\n     * @param handler - The handler function to remove\n     */\n    function off<T = unknown>(\n        eventName: string,\n        handler: (payload: T) => void\n    ) {\n        const handlers = listeners.get(eventName);\n        if (!handlers) {\n            return;\n        }\n        listeners.set(\n            eventName,\n            handlers.filter((h) => h !== handler)\n        );\n    }\n\n    /**\n     * Subscribes to an event with a handler that will only be called once.\n     * The handler is automatically removed after the first emission.\n     *\n     * @template T - The type of the event payload\n     * @param eventName - The name of the event to listen for\n     * @param handler - Function to call when the event is emitted (only once)\n     */\n    function once<T = unknown>(\n        eventName: string,\n        handler: (payload: T) => void\n    ): void {\n        const onceHandler = (payload: T) => {\n            // Remove the handler after first invocation\n            off(eventName, onceHandler as (payload: unknown) => void);\n            // Call the original handler\n            handler(payload);\n        };\n\n        // Add the wrapper handler\n        on(eventName, onceHandler);\n    }\n\n    /**\n     * Emits an event to all subscribed handlers.\n     *\n     * @template T - The type of the event payload\n     * @param eventName - The name of the event to emit\n     * @param payload - The data to pass to event handlers\n     */\n    function emit<T = unknown>(eventName: string, payload?: T) {\n        const handlers = listeners.get(eventName);\n        handlers?.forEach((fn) => {\n            fn(payload);\n        });\n    }\n\n    return { on, off, emit, once };\n}\n","/**\n * The functional shape shared by inbound and outbound middleware: receive a\n * context and a `next`, optionally async. The context type is the only thing\n * that differs per direction.\n */\ntype PipelineMiddleware<TContext> = (\n    ctx: TContext,\n    next: () => void | Promise<void>\n) => void | Promise<void>;\n\n/**\n * Runs a message through a middleware chain (onion model).\n *\n * Each middleware receives the shared context and a `next` it may call to pass\n * control onward. When the chain runs to completion, `terminal` is invoked —\n * for inbound messages that is where the client emits `message`; for outbound,\n * where it encodes and writes to the socket. A middleware that returns without\n * calling `next()` short-circuits the chain (and `terminal`).\n *\n * Mirrors the guard from the old store pipeline: calling `next()` more than once\n * in a single middleware is a bug and throws.\n *\n * @returns `void`, or a `Promise` if any middleware in the chain is async.\n */\nexport function runPipeline<TContext>(\n    middlewares: readonly PipelineMiddleware<TContext>[],\n    ctx: TContext,\n    terminal: () => void\n): void | Promise<void> {\n    let invoked = -1;\n\n    function dispatch(i: number): void | Promise<void> {\n        if (i <= invoked) {\n            throw new Error(\"next() called multiple times\");\n        }\n        invoked = i;\n\n        const middleware = middlewares[i];\n        if (!middleware) {\n            return terminal();\n        }\n        return middleware(ctx, () => dispatch(i + 1));\n    }\n\n    return dispatch(0);\n}\n","import type { QueueOptions } from \"@/types\";\n\n/** `QueueOptions` with every field filled in. */\nexport type ResolvedQueue = Required<QueueOptions>;\n\n/**\n * The default outbound-queue policy: bounded at 256 messages, drop-oldest.\n * Never silently unbounded (a memory leak), never silently lossy (every drop\n * emits a `drop` event). See the RFC's M3 decisions.\n */\nexport const QUEUE_DEFAULTS: ResolvedQueue = {\n    maxSize: 256\n};\n\n/**\n * Resolve the user's `queue` config: `false` disables queueing entirely\n * (`null`), anything else is merged over the defaults.\n */\nexport function resolveQueue(\n    option: false | QueueOptions | undefined\n): ResolvedQueue | null {\n    if (option === false) {\n        return null;\n    }\n    return { ...QUEUE_DEFAULTS, ...option };\n}\n","/**\n * The Standard Schema v1 interface (https://standardschema.dev), vendored as\n * types-only per the spec's guidance — implementing libraries (zod, valibot,\n * arktype, …) conform to this shape, so DurableWS can accept any of them\n * without depending on any of them. Keeps core zero-dependency.\n */\nexport interface StandardSchemaV1<Input = unknown, Output = Input> {\n    readonly \"~standard\": StandardSchemaV1.Props<Input, Output>;\n}\n\nexport declare namespace StandardSchemaV1 {\n    export interface Props<Input = unknown, Output = Input> {\n        readonly version: 1;\n        readonly vendor: string;\n        readonly validate: (\n            value: unknown\n        ) => Result<Output> | Promise<Result<Output>>;\n        readonly types?: Types<Input, Output> | undefined;\n    }\n\n    export type Result<Output> = SuccessResult<Output> | FailureResult;\n\n    export interface SuccessResult<Output> {\n        readonly value: Output;\n        readonly issues?: undefined;\n    }\n\n    export interface FailureResult {\n        readonly issues: ReadonlyArray<Issue>;\n    }\n\n    export interface Issue {\n        readonly message: string;\n        readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;\n    }\n\n    export interface PathSegment {\n        readonly key: PropertyKey;\n    }\n\n    export interface Types<Input = unknown, Output = Input> {\n        readonly input: Input;\n        readonly output: Output;\n    }\n\n    export type InferInput<Schema extends StandardSchemaV1> = NonNullable<\n        Schema[\"~standard\"][\"types\"]\n    >[\"input\"];\n\n    export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<\n        Schema[\"~standard\"][\"types\"]\n    >[\"output\"];\n}\n\n/**\n * Thrown (as an `error` event payload) when an inbound message fails the\n * configured schema. The message is **not** emitted — handlers only ever see\n * data that passed validation.\n */\nexport class SchemaValidationError extends Error {\n    readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;\n\n    constructor(issues: ReadonlyArray<StandardSchemaV1.Issue>) {\n        super(\n            `Inbound message failed schema validation: ${issues\n                .map((issue) => issue.message)\n                .join(\"; \")}`\n        );\n        this.name = \"SchemaValidationError\";\n        this.issues = issues;\n    }\n}\n","import { computeDelay, resolveReconnect } from \"@/backoff\";\nimport { jsonCodec } from \"@/codec\";\nimport { nextState } from \"@/fsm\";\nimport { HEARTBEAT_TIMEOUT_CODE, resolveHeartbeat } from \"@/heartbeat\";\nimport { defineEventBus } from \"@/helpers/event-bus\";\nimport { runPipeline } from \"@/pipeline\";\nimport { resolveQueue } from \"@/queue\";\nimport { SchemaValidationError, type StandardSchemaV1 } from \"@/schema\";\nimport type {\n    ClientEventMap,\n    ClientState,\n    ConnectionEvent,\n    ConnectionState,\n    DirectionalMiddleware,\n    Middleware,\n    OutboundMiddleware,\n    WebSocketClient,\n    WebSocketClientConfig\n} from \"@/types\";\n\n/**\n * Creates a WebSocket client driven by an explicit connection FSM.\n *\n * Durable by default: an unexpected disconnect schedules a reconnect with\n * full-jitter exponential backoff (see `backoff.ts`); pass `reconnect: false`\n * to opt out.\n *\n * @param config - Connection configuration (at minimum, a `url`).\n *\n * @example\n * ```typescript\n * const ws = client({ url: \"wss://example.com/socket\" });\n *\n * ws.on(\"message\", (data) => console.log(\"received:\", data));\n * ws.on(\"reconnecting\", ({ attempt, delay }) => {\n *     console.log(`retry #${attempt} in ${Math.round(delay)}ms`);\n * });\n *\n * await ws.connect();\n * ws.send({ type: \"hello\", message: \"world\" });\n *\n * ws.close();\n * ```\n */\nexport function client(config: WebSocketClientConfig): WebSocketClient {\n    const bus = defineEventBus();\n    const codec = config.codec ?? jsonCodec;\n    const reconnect = resolveReconnect(config.reconnect);\n    const queue = resolveQueue(config.queue);\n    const heartbeat = resolveHeartbeat(config.heartbeat);\n    const middlewares: Middleware[] = [];\n    const outboundMiddlewares: OutboundMiddleware[] = [];\n\n    // Outbound messages awaiting an open socket, in send() order. Original\n    // (un-encoded) values: encoding happens at flush, so a drop event can hand\n    // the user back exactly what they passed to send().\n    const queued: unknown[] = [];\n\n    let socket: WebSocket | null = null;\n    let state: ConnectionState = \"idle\";\n    let lastError: Event | Error | null = null;\n\n    // Heartbeat bookkeeping: when the last inbound frame (of any kind)\n    // arrived, the ping interval, and the per-ping liveness deadline.\n    let lastInboundAt = 0;\n    let heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n    let heartbeatDeadline: ReturnType<typeof setTimeout> | null = null;\n\n    // The serialized outbound path (in play only when outbound middleware is\n    // registered). `outboundTail` is the tail of the in-flight chain: while\n    // set, every new message chains behind it, so socket writes keep send()\n    // order even when a middleware awaits. `requeueIndex` keeps messages that\n    // were mid-pipeline when the connection dropped ahead of newer queued\n    // sends; it resets on every socket close.\n    let outboundTail: Promise<void> | null = null;\n    let requeueIndex = 0;\n\n    // True between a user close() and the next connect(); suppresses\n    // reconnection so \"the user hung up\" is never retried.\n    let closeRequested = false;\n    // Retries used in the current disconnection episode (see ClientState).\n    let retryAttempt = 0;\n    let retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n    // subscribe() listeners plus the cached getState() snapshot. The cache\n    // makes snapshots referentially stable between changes — required by\n    // React's useSyncExternalStore (a fresh object per getSnapshot() call\n    // would loop the renderer).\n    const subscribers = new Set<() => void>();\n    let snapshot: ClientState | null = null;\n\n    // The in-flight connect() promise and its settlers. A single promise is\n    // shared across concurrent/repeat connect() calls so the method is\n    // idempotent, and it survives failed attempts while reconnection is\n    // active — it settles only on first open or terminal failure.\n    let pending: {\n        readonly promise: Promise<void>;\n        readonly resolve: () => void;\n        readonly reject: (reason: Error) => void;\n    } | null = null;\n\n    /**\n     * Applies an FSM event. Legal transitions update the state and emit\n     * `statechange`; illegal ones are ignored (the table is the guard).\n     *\n     * @returns the new state if a transition occurred, otherwise `null`.\n     */\n    /**\n     * Invalidates the cached snapshot and fires subscribe() listeners. Called\n     * after every mutation of the observable state, before the corresponding\n     * bus event, so any observer reading getState() sees fresh data.\n     */\n    function notify() {\n        snapshot = null;\n        for (const listener of [...subscribers]) {\n            listener();\n        }\n    }\n\n    function transition(event: ConnectionEvent): ConnectionState | null {\n        const next = nextState(state, event);\n        if (next === null || next === state) {\n            return null;\n        }\n\n        const previous = state;\n        state = next;\n        notify();\n        bus.emit(\"statechange\", { previous, current: next });\n        return next;\n    }\n\n    function settleConnected() {\n        pending?.resolve();\n        pending = null;\n    }\n\n    function settleFailed(reason: Error) {\n        pending?.reject(reason);\n        pending = null;\n    }\n\n    function clearRetryTimer() {\n        if (retryTimer !== null) {\n            clearTimeout(retryTimer);\n            retryTimer = null;\n        }\n    }\n\n    function stopHeartbeat() {\n        if (heartbeatTimer !== null) {\n            clearInterval(heartbeatTimer);\n            heartbeatTimer = null;\n        }\n        if (heartbeatDeadline !== null) {\n            clearTimeout(heartbeatDeadline);\n            heartbeatDeadline = null;\n        }\n    }\n\n    /**\n     * While open, sends the heartbeat message every `interval` ms and arms a\n     * liveness deadline after each ping. Any inbound frame before the deadline\n     * proves the link; none means it's dead — force-close with code 4408,\n     * which flows into the normal reconnect machinery (the close is not\n     * user-initiated, so it is retryable).\n     */\n    function startHeartbeat() {\n        if (heartbeat === null) {\n            return;\n        }\n        stopHeartbeat();\n        heartbeatTimer = setInterval(() => {\n            if (state !== \"open\" || !socket) {\n                return;\n            }\n            const pingSentAt = Date.now();\n            try {\n                socket.send(codec.encode(heartbeat.message));\n            } catch (error) {\n                bus.emit(\"error\", toError(error));\n            }\n            if (heartbeatDeadline !== null) {\n                clearTimeout(heartbeatDeadline);\n            }\n            heartbeatDeadline = setTimeout(() => {\n                heartbeatDeadline = null;\n                if (state === \"open\" && socket && lastInboundAt < pingSentAt) {\n                    const failure = new Error(\n                        `Heartbeat timeout: no inbound traffic within ${heartbeat.timeout}ms of a ping`\n                    );\n                    lastError = failure;\n                    notify();\n                    bus.emit(\"error\", failure);\n                    socket.close(HEARTBEAT_TIMEOUT_CODE, \"heartbeat timeout\");\n                }\n            }, heartbeat.timeout);\n        }, heartbeat.interval);\n    }\n\n    /**\n     * Final stage of the outbound pipeline: encode the (possibly transformed)\n     * message and write it to the socket. The connection may have changed\n     * while middleware awaited, so re-check here: if a retry is underway, the\n     * *original* value is re-queued ahead of newer sends (middleware re-runs\n     * at the next transmission, keeping e.g. tokens fresh); on a dead-end\n     * state it surfaces as a `drop` — never silently lost.\n     */\n    function wire(transformed: unknown, original: unknown) {\n        if (socket && state === \"open\") {\n            socket.send(codec.encode(transformed));\n            return;\n        }\n        if (\n            queue !== null &&\n            (state === \"connecting\" || state === \"reconnecting\")\n        ) {\n            if (queued.length >= queue.maxSize) {\n                bus.emit(\"drop\", {\n                    data: queued.shift(),\n                    reason: \"overflow\"\n                });\n                if (requeueIndex > 0) {\n                    requeueIndex -= 1;\n                }\n            }\n            queued.splice(requeueIndex, 0, original);\n            requeueIndex += 1;\n            notify();\n            return;\n        }\n        bus.emit(\"drop\", { data: original, reason: \"close\" });\n    }\n\n    /**\n     * Runs one message through the outbound middleware chain. Errors are\n     * per-message: a throw/rejection surfaces as `error` and only this\n     * message is skipped.\n     */\n    function runOutbound(data: unknown): void | Promise<void> {\n        const ctx = { data, client: api };\n        try {\n            const result = runPipeline(outboundMiddlewares, ctx, () => {\n                wire(ctx.data, data);\n            });\n            if (result instanceof Promise) {\n                return result.catch((error: unknown) => {\n                    bus.emit(\"error\", toError(error));\n                });\n            }\n        } catch (error) {\n            bus.emit(\"error\", toError(error));\n        }\n    }\n\n    /**\n     * Sends a message through the outbound middleware pipeline, preserving\n     * send() order: while any message is in flight (async middleware), newer\n     * messages chain behind it. With no middleware in flight and an all-sync\n     * chain, the path stays fully synchronous.\n     */\n    function transmit(data: unknown) {\n        if (outboundTail === null) {\n            const result = runOutbound(data);\n            if (result instanceof Promise) {\n                setOutboundTail(result);\n            }\n            return;\n        }\n        setOutboundTail(outboundTail.then(() => runOutbound(data)));\n    }\n\n    function setOutboundTail(run: Promise<void>) {\n        const tail = run.then(() => {\n            // Chain drained: restore the synchronous fast path.\n            if (outboundTail === tail) {\n                outboundTail = null;\n            }\n        });\n        outboundTail = tail;\n    }\n\n    /**\n     * Sends every queued message in order. Called once the socket opens,\n     * *before* the `open` event, so the backlog (sent earlier in time)\n     * precedes anything an `open` handler sends — under async outbound\n     * middleware \"precedes\" means pipeline order; socket writes follow it.\n     * A per-message encode/send failure surfaces as an `error` event and\n     * flushing continues.\n     */\n    function flushQueue() {\n        const hadQueued = queued.length > 0;\n        requeueIndex = 0;\n        while (queued.length > 0 && socket && state === \"open\") {\n            const data = queued.shift();\n            if (outboundMiddlewares.length === 0) {\n                try {\n                    socket.send(codec.encode(data));\n                } catch (error) {\n                    bus.emit(\"error\", toError(error));\n                }\n            } else {\n                transmit(data);\n            }\n        }\n        if (hadQueued) {\n            notify();\n        }\n    }\n\n    /**\n     * Empties the queue as `drop` events — these messages will never be sent\n     * (user `close()` or terminal failure). Never silently lossy.\n     */\n    function dropQueued() {\n        const hadQueued = queued.length > 0;\n        while (queued.length > 0) {\n            bus.emit(\"drop\", { data: queued.shift(), reason: \"close\" });\n        }\n        if (hadQueued) {\n            notify();\n        }\n    }\n\n    /**\n     * Whether an unexpected close should be retried: reconnection enabled, not\n     * a user `close()`, retries left, and no `shouldReconnect` veto.\n     */\n    function isRetryable(event: CloseEvent): boolean {\n        return (\n            reconnect !== null &&\n            !closeRequested &&\n            retryAttempt < reconnect.maxRetries &&\n            reconnect.shouldReconnect(event)\n        );\n    }\n\n    function openSocket() {\n        if (lastError !== null) {\n            lastError = null;\n            notify();\n        }\n        socket = config.protocols\n            ? new WebSocket(config.url, config.protocols)\n            : new WebSocket(config.url);\n        if (config.binaryType) {\n            socket.binaryType = config.binaryType;\n        }\n\n        socket.onopen = () => {\n            retryAttempt = 0;\n            transition(\"OPEN\");\n            flushQueue();\n            startHeartbeat();\n            bus.emit(\"open\");\n            settleConnected();\n        };\n\n        socket.onmessage = (event: MessageEvent) => {\n            lastInboundAt = Date.now();\n            deliver(event.data);\n        };\n\n        socket.onerror = (event: Event) => {\n            lastError = event;\n            notify();\n            bus.emit(\"error\", event);\n        };\n\n        socket.onclose = (event: CloseEvent) => {\n            const wasConnecting = state === \"connecting\";\n            socket = null;\n            stopHeartbeat();\n            // A new disconnected period begins: in-flight outbound messages\n            // re-queue from the front (see wire()).\n            requeueIndex = 0;\n\n            if (reconnect !== null && isRetryable(event)) {\n                // Event order is deliberate: statechange (state already moved\n                // to `reconnecting`), then the close that caused it, then the\n                // retry announcement with attempt + delay.\n                retryAttempt += 1;\n                const delay = computeDelay(retryAttempt - 1, reconnect);\n                transition(\"RETRY\");\n                bus.emit(\"close\", event);\n                bus.emit(\"reconnecting\", { attempt: retryAttempt, delay });\n                retryTimer = setTimeout(() => {\n                    retryTimer = null;\n                    if (transition(\"CONNECT\") !== null) {\n                        openSocket();\n                    }\n                }, delay);\n                return; // pending connect() survives the retry\n            }\n\n            transition(\"CLOSED\");\n            dropQueued();\n            bus.emit(\"close\", event);\n            // Terminal for any in-flight connect(): closed before first open\n            // with no (further) retries coming.\n            if (wasConnecting || pending) {\n                settleFailed(\n                    new Error(\n                        retryAttempt > 0\n                            ? `WebSocket reconnect gave up after ${retryAttempt} attempt(s) (code ${event.code})`\n                            : `WebSocket closed before opening (code ${event.code}${\n                                  event.reason ? `: ${event.reason}` : \"\"\n                              })`\n                    )\n                );\n            }\n        };\n    }\n\n    /**\n     * Runs a decoded — and, if a schema is configured, validated — inbound\n     * message through the middleware chain. If the chain completes, the\n     * message is emitted as `message`; a middleware that throws or rejects\n     * surfaces as an `error`. Validation precedes middleware, so middleware\n     * only ever sees trusted data; an invalid message surfaces as an `error`\n     * (`SchemaValidationError`) and never reaches middleware or `message`.\n     */\n    function deliver(raw: unknown) {\n        const decoded = codec.decode(raw);\n        if (config.schema === undefined) {\n            dispatchMessage(decoded);\n            return;\n        }\n        let result: ReturnType<StandardSchemaV1[\"~standard\"][\"validate\"]>;\n        try {\n            result = config.schema[\"~standard\"].validate(decoded);\n        } catch (error) {\n            bus.emit(\"error\", toError(error));\n            return;\n        }\n        if (result instanceof Promise) {\n            result.then(handleValidated, (error: unknown) => {\n                bus.emit(\"error\", toError(error));\n            });\n            return;\n        }\n        handleValidated(result);\n    }\n\n    function handleValidated(result: StandardSchemaV1.Result<unknown>) {\n        if (result.issues) {\n            bus.emit(\"error\", new SchemaValidationError(result.issues));\n            return;\n        }\n        dispatchMessage(result.value);\n    }\n\n    function dispatchMessage(data: unknown) {\n        const ctx = { data, client: api };\n        const emit = () => {\n            bus.emit(\"message\", ctx.data);\n        };\n        try {\n            const result = runPipeline(middlewares, ctx, emit);\n            if (result instanceof Promise) {\n                result.catch((error: unknown) => {\n                    bus.emit(\"error\", toError(error));\n                });\n            }\n        } catch (error) {\n            bus.emit(\"error\", toError(error));\n        }\n    }\n\n    /** Lazily create (or reuse) the shared connect() promise. */\n    function ensurePending(): Promise<void> {\n        if (pending) {\n            return pending.promise;\n        }\n        let resolve!: () => void;\n        let reject!: (reason: Error) => void;\n        const promise = new Promise<void>((res, rej) => {\n            resolve = res;\n            reject = rej;\n        });\n        pending = { promise, resolve, reject };\n        return promise;\n    }\n\n    const api: WebSocketClient = {\n        get state() {\n            return state;\n        },\n\n        connect() {\n            if (state === \"open\") {\n                return Promise.resolve();\n            }\n            if (state === \"connecting\") {\n                return ensurePending();\n            }\n            if (state === \"closing\") {\n                return Promise.reject(\n                    new Error(\n                        \"Cannot connect() while the connection is closing\"\n                    )\n                );\n            }\n            if (state === \"reconnecting\") {\n                // Skip the rest of the backoff wait and attempt now.\n                clearRetryTimer();\n                const promise = ensurePending();\n                transition(\"CONNECT\");\n                openSocket();\n                return promise;\n            }\n\n            // idle or closed → start a fresh episode.\n            closeRequested = false;\n            retryAttempt = 0;\n            if (transition(\"CONNECT\") === null) {\n                return Promise.reject(\n                    new Error(`Cannot connect() from state \"${state}\"`)\n                );\n            }\n\n            const promise = ensurePending();\n            try {\n                openSocket();\n            } catch (error) {\n                transition(\"CLOSED\");\n                socket = null;\n                settleFailed(toError(error));\n            }\n\n            return promise;\n        },\n\n        send(data: unknown) {\n            if (socket && state === \"open\") {\n                if (outboundMiddlewares.length === 0) {\n                    // No outbound middleware: today's direct path, including\n                    // synchronous encode errors thrown to the caller.\n                    socket.send(codec.encode(data));\n                } else {\n                    transmit(data);\n                }\n                return;\n            }\n            // An open is coming (or being retried): queue, bounded drop-oldest.\n            if (\n                queue !== null &&\n                (state === \"connecting\" || state === \"reconnecting\")\n            ) {\n                if (queued.length >= queue.maxSize) {\n                    bus.emit(\"drop\", {\n                        data: queued.shift(),\n                        reason: \"overflow\"\n                    });\n                }\n                queued.push(data);\n                notify();\n                return;\n            }\n            throw new Error(\n                `Cannot send: connection is not open (state: \"${state}\")`\n            );\n        },\n\n        close(code?: number, reason?: string) {\n            closeRequested = true;\n            clearRetryTimer();\n            stopHeartbeat();\n            if (retryAttempt !== 0) {\n                retryAttempt = 0;\n                notify();\n            }\n            // The user hung up: queued messages will never send. Surface them\n            // now (deterministically), not when the socket finishes closing.\n            dropQueued();\n\n            if (state === \"reconnecting\") {\n                // No socket exists while waiting out the backoff: go straight\n                // to closed and terminate any in-flight connect().\n                transition(\"CLOSE_REQUESTED\");\n                settleFailed(\n                    new Error(\"close() called before the connection opened\")\n                );\n                return;\n            }\n            if (!socket) {\n                return;\n            }\n            transition(\"CLOSE_REQUESTED\");\n            socket.close(code, reason);\n        },\n\n        on<K extends keyof ClientEventMap>(\n            event: K,\n            handler: (payload: ClientEventMap[K]) => void\n        ) {\n            bus.on(event, handler);\n            return () => bus.off(event, handler);\n        },\n\n        use(middleware: Middleware | DirectionalMiddleware) {\n            if (typeof middleware === \"function\") {\n                middlewares.push(middleware);\n                return api;\n            }\n            if (middleware.inbound) {\n                middlewares.push(middleware.inbound);\n            }\n            if (middleware.outbound) {\n                outboundMiddlewares.push(middleware.outbound);\n            }\n            return api;\n        },\n\n        getState(): ClientState {\n            if (snapshot === null) {\n                snapshot = Object.freeze({\n                    state,\n                    lastError,\n                    retryAttempt,\n                    queueLength: queued.length\n                });\n            }\n            return snapshot;\n        },\n\n        subscribe(listener: () => void) {\n            subscribers.add(listener);\n            return () => {\n                subscribers.delete(listener);\n            };\n        }\n    };\n\n    return api;\n}\n\n/** Normalize an unknown thrown value into an `Error`. */\nfunction toError(value: unknown): Error {\n    return value instanceof Error ? value : new Error(String(value));\n}\n","import type { Middleware } from \"@/types\";\n\n/**\n * Replies to a textual `\"ping\"` with `\"pong\"` and stops the message there\n * (it is not emitted as a `message` event). A common keepalive convention.\n *\n * Opt in explicitly — it is not registered by default:\n *\n * ```typescript\n * import { defineClient, pingpong } from \"durablews\";\n *\n * const ws = defineClient({ url }).use(pingpong);\n * ```\n */\nexport const pingpong: Middleware = (ctx, next) => {\n    if (ctx.data === \"ping\") {\n        ctx.client.send(\"pong\");\n        return;\n    }\n    return next();\n};\n","import { client } from \"@/client\";\nimport type { StandardSchemaV1 } from \"@/schema\";\nimport type { WebSocketClient, WebSocketClientConfig } from \"@/types\";\n\n/**\n * Creates a new {@link WebSocketClient}.\n *\n * Each call returns an independent client — there is no shared singleton.\n *\n * Inbound message typing, three ways:\n * - **Schema (recommended):** pass a [Standard Schema](https://standardschema.dev)\n *   (zod, valibot, arktype, …) and the message type is inferred — plus every\n *   inbound message is validated at runtime.\n * - **Generics:** `defineClient<Incoming, Outgoing>(config)` for types without\n *   runtime validation.\n * - **Neither:** messages are `unknown`.\n *\n * @example\n * ```typescript\n * const Message = z.object({ type: z.string(), body: z.string() });\n * const ws = defineClient({ url: \"wss://example.com/socket\", schema: Message });\n *\n * ws.on(\"message\", (msg) => {\n *     // msg is { type: string; body: string } — validated at runtime\n * });\n * await ws.connect();\n * ```\n */\nexport function defineClient<TSchema extends StandardSchemaV1>(\n    config: WebSocketClientConfig & { readonly schema: TSchema }\n): WebSocketClient<StandardSchemaV1.InferOutput<TSchema>>;\nexport function defineClient<TIn = unknown, TOut = unknown>(\n    config: WebSocketClientConfig\n): WebSocketClient<TIn, TOut>;\nexport function defineClient(config: WebSocketClientConfig): WebSocketClient {\n    return client(config);\n}\n\nexport { RECONNECT_DEFAULTS } from \"@/backoff\";\nexport { jsonCodec } from \"@/codec\";\nexport { HEARTBEAT_TIMEOUT_CODE } from \"@/heartbeat\";\nexport { pingpong } from \"@/middleware\";\nexport { QUEUE_DEFAULTS } from \"@/queue\";\nexport type { StandardSchemaV1 } from \"@/schema\";\nexport { SchemaValidationError } from \"@/schema\";\nexport type {\n    ClientEventMap,\n    ClientState,\n    Codec,\n    ConnectionState,\n    DirectionalMiddleware,\n    DropEvent,\n    HeartbeatOptions,\n    MessageContext,\n    Middleware,\n    OutboundContext,\n    OutboundMiddleware,\n    QueueOptions,\n    ReconnectingEvent,\n    ReconnectOptions,\n    StateChange,\n    WebSocketClient,\n    WebSocketClientConfig\n} from \"@/types\";\n"]}