react-realtime-hooks 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/env.ts","../src/hooks/useOnlineStatus.ts","../src/core/reconnect.ts","../src/core/timers.ts","../src/hooks/useReconnect.ts","../src/hooks/useHeartbeat.ts","../src/core/connection-state.ts","../src/core/url.ts","../src/hooks/useWebSocket.ts","../src/hooks/useEventSource.ts"],"names":["useSyncExternalStore","useRef","useState","useEffect","startTransition","useEffectEvent","createInitialState","useMemo","socket","defaultParseMessage"],"mappings":"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","file":"index.cjs","sourcesContent":["export interface RuntimeFeatureSupport {\n eventSource: boolean;\n navigatorOnLine: boolean;\n webSocket: boolean;\n}\n\nexport const isBrowserRuntime = (): boolean =>\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\nexport const isWebSocketSupported = (): boolean =>\n typeof WebSocket !== \"undefined\";\n\nexport const isEventSourceSupported = (): boolean =>\n typeof EventSource !== \"undefined\";\n\nexport const hasNavigatorOnLineSupport = (): boolean =>\n typeof navigator !== \"undefined\" && typeof navigator.onLine === \"boolean\";\n\nexport const readOnlineStatus = (initialOnline = true): {\n isOnline: boolean;\n isSupported: boolean;\n} => {\n if (!hasNavigatorOnLineSupport()) {\n return {\n isOnline: initialOnline,\n isSupported: false\n };\n }\n\n return {\n isOnline: navigator.onLine,\n isSupported: true\n };\n};\n\nexport const getRuntimeFeatureSupport = (): RuntimeFeatureSupport => ({\n eventSource: isEventSourceSupported(),\n navigatorOnLine: hasNavigatorOnLineSupport(),\n webSocket: isWebSocketSupported()\n});\r\n","import { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\r\n\r\nimport { hasNavigatorOnLineSupport, readOnlineStatus } from \"../core/env\";\r\nimport type {\r\n UseOnlineStatusHook,\r\n UseOnlineStatusOptions,\r\n UseOnlineStatusResult\r\n} from \"../types/useOnlineStatus\";\r\n\r\nconst subscribeToOnlineStatus = (onStoreChange: () => void): (() => void) => {\r\n if (typeof window === \"undefined\") {\r\n return () => {};\r\n }\r\n\r\n window.addEventListener(\"online\", onStoreChange);\r\n window.addEventListener(\"offline\", onStoreChange);\r\n\r\n return () => {\r\n window.removeEventListener(\"online\", onStoreChange);\r\n window.removeEventListener(\"offline\", onStoreChange);\r\n };\r\n};\r\n\r\nconst createEmptyTransitionState = (): Pick<\r\n UseOnlineStatusResult,\r\n \"lastChangedAt\" | \"wentOfflineAt\" | \"wentOnlineAt\"\r\n> => ({\r\n lastChangedAt: null,\r\n wentOfflineAt: null,\r\n wentOnlineAt: null\r\n});\r\n\r\nexport const useOnlineStatus: UseOnlineStatusHook = (\r\n options: UseOnlineStatusOptions = {}\r\n) => {\r\n const initialOnline = options.initialOnline ?? true;\r\n const trackTransitions = options.trackTransitions ?? true;\r\n\r\n const isOnline = useSyncExternalStore(\r\n subscribeToOnlineStatus,\r\n () => readOnlineStatus(initialOnline).isOnline,\r\n () => initialOnline\r\n );\r\n\r\n const previousOnlineRef = useRef(isOnline);\r\n const [transitions, setTransitions] = useState(createEmptyTransitionState);\r\n\r\n useEffect(() => {\r\n if (!trackTransitions) {\r\n previousOnlineRef.current = isOnline;\r\n setTransitions(createEmptyTransitionState);\r\n return;\r\n }\r\n\r\n if (previousOnlineRef.current === isOnline) {\r\n return;\r\n }\r\n\r\n const changedAt = Date.now();\r\n previousOnlineRef.current = isOnline;\r\n\r\n setTransitions((current) => ({\r\n lastChangedAt: changedAt,\r\n wentOfflineAt: isOnline ? current.wentOfflineAt : changedAt,\r\n wentOnlineAt: isOnline ? changedAt : current.wentOnlineAt\r\n }));\r\n }, [isOnline, trackTransitions]);\r\n\r\n return {\r\n isOnline,\r\n isSupported: hasNavigatorOnLineSupport(),\r\n ...transitions\r\n };\r\n};\r\n","import type {\n ReconnectAttempt,\n ReconnectDelayContext,\n ReconnectDelayStrategy,\n ReconnectTrigger,\n UseReconnectOptions\n} from \"../types/useReconnect\";\n\nexport interface NormalizedReconnectOptions {\n backoffFactor: number;\n enabled: boolean;\n getDelayMs?: ReconnectDelayStrategy;\n initialDelayMs: number;\n jitterRatio: number;\n maxAttempts: number | null;\n maxDelayMs: number;\n onCancel?: () => void;\n onReset?: () => void;\n onSchedule?: (attempt: ReconnectAttempt) => void;\n resetOnSuccess: boolean;\n}\n\nexport interface ReconnectDelayCalculationOptions {\n random?: () => number;\n strategy?: ReconnectDelayStrategy;\n}\n\nexport interface CreateReconnectAttemptOptions\n extends ReconnectDelayCalculationOptions {\n now?: number;\n}\n\nexport const DEFAULT_RECONNECT_OPTIONS: Readonly<\n Omit<NormalizedReconnectOptions, \"getDelayMs\" | \"onCancel\" | \"onReset\" | \"onSchedule\">\n> = {\n backoffFactor: 2,\n enabled: true,\n initialDelayMs: 1_000,\n jitterRatio: 0.2,\n maxAttempts: null,\n maxDelayMs: 30_000,\n resetOnSuccess: true\n};\n\nconst clampNumber = (value: number, min: number, max: number): number =>\n Math.min(max, Math.max(min, value));\n\nconst sanitizeDelay = (value: number): number => {\n if (!Number.isFinite(value)) {\n return 0;\n }\n\n return Math.max(0, Math.round(value));\n};\n\nconst sanitizeBackoffFactor = (value: number): number => {\n if (!Number.isFinite(value)) {\n return DEFAULT_RECONNECT_OPTIONS.backoffFactor;\n }\n\n return Math.max(1, value);\n};\n\nconst sanitizeMaxAttempts = (\n value: number | null | undefined\n): number | null => {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (!Number.isFinite(value)) {\n return null;\n }\n\n return Math.max(0, Math.floor(value));\n};\n\nconst sanitizeJitterRatio = (value: number): number => {\n if (!Number.isFinite(value)) {\n return DEFAULT_RECONNECT_OPTIONS.jitterRatio;\n }\n\n return clampNumber(value, 0, 1);\n};\n\nexport const normalizeReconnectOptions = (\n options?: false | UseReconnectOptions\n): NormalizedReconnectOptions | null => {\n if (options === false) {\n return null;\n }\n\n const initialDelayMs = sanitizeDelay(\n options?.initialDelayMs ?? DEFAULT_RECONNECT_OPTIONS.initialDelayMs\n );\n const maxDelayMs = Math.max(\n initialDelayMs,\n sanitizeDelay(options?.maxDelayMs ?? DEFAULT_RECONNECT_OPTIONS.maxDelayMs)\n );\n\n const normalized: NormalizedReconnectOptions = {\n backoffFactor: sanitizeBackoffFactor(\n options?.backoffFactor ?? DEFAULT_RECONNECT_OPTIONS.backoffFactor\n ),\n enabled: options?.enabled ?? DEFAULT_RECONNECT_OPTIONS.enabled,\n initialDelayMs,\n jitterRatio: sanitizeJitterRatio(\n options?.jitterRatio ?? DEFAULT_RECONNECT_OPTIONS.jitterRatio\n ),\n maxAttempts: sanitizeMaxAttempts(options?.maxAttempts),\n maxDelayMs,\n resetOnSuccess: options?.resetOnSuccess ?? DEFAULT_RECONNECT_OPTIONS.resetOnSuccess\n };\n\n if (options?.getDelayMs !== undefined) {\n normalized.getDelayMs = options.getDelayMs;\n }\n\n if (options?.onCancel !== undefined) {\n normalized.onCancel = options.onCancel;\n }\n\n if (options?.onReset !== undefined) {\n normalized.onReset = options.onReset;\n }\n\n if (options?.onSchedule !== undefined) {\n normalized.onSchedule = options.onSchedule;\n }\n\n return normalized;\n};\n\nexport const createReconnectDelayContext = (\n attempt: number,\n options: Pick<\n NormalizedReconnectOptions,\n \"backoffFactor\" | \"initialDelayMs\" | \"jitterRatio\" | \"maxDelayMs\"\n >,\n lastDelayMs: number | null\n): ReconnectDelayContext => ({\n attempt: Math.max(1, Math.floor(attempt)),\n backoffFactor: options.backoffFactor,\n initialDelayMs: options.initialDelayMs,\n jitterRatio: options.jitterRatio,\n lastDelayMs,\n maxDelayMs: options.maxDelayMs\n});\n\nexport const defaultReconnectDelayStrategy = (\n context: ReconnectDelayContext\n): number => {\n const exponent = Math.max(0, context.attempt - 1);\n const baseDelay = context.initialDelayMs * context.backoffFactor ** exponent;\n return Math.min(context.maxDelayMs, sanitizeDelay(baseDelay));\n};\n\nexport const applyJitterToDelay = (\n delayMs: number,\n jitterRatio: number,\n random: () => number = Math.random\n): number => {\n if (delayMs === 0 || jitterRatio === 0) {\n return delayMs;\n }\n\n const safeRandom = clampNumber(random(), 0, 1);\n const variance = delayMs * jitterRatio;\n const offset = (safeRandom * 2 - 1) * variance;\n return sanitizeDelay(delayMs + offset);\n};\n\nexport const calculateReconnectDelay = (\n context: ReconnectDelayContext,\n options: ReconnectDelayCalculationOptions = {}\n): number => {\n const baseDelay = sanitizeDelay(\n (options.strategy ?? defaultReconnectDelayStrategy)(context)\n );\n const cappedDelay = Math.min(context.maxDelayMs, baseDelay);\n return Math.min(\n context.maxDelayMs,\n applyJitterToDelay(cappedDelay, context.jitterRatio, options.random)\n );\n};\n\nexport const canScheduleReconnectAttempt = (\n attempt: number,\n options: Pick<NormalizedReconnectOptions, \"enabled\" | \"maxAttempts\">\n): boolean => {\n if (!options.enabled) {\n return false;\n }\n\n if (attempt < 1) {\n return false;\n }\n\n return options.maxAttempts === null || attempt <= options.maxAttempts;\n};\n\nexport const createReconnectAttempt = (\n attempt: number,\n trigger: ReconnectTrigger,\n options: Pick<\n NormalizedReconnectOptions,\n \"backoffFactor\" | \"enabled\" | \"getDelayMs\" | \"initialDelayMs\" | \"jitterRatio\" | \"maxAttempts\" | \"maxDelayMs\"\n >,\n lastDelayMs: number | null,\n config: CreateReconnectAttemptOptions = {}\n): ReconnectAttempt | null => {\n if (!canScheduleReconnectAttempt(attempt, options)) {\n return null;\n }\n\n const context = createReconnectDelayContext(attempt, options, lastDelayMs);\n const calculationOptions: ReconnectDelayCalculationOptions = {};\n\n if (config.random !== undefined) {\n calculationOptions.random = config.random;\n }\n\n if (options.getDelayMs !== undefined) {\n calculationOptions.strategy = options.getDelayMs;\n }\n\n return {\n attempt,\n delayMs: calculateReconnectDelay(context, calculationOptions),\n scheduledAt: config.now ?? Date.now(),\n trigger\n };\n};\r\n","export interface ManagedTimeout {\n cancel: () => void;\n isActive: () => boolean;\n schedule: (callback: () => void, delayMs: number) => void;\n}\n\nexport interface ManagedInterval {\n cancel: () => void;\n isActive: () => boolean;\n start: (callback: () => void, intervalMs: number) => void;\n}\n\nconst sanitizeTimerDelay = (delayMs: number): number => {\n if (!Number.isFinite(delayMs)) {\n return 0;\n }\n\n return Math.max(0, Math.round(delayMs));\n};\n\nexport const createManagedTimeout = (): ManagedTimeout => {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return {\n cancel() {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n },\n isActive() {\n return timeoutId !== null;\n },\n schedule(callback, delayMs) {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n timeoutId = null;\n callback();\n }, sanitizeTimerDelay(delayMs));\n }\n };\n};\n\nexport const createManagedInterval = (): ManagedInterval => {\n let intervalId: ReturnType<typeof setInterval> | null = null;\n\n return {\n cancel() {\n if (intervalId !== null) {\n clearInterval(intervalId);\n intervalId = null;\n }\n },\n isActive() {\n return intervalId !== null;\n },\n start(callback, intervalMs) {\n if (intervalId !== null) {\n clearInterval(intervalId);\n }\n\n intervalId = setInterval(callback, sanitizeTimerDelay(intervalMs));\n }\n };\n};\r\n","import {\r\n startTransition,\r\n useEffect,\r\n useEffectEvent,\r\n useRef,\r\n useState\r\n} from \"react\";\r\n\r\nimport {\r\n createReconnectAttempt,\r\n normalizeReconnectOptions\r\n} from \"../core/reconnect\";\r\nimport { createManagedTimeout } from \"../core/timers\";\r\nimport type {\r\n ReconnectAttempt,\r\n ReconnectTrigger,\r\n UseReconnectHook,\r\n UseReconnectResult\r\n} from \"../types/useReconnect\";\r\n\r\ntype ReconnectState = Pick<\r\n UseReconnectResult,\r\n \"attempt\" | \"nextDelayMs\" | \"status\"\r\n>;\r\n\r\nconst createInitialState = (enabled: boolean): ReconnectState => ({\r\n attempt: 0,\r\n nextDelayMs: null,\r\n status: enabled ? \"idle\" : \"stopped\"\r\n});\r\n\r\nexport const useReconnect: UseReconnectHook = (options = {}) => {\r\n const normalizedOptions = normalizeReconnectOptions(options) ??\r\n normalizeReconnectOptions()!;\r\n const timeoutRef = useRef(createManagedTimeout());\r\n const lastDelayRef = useRef<number | null>(null);\r\n const [state, setState] = useState<ReconnectState>(() =>\r\n createInitialState(normalizedOptions.enabled)\r\n );\r\n const stateRef = useRef(state);\r\n\r\n stateRef.current = state;\r\n\r\n const commitState = (\r\n next:\r\n | ReconnectState\r\n | ((current: ReconnectState) => ReconnectState)\r\n ): void => {\r\n const resolved =\r\n typeof next === \"function\"\r\n ? next(stateRef.current)\r\n : next;\r\n\r\n stateRef.current = resolved;\r\n startTransition(() => {\r\n setState(resolved);\r\n });\r\n };\r\n\r\n const runAttempt = useEffectEvent((attempt: number) => {\r\n commitState({\r\n attempt,\r\n nextDelayMs: null,\r\n status: \"running\"\r\n });\r\n });\r\n\r\n const emitSchedule = useEffectEvent((attempt: ReconnectAttempt) => {\r\n normalizedOptions.onSchedule?.(attempt);\r\n });\r\n\r\n const emitCancel = useEffectEvent(() => {\r\n normalizedOptions.onCancel?.();\r\n });\r\n\r\n const emitReset = useEffectEvent(() => {\r\n normalizedOptions.onReset?.();\r\n });\r\n\r\n useEffect(() => {\r\n if (!normalizedOptions.enabled) {\r\n timeoutRef.current.cancel();\r\n commitState((current) => ({\r\n ...current,\r\n nextDelayMs: null,\r\n status: \"stopped\"\r\n }));\r\n return;\r\n }\r\n\r\n commitState((current) =>\r\n current.status === \"stopped\"\r\n ? {\r\n ...current,\r\n status: \"idle\"\r\n }\r\n : current\r\n );\r\n }, [normalizedOptions.enabled]);\r\n\r\n useEffect(() => () => {\r\n timeoutRef.current.cancel();\r\n }, []);\r\n\r\n const schedule = (trigger: ReconnectTrigger = \"manual\"): void => {\r\n const current = stateRef.current;\r\n const nextAttempt = current.attempt + 1;\r\n const attempt = createReconnectAttempt(\r\n nextAttempt,\r\n trigger,\r\n normalizedOptions,\r\n lastDelayRef.current\r\n );\r\n\r\n timeoutRef.current.cancel();\r\n\r\n if (attempt === null) {\r\n commitState((snapshot) => ({\r\n ...snapshot,\r\n nextDelayMs: null,\r\n status: \"stopped\"\r\n }));\r\n return;\r\n }\r\n\r\n lastDelayRef.current = attempt.delayMs;\r\n timeoutRef.current.schedule(() => {\r\n runAttempt(attempt.attempt);\r\n }, attempt.delayMs);\r\n\r\n commitState({\r\n attempt: attempt.attempt,\r\n nextDelayMs: attempt.delayMs,\r\n status: \"scheduled\"\r\n });\r\n\r\n emitSchedule(attempt);\r\n };\r\n\r\n const cancel = (): void => {\r\n const current = stateRef.current;\r\n const shouldEmitCancel =\r\n timeoutRef.current.isActive() ||\r\n current.status === \"scheduled\" ||\r\n current.status === \"running\";\r\n\r\n timeoutRef.current.cancel();\r\n commitState((snapshot) => ({\r\n ...snapshot,\r\n nextDelayMs: null,\r\n status: \"stopped\"\r\n }));\r\n\r\n if (shouldEmitCancel) {\r\n emitCancel();\r\n }\r\n };\r\n\r\n const reset = (): void => {\r\n timeoutRef.current.cancel();\r\n lastDelayRef.current = null;\r\n commitState(createInitialState(normalizedOptions.enabled));\r\n emitReset();\r\n };\r\n\r\n const markConnected = (): void => {\r\n timeoutRef.current.cancel();\r\n\r\n if (normalizedOptions.resetOnSuccess) {\r\n lastDelayRef.current = null;\r\n commitState(createInitialState(normalizedOptions.enabled));\r\n emitReset();\r\n return;\r\n }\r\n\r\n commitState((current) => ({\r\n ...current,\r\n nextDelayMs: null,\r\n status: normalizedOptions.enabled ? \"idle\" : \"stopped\"\r\n }));\r\n };\r\n\r\n return {\r\n attempt: state.attempt,\r\n cancel,\r\n isActive: state.status === \"scheduled\" || state.status === \"running\",\r\n isScheduled: state.status === \"scheduled\",\r\n markConnected,\r\n nextDelayMs: state.nextDelayMs,\r\n reset,\r\n schedule,\r\n status: state.status\r\n };\r\n};\r\n","import { useEffect, useEffectEvent, useRef, useState } from \"react\";\r\n\r\nimport {\r\n createManagedInterval,\r\n createManagedTimeout\r\n} from \"../core/timers\";\r\nimport type {\r\n UseHeartbeatOptions,\r\n UseHeartbeatHook,\r\n UseHeartbeatResult\r\n} from \"../types/useHeartbeat\";\r\n\r\ntype HeartbeatState = Pick<\r\n UseHeartbeatResult,\r\n \"hasTimedOut\" | \"isRunning\" | \"lastAckAt\" | \"lastBeatAt\" | \"latencyMs\"\r\n>;\r\n\r\nconst createInitialState = (isRunning: boolean): HeartbeatState => ({\r\n hasTimedOut: false,\r\n isRunning,\r\n lastAckAt: null,\r\n lastBeatAt: null,\r\n latencyMs: null\r\n});\r\n\r\nexport const useHeartbeat = <\r\n TOutgoing = unknown,\r\n TIncoming = TOutgoing\r\n>(\r\n options: UseHeartbeatOptions<TOutgoing, TIncoming>\r\n): UseHeartbeatResult<TIncoming> => {\r\n const enabled = options.enabled ?? true;\r\n const startOnMount = options.startOnMount ?? true;\r\n const intervalRef = useRef(createManagedInterval());\r\n const timeoutRef = useRef(createManagedTimeout());\r\n const [state, setState] = useState<HeartbeatState>(() =>\r\n createInitialState(enabled && startOnMount)\r\n );\r\n const stateRef = useRef(state);\r\n\r\n stateRef.current = state;\r\n\r\n const commitState = (\r\n next:\r\n | HeartbeatState\r\n | ((current: HeartbeatState) => HeartbeatState)\r\n ): void => {\r\n const resolved =\r\n typeof next === \"function\" ? next(stateRef.current) : next;\r\n\r\n stateRef.current = resolved;\r\n setState(resolved);\r\n };\r\n\r\n const handleTimeout = useEffectEvent(() => {\r\n commitState((current) => ({\r\n ...current,\r\n hasTimedOut: true\r\n }));\r\n options.onTimeout?.();\r\n });\r\n\r\n const scheduleTimeout = useEffectEvent(() => {\r\n if (options.timeoutMs === undefined) {\r\n timeoutRef.current.cancel();\r\n return;\r\n }\r\n\r\n timeoutRef.current.schedule(() => {\r\n handleTimeout();\r\n }, options.timeoutMs);\r\n });\r\n\r\n const runBeat = useEffectEvent(() => {\r\n const performedAt = Date.now();\r\n\r\n commitState((current) => ({\r\n ...current,\r\n hasTimedOut: false,\r\n lastBeatAt: performedAt\r\n }));\r\n\r\n scheduleTimeout();\r\n options.onBeat?.();\r\n\r\n void options.beat?.();\r\n });\r\n\r\n const start = (): void => {\r\n if (!enabled) {\r\n return;\r\n }\r\n\r\n if (!intervalRef.current.isActive()) {\r\n intervalRef.current.start(() => {\r\n runBeat();\r\n }, options.intervalMs);\r\n }\r\n\r\n commitState((current) => ({\r\n ...current,\r\n hasTimedOut: false,\r\n isRunning: true\r\n }));\r\n };\r\n\r\n const stop = (): void => {\r\n intervalRef.current.cancel();\r\n timeoutRef.current.cancel();\r\n commitState((current) => ({\r\n ...current,\r\n hasTimedOut: false,\r\n isRunning: false\r\n }));\r\n };\r\n\r\n const beat = (): void => {\r\n if (!enabled) {\r\n return;\r\n }\r\n\r\n runBeat();\r\n };\r\n\r\n const notifyAck = (message: TIncoming): boolean => {\r\n if (stateRef.current.lastBeatAt === null) {\r\n return false;\r\n }\r\n\r\n const matchesAck =\r\n options.matchesAck === undefined || options.matchesAck(message);\r\n\r\n if (!matchesAck) {\r\n return false;\r\n }\r\n\r\n const acknowledgedAt = Date.now();\r\n timeoutRef.current.cancel();\r\n\r\n commitState((current) => ({\r\n ...current,\r\n hasTimedOut: false,\r\n lastAckAt: acknowledgedAt,\r\n latencyMs:\r\n current.lastBeatAt === null\r\n ? null\r\n : acknowledgedAt - current.lastBeatAt\r\n }));\r\n\r\n return true;\r\n };\r\n\r\n useEffect(() => {\r\n if (!enabled) {\r\n stop();\r\n return;\r\n }\r\n\r\n if (startOnMount) {\r\n start();\r\n return stop;\r\n }\r\n\r\n stop();\r\n return undefined;\r\n }, [enabled, options.intervalMs, startOnMount]);\r\n\r\n useEffect(() => () => {\r\n intervalRef.current.cancel();\r\n timeoutRef.current.cancel();\r\n }, []);\r\n\r\n return {\r\n beat,\r\n hasTimedOut: state.hasTimedOut,\r\n isRunning: state.isRunning,\r\n lastAckAt: state.lastAckAt,\r\n lastBeatAt: state.lastBeatAt,\r\n latencyMs: state.latencyMs,\r\n notifyAck,\r\n start,\r\n stop\r\n };\r\n};\r\n\r\nconst _useHeartbeatTypecheck: UseHeartbeatHook = useHeartbeat;\r\nvoid _useHeartbeatTypecheck;\r\n","import type {\r\n ConnectionStateSnapshot,\r\n RealtimeConnectionStatus\r\n} from \"../types/common\";\r\n\r\nexport const isConnectedStatus = (\r\n status: RealtimeConnectionStatus\r\n): boolean => status === \"open\";\r\n\r\nexport const isConnectingStatus = (\r\n status: RealtimeConnectionStatus\r\n): boolean => status === \"connecting\" || status === \"reconnecting\";\r\n\r\nexport const isClosedStatus = (\r\n status: RealtimeConnectionStatus\r\n): boolean => status === \"closed\" || status === \"idle\" || status === \"error\";\r\n\r\nexport const createConnectionStateSnapshot = (\r\n status: RealtimeConnectionStatus,\r\n config: {\r\n isSupported?: boolean;\r\n lastChangedAt?: number | null;\r\n } = {}\r\n): ConnectionStateSnapshot => {\r\n const base = {\r\n isSupported: config.isSupported ?? true,\r\n lastChangedAt: config.lastChangedAt ?? null\r\n };\r\n\r\n switch (status) {\r\n case \"open\":\r\n return {\r\n ...base,\r\n isClosed: false,\r\n isConnected: true,\r\n isConnecting: false,\r\n status\r\n };\r\n case \"connecting\":\r\n case \"reconnecting\":\r\n return {\r\n ...base,\r\n isClosed: false,\r\n isConnected: false,\r\n isConnecting: true,\r\n status\r\n };\r\n case \"closing\":\r\n return {\r\n ...base,\r\n isClosed: false,\r\n isConnected: false,\r\n isConnecting: false,\r\n status\r\n };\r\n case \"idle\":\r\n case \"closed\":\r\n case \"error\":\r\n return {\r\n ...base,\r\n isClosed: true,\r\n isConnected: false,\r\n isConnecting: false,\r\n status\r\n };\r\n }\r\n};\r\n","import type { UrlProvider } from \"../types/common\";\n\nconst normalizeResolvedUrl = (value: string | URL | null): string | null => {\n if (value === null) {\n return null;\n }\n\n if (value instanceof URL) {\n return value.toString();\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n};\n\nexport const resolveUrlProvider = (url: UrlProvider): string | null => {\n const resolved = typeof url === \"function\" ? url() : url;\n return normalizeResolvedUrl(resolved ?? null);\n};\r\n","import { useEffect, useEffectEvent, useMemo, useRef, useState } from \"react\";\r\n\r\nimport { createConnectionStateSnapshot } from \"../core/connection-state\";\r\nimport { isWebSocketSupported } from \"../core/env\";\r\nimport { resolveUrlProvider } from \"../core/url\";\r\nimport { useHeartbeat } from \"./useHeartbeat\";\r\nimport { useReconnect } from \"./useReconnect\";\r\nimport type { UseHeartbeatOptions } from \"../types/useHeartbeat\";\r\nimport type {\r\n UseWebSocketHook,\r\n UseWebSocketOptions,\r\n UseWebSocketResult\r\n} from \"../types/useWebSocket\";\r\n\r\ntype WebSocketState<TIncoming> = {\r\n bufferedAmount: number;\r\n lastChangedAt: number | null;\r\n lastCloseEvent: CloseEvent | null;\r\n lastError: Event | null;\r\n lastMessage: TIncoming | null;\r\n lastMessageEvent: MessageEvent<unknown> | null;\r\n status: UseWebSocketResult<TIncoming>[\"status\"];\r\n};\r\n\r\nconst createInitialState = <TIncoming,>(\r\n status: UseWebSocketResult<TIncoming>[\"status\"] = \"idle\"\r\n): WebSocketState<TIncoming> => ({\r\n bufferedAmount: 0,\r\n lastChangedAt: null,\r\n lastCloseEvent: null,\r\n lastError: null,\r\n lastMessage: null,\r\n lastMessageEvent: null,\r\n status\r\n});\r\n\r\nconst defaultParseMessage = <TIncoming,>(\r\n event: MessageEvent<unknown>\r\n): TIncoming => event.data as TIncoming;\r\n\r\nconst defaultSerializeMessage = <TOutgoing,>(message: TOutgoing) => {\r\n if (\r\n typeof message === \"string\" ||\r\n message instanceof Blob ||\r\n message instanceof ArrayBuffer\r\n ) {\r\n return message;\r\n }\r\n\r\n if (ArrayBuffer.isView(message)) {\r\n return message;\r\n }\r\n\r\n return JSON.stringify(message);\r\n};\r\n\r\nconst resolveFactoryValue = <TValue,>(\r\n value: TValue | (() => TValue)\r\n): TValue =>\r\n typeof value === \"function\"\r\n ? (value as () => TValue)()\r\n : value;\r\n\r\nconst toProtocolsDependency = (protocols: string | string[] | undefined): string => {\r\n if (protocols === undefined) {\r\n return \"\";\r\n }\r\n\r\n return Array.isArray(protocols) ? protocols.join(\"|\") : protocols;\r\n};\r\n\r\nconst toHeartbeatConfig = <TOutgoing, TIncoming>(\r\n heartbeat: UseWebSocketOptions<TIncoming, TOutgoing>[\"heartbeat\"]\r\n): UseHeartbeatOptions<TOutgoing, TIncoming> | null =>\r\n heartbeat === undefined || heartbeat === false ? null : heartbeat;\r\n\r\nexport const useWebSocket: UseWebSocketHook = <\r\n TIncoming = unknown,\r\n TOutgoing = TIncoming\r\n>(\r\n options: UseWebSocketOptions<TIncoming, TOutgoing>\r\n): UseWebSocketResult<TIncoming, TOutgoing> => {\r\n const connect = options.connect ?? true;\r\n const supported = isWebSocketSupported();\r\n const resolvedUrl = useMemo(() => resolveUrlProvider(options.url), [options.url]);\r\n const protocolsDependency = toProtocolsDependency(options.protocols);\r\n\r\n const socketRef = useRef<WebSocket | null>(null);\r\n const socketKeyRef = useRef<string | null>(null);\r\n const manualCloseRef = useRef(false);\r\n const manualOpenRef = useRef(false);\r\n const skipCloseReconnectRef = useRef(false);\r\n const suppressReconnectRef = useRef(false);\r\n const [openNonce, setOpenNonce] = useState(0);\r\n const [state, setState] = useState<WebSocketState<TIncoming>>(() =>\r\n createInitialState(connect ? \"connecting\" : \"idle\")\r\n );\r\n const stateRef = useRef(state);\r\n stateRef.current = state;\r\n\r\n const reconnectEnabled =\r\n options.reconnect !== false && supported && resolvedUrl !== null;\r\n const reconnect = useReconnect(\r\n options.reconnect === false\r\n ? { enabled: false }\r\n : {\r\n ...options.reconnect,\r\n enabled: reconnectEnabled && (options.reconnect?.enabled ?? true)\r\n }\r\n );\r\n\r\n const heartbeatEnabled =\r\n options.heartbeat !== false && supported && resolvedUrl !== null;\r\n const heartbeatConfig = toHeartbeatConfig<TOutgoing, TIncoming>(\r\n options.heartbeat\r\n );\r\n const heartbeatHookOptions: UseHeartbeatOptions<TOutgoing, TIncoming> =\r\n heartbeatConfig === null\r\n ? {\r\n enabled: false,\r\n intervalMs: 1_000,\r\n startOnMount: false\r\n }\r\n : {\r\n beat: () => {\r\n const socket = socketRef.current;\r\n if (socket === null || socket.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n\r\n const heartbeatMessage = heartbeatConfig.message;\r\n\r\n if (heartbeatMessage !== undefined) {\r\n const serialized = (options.serializeMessage ?? defaultSerializeMessage)(\r\n resolveFactoryValue(heartbeatMessage)\r\n );\r\n socket.send(serialized);\r\n }\r\n\r\n return heartbeatConfig.beat?.() ?? true;\r\n },\r\n enabled: heartbeatEnabled && (heartbeatConfig.enabled ?? true),\r\n intervalMs: heartbeatConfig.intervalMs,\r\n startOnMount: false\r\n };\r\n\r\n if (heartbeatConfig !== null && heartbeatConfig.timeoutMs !== undefined) {\r\n heartbeatHookOptions.timeoutMs = heartbeatConfig.timeoutMs;\r\n }\r\n\r\n if (heartbeatConfig !== null && heartbeatConfig.matchesAck !== undefined) {\r\n heartbeatHookOptions.matchesAck = heartbeatConfig.matchesAck;\r\n }\r\n\r\n if (heartbeatConfig !== null && heartbeatConfig.onBeat !== undefined) {\r\n heartbeatHookOptions.onBeat = heartbeatConfig.onBeat;\r\n }\r\n\r\n if (heartbeatConfig !== null && heartbeatConfig.onTimeout !== undefined) {\r\n heartbeatHookOptions.onTimeout = heartbeatConfig.onTimeout;\r\n }\r\n\r\n const heartbeat = useHeartbeat<TOutgoing, TIncoming>(\r\n heartbeatHookOptions\r\n );\r\n\r\n const commitState = (\r\n next:\r\n | WebSocketState<TIncoming>\r\n | ((current: WebSocketState<TIncoming>) => WebSocketState<TIncoming>)\r\n ): void => {\r\n const resolved = typeof next === \"function\" ? next(stateRef.current) : next;\r\n stateRef.current = resolved;\r\n setState(resolved);\r\n };\r\n\r\n const closeSocket = useEffectEvent((code?: number, reason?: string) => {\r\n const socket = socketRef.current;\r\n\r\n if (socket === null) {\r\n return;\r\n }\r\n\r\n socketRef.current = null;\r\n socketKeyRef.current = null;\r\n\r\n if (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING) {\r\n socket.close(code, reason);\r\n }\r\n });\r\n\r\n const parseMessage = useEffectEvent((event: MessageEvent<unknown>) => {\r\n const parser = options.parseMessage ?? defaultParseMessage<TIncoming>;\r\n return parser(event);\r\n });\r\n\r\n const updateBufferedAmount = useEffectEvent(() => {\r\n commitState((current) => ({\r\n ...current,\r\n bufferedAmount: socketRef.current?.bufferedAmount ?? 0\r\n }));\r\n });\r\n\r\n const handleOpen = useEffectEvent((event: Event, socket: WebSocket) => {\r\n manualCloseRef.current = false;\r\n suppressReconnectRef.current = false;\r\n reconnect.markConnected();\r\n heartbeat.start();\r\n\r\n commitState((current) => ({\r\n ...current,\r\n bufferedAmount: socket.bufferedAmount,\r\n lastChangedAt: Date.now(),\r\n status: \"open\"\r\n }));\r\n\r\n options.onOpen?.(event, socket);\r\n });\r\n\r\n const handleMessage = useEffectEvent((event: MessageEvent<unknown>) => {\r\n try {\r\n const message = parseMessage(event);\r\n heartbeat.notifyAck(message);\r\n\r\n commitState((current) => ({\r\n ...current,\r\n bufferedAmount: socketRef.current?.bufferedAmount ?? current.bufferedAmount,\r\n lastMessage: message,\r\n lastMessageEvent: event\r\n }));\r\n\r\n options.onMessage?.(message, event);\r\n } catch {\r\n const parseError = new Event(\"error\");\r\n commitState((current) => ({\r\n ...current,\r\n lastError: parseError,\r\n status: \"error\"\r\n }));\r\n }\r\n });\r\n\r\n const handleError = useEffectEvent((event: Event) => {\r\n heartbeat.stop();\r\n commitState((current) => ({\r\n ...current,\r\n lastError: event,\r\n status: \"error\"\r\n }));\r\n\r\n options.onError?.(event);\r\n });\r\n\r\n const handleClose = useEffectEvent((event: CloseEvent) => {\r\n socketRef.current = null;\r\n socketKeyRef.current = null;\r\n heartbeat.stop();\r\n updateBufferedAmount();\r\n const skipCloseReconnect = skipCloseReconnectRef.current;\r\n skipCloseReconnectRef.current = false;\r\n\r\n const shouldReconnect =\r\n !suppressReconnectRef.current &&\r\n !skipCloseReconnect &&\r\n reconnectEnabled &&\r\n (options.shouldReconnect?.(event) ?? true);\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastChangedAt: Date.now(),\r\n lastCloseEvent: event,\r\n status: shouldReconnect ? \"reconnecting\" : \"closed\"\r\n }));\r\n\r\n options.onClose?.(event);\r\n\r\n if (shouldReconnect) {\r\n reconnect.schedule(\"close\");\r\n } else {\r\n suppressReconnectRef.current = false;\r\n }\r\n });\r\n\r\n const open = (): void => {\r\n manualCloseRef.current = false;\r\n manualOpenRef.current = true;\r\n suppressReconnectRef.current = false;\r\n reconnect.cancel();\r\n setOpenNonce((current) => current + 1);\r\n };\r\n\r\n const reconnectNow = (): void => {\r\n manualCloseRef.current = false;\r\n manualOpenRef.current = true;\r\n skipCloseReconnectRef.current = true;\r\n suppressReconnectRef.current = true;\r\n heartbeat.stop();\r\n closeSocket();\r\n suppressReconnectRef.current = false;\r\n reconnect.schedule(\"manual\");\r\n };\r\n\r\n const close = (code?: number, reason?: string): void => {\r\n manualCloseRef.current = true;\r\n manualOpenRef.current = false;\r\n suppressReconnectRef.current = true;\r\n reconnect.cancel();\r\n heartbeat.stop();\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastChangedAt: Date.now(),\r\n status: \"closing\"\r\n }));\r\n\r\n closeSocket(code, reason);\r\n };\r\n\r\n const send = (message: TOutgoing): boolean => {\r\n const socket = socketRef.current;\r\n\r\n if (socket === null || socket.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n\r\n const serializer = options.serializeMessage ?? defaultSerializeMessage<TOutgoing>;\r\n socket.send(serializer(message));\r\n updateBufferedAmount();\r\n return true;\r\n };\r\n\r\n useEffect(() => {\r\n if (!supported) {\r\n socketKeyRef.current = null;\r\n commitState((current) => ({\r\n ...current,\r\n status: \"closed\"\r\n }));\r\n return;\r\n }\r\n\r\n if (resolvedUrl === null) {\r\n socketKeyRef.current = null;\r\n closeSocket();\r\n commitState((current) => ({\r\n ...current,\r\n status: \"closed\"\r\n }));\r\n return;\r\n }\r\n\r\n const shouldConnect =\r\n (connect && !manualCloseRef.current) ||\r\n manualOpenRef.current ||\r\n reconnect.status === \"running\";\r\n const nextSocketKey = `${resolvedUrl}::${protocolsDependency}::${options.binaryType ?? \"blob\"}`;\r\n\r\n if (!shouldConnect) {\r\n if (socketRef.current !== null) {\r\n suppressReconnectRef.current = true;\r\n closeSocket();\r\n }\r\n\r\n socketKeyRef.current = null;\r\n commitState((current) => ({\r\n ...current,\r\n status: manualCloseRef.current ? \"closed\" : \"idle\"\r\n }));\r\n return;\r\n }\r\n\r\n if (socketRef.current !== null && socketKeyRef.current !== nextSocketKey) {\r\n suppressReconnectRef.current = true;\r\n closeSocket();\r\n }\r\n\r\n if (socketRef.current !== null) {\r\n return;\r\n }\r\n\r\n const socket = new WebSocket(resolvedUrl, options.protocols);\r\n socketRef.current = socket;\r\n socketKeyRef.current = nextSocketKey;\r\n socket.binaryType = options.binaryType ?? \"blob\";\r\n\r\n commitState((current) => ({\r\n ...current,\r\n bufferedAmount: socket.bufferedAmount,\r\n lastChangedAt: Date.now(),\r\n status:\r\n reconnect.status === \"running\" || reconnect.status === \"scheduled\"\r\n ? \"reconnecting\"\r\n : \"connecting\"\r\n }));\r\n\r\n const handleSocketOpen = (event: Event): void => {\r\n handleOpen(event, socket);\r\n };\r\n const handleSocketMessage = (event: MessageEvent<unknown>): void => {\r\n handleMessage(event);\r\n };\r\n const handleSocketError = (event: Event): void => {\r\n handleError(event);\r\n };\r\n const handleSocketClose = (event: CloseEvent): void => {\r\n handleClose(event);\r\n };\r\n\r\n socket.addEventListener(\"open\", handleSocketOpen);\r\n socket.addEventListener(\"message\", handleSocketMessage);\r\n socket.addEventListener(\"error\", handleSocketError);\r\n socket.addEventListener(\"close\", handleSocketClose);\r\n\r\n return () => {\r\n socket.removeEventListener(\"open\", handleSocketOpen);\r\n socket.removeEventListener(\"message\", handleSocketMessage);\r\n socket.removeEventListener(\"error\", handleSocketError);\r\n socket.removeEventListener(\"close\", handleSocketClose);\r\n };\r\n }, [\r\n connect,\r\n openNonce,\r\n options.binaryType,\r\n protocolsDependency,\r\n reconnect.status,\r\n resolvedUrl,\r\n supported\r\n ]);\r\n\r\n useEffect(() => () => {\r\n suppressReconnectRef.current = true;\r\n socketKeyRef.current = null;\r\n\r\n const socket = socketRef.current;\r\n socketRef.current = null;\r\n\r\n if (socket === null) {\r\n return;\r\n }\r\n\r\n if (\r\n socket.readyState === WebSocket.OPEN ||\r\n socket.readyState === WebSocket.CONNECTING\r\n ) {\r\n socket.close();\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (state.status !== \"open\") {\r\n heartbeat.stop();\r\n }\r\n }, [state.status]);\r\n\r\n const status =\r\n (reconnect.status === \"scheduled\" || reconnect.status === \"running\") &&\r\n state.status !== \"open\"\r\n ? \"reconnecting\"\r\n : state.status;\r\n\r\n const snapshot = createConnectionStateSnapshot(status, {\r\n isSupported: supported,\r\n lastChangedAt: state.lastChangedAt\r\n });\r\n const heartbeatState =\r\n options.heartbeat === false\r\n ? null\r\n : {\r\n hasTimedOut: heartbeat.hasTimedOut,\r\n isRunning: heartbeat.isRunning,\r\n lastAckAt: heartbeat.lastAckAt,\r\n lastBeatAt: heartbeat.lastBeatAt,\r\n latencyMs: heartbeat.latencyMs\r\n };\r\n const reconnectState =\r\n options.reconnect === false\r\n ? null\r\n : {\r\n attempt: reconnect.attempt,\r\n isScheduled: reconnect.isScheduled,\r\n nextDelayMs: reconnect.nextDelayMs,\r\n status: reconnect.status\r\n };\r\n const commonResult = {\r\n bufferedAmount: state.bufferedAmount,\r\n close,\r\n heartbeatState,\r\n lastCloseEvent: state.lastCloseEvent,\r\n lastError: state.lastError,\r\n lastMessage: state.lastMessage,\r\n lastMessageEvent: state.lastMessageEvent,\r\n open,\r\n reconnect: reconnectNow,\r\n reconnectState,\r\n send,\r\n transport: \"websocket\" as const\r\n };\r\n const socket = socketRef.current;\r\n\r\n if (snapshot.status === \"open\") {\r\n return {\r\n ...snapshot,\r\n ...commonResult,\r\n socket: socket as WebSocket\r\n };\r\n }\r\n\r\n return {\r\n ...snapshot,\r\n ...commonResult,\r\n socket\r\n };\r\n};\r\n","import { useEffect, useEffectEvent, useMemo, useRef, useState } from \"react\";\r\n\r\nimport { createConnectionStateSnapshot } from \"../core/connection-state\";\r\nimport { isEventSourceSupported } from \"../core/env\";\r\nimport { resolveUrlProvider } from \"../core/url\";\r\nimport { useReconnect } from \"./useReconnect\";\r\nimport type {\r\n UseEventSourceHook,\r\n UseEventSourceOptions,\r\n UseEventSourceResult\r\n} from \"../types/useEventSource\";\r\n\r\ntype EventSourceState<TMessage> = {\r\n lastChangedAt: number | null;\r\n lastError: Event | null;\r\n lastEventName: string | null;\r\n lastMessage: TMessage | null;\r\n lastMessageEvent: MessageEvent<string> | null;\r\n status: UseEventSourceResult<TMessage>[\"status\"];\r\n};\r\n\r\nconst createInitialState = <TMessage,>(\r\n status: UseEventSourceResult<TMessage>[\"status\"] = \"idle\"\r\n): EventSourceState<TMessage> => ({\r\n lastChangedAt: null,\r\n lastError: null,\r\n lastEventName: null,\r\n lastMessage: null,\r\n lastMessageEvent: null,\r\n status\r\n});\r\n\r\nconst defaultParseMessage = <TMessage,>(\r\n event: MessageEvent<string>\r\n): TMessage => event.data as TMessage;\r\n\r\nconst toEventsDependency = (events: readonly string[] | undefined): string => {\r\n if (events === undefined || events.length === 0) {\r\n return \"\";\r\n }\r\n\r\n return [...new Set(events)].sort().join(\"|\");\r\n};\r\n\r\nconst normalizeNamedEvents = (\r\n events: readonly string[] | undefined\r\n): string[] => {\r\n if (events === undefined || events.length === 0) {\r\n return [];\r\n }\r\n\r\n return [...new Set(events)].filter((eventName) => eventName !== \"message\");\r\n};\r\n\r\nexport const useEventSource: UseEventSourceHook = <TMessage = unknown>(\r\n options: UseEventSourceOptions<TMessage>\r\n): UseEventSourceResult<TMessage> => {\r\n const connect = options.connect ?? true;\r\n const supported = isEventSourceSupported();\r\n const resolvedUrl = useMemo(() => resolveUrlProvider(options.url), [options.url]);\r\n const eventsDependency = toEventsDependency(options.events);\r\n const namedEvents = useMemo(\r\n () => normalizeNamedEvents(options.events),\r\n [eventsDependency]\r\n );\r\n\r\n const eventSourceRef = useRef<EventSource | null>(null);\r\n const eventSourceKeyRef = useRef<string | null>(null);\r\n const manualCloseRef = useRef(false);\r\n const manualOpenRef = useRef(false);\r\n const skipErrorReconnectRef = useRef(false);\r\n const suppressReconnectRef = useRef(false);\r\n const [openNonce, setOpenNonce] = useState(0);\r\n const [state, setState] = useState<EventSourceState<TMessage>>(() =>\r\n createInitialState(connect ? \"connecting\" : \"idle\")\r\n );\r\n const stateRef = useRef(state);\r\n stateRef.current = state;\r\n\r\n const reconnectEnabled =\r\n options.reconnect !== false && supported && resolvedUrl !== null;\r\n const reconnect = useReconnect(\r\n options.reconnect === false\r\n ? { enabled: false }\r\n : {\r\n ...options.reconnect,\r\n enabled: reconnectEnabled && (options.reconnect?.enabled ?? true)\r\n }\r\n );\r\n\r\n const commitState = (\r\n next:\r\n | EventSourceState<TMessage>\r\n | ((current: EventSourceState<TMessage>) => EventSourceState<TMessage>)\r\n ): void => {\r\n const resolved = typeof next === \"function\" ? next(stateRef.current) : next;\r\n stateRef.current = resolved;\r\n setState(resolved);\r\n };\r\n\r\n const closeEventSource = useEffectEvent(() => {\r\n const source = eventSourceRef.current;\r\n\r\n if (source === null) {\r\n return;\r\n }\r\n\r\n eventSourceRef.current = null;\r\n eventSourceKeyRef.current = null;\r\n source.close();\r\n });\r\n\r\n const parseMessage = useEffectEvent((event: MessageEvent<string>) => {\r\n const parser = options.parseMessage ?? defaultParseMessage<TMessage>;\r\n return parser(event);\r\n });\r\n\r\n const handleOpen = useEffectEvent((event: Event, source: EventSource) => {\r\n manualCloseRef.current = false;\r\n suppressReconnectRef.current = false;\r\n reconnect.markConnected();\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastChangedAt: Date.now(),\r\n status: \"open\"\r\n }));\r\n\r\n options.onOpen?.(event, source);\r\n });\r\n\r\n const commitParsedMessage = useEffectEvent(\r\n (eventName: string, event: MessageEvent<string>, isNamedEvent: boolean) => {\r\n try {\r\n const message = parseMessage(event);\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastEventName: eventName,\r\n lastMessage: message,\r\n lastMessageEvent: event\r\n }));\r\n\r\n if (isNamedEvent) {\r\n options.onEvent?.(eventName, message, event);\r\n return;\r\n }\r\n\r\n options.onMessage?.(message, event);\r\n } catch {\r\n const parseError = new Event(\"error\");\r\n commitState((current) => ({\r\n ...current,\r\n lastError: parseError,\r\n status: \"error\"\r\n }));\r\n }\r\n }\r\n );\r\n\r\n const handleError = useEffectEvent((event: Event, source: EventSource) => {\r\n const skipErrorReconnect = skipErrorReconnectRef.current;\r\n skipErrorReconnectRef.current = false;\r\n const shouldReconnect =\r\n !suppressReconnectRef.current &&\r\n !skipErrorReconnect &&\r\n reconnectEnabled &&\r\n (options.shouldReconnect?.(event) ?? true);\r\n\r\n const readyState = source.readyState;\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastChangedAt: Date.now(),\r\n lastError: event,\r\n status:\r\n readyState === EventSource.OPEN\r\n ? \"open\"\r\n : shouldReconnect\r\n ? \"reconnecting\"\r\n : \"closed\"\r\n }));\r\n\r\n options.onError?.(event);\r\n\r\n if (!shouldReconnect) {\r\n suppressReconnectRef.current = false;\r\n closeEventSource();\r\n return;\r\n }\r\n\r\n if (readyState === EventSource.CLOSED) {\r\n eventSourceRef.current = null;\r\n eventSourceKeyRef.current = null;\r\n reconnect.schedule(\"error\");\r\n }\r\n });\r\n\r\n const open = (): void => {\r\n manualCloseRef.current = false;\r\n manualOpenRef.current = true;\r\n suppressReconnectRef.current = false;\r\n reconnect.cancel();\r\n setOpenNonce((current) => current + 1);\r\n };\r\n\r\n const reconnectNow = (): void => {\r\n manualCloseRef.current = false;\r\n manualOpenRef.current = true;\r\n skipErrorReconnectRef.current = true;\r\n suppressReconnectRef.current = true;\r\n closeEventSource();\r\n suppressReconnectRef.current = false;\r\n reconnect.schedule(\"manual\");\r\n };\r\n\r\n const close = (): void => {\r\n manualCloseRef.current = true;\r\n manualOpenRef.current = false;\r\n suppressReconnectRef.current = true;\r\n reconnect.cancel();\r\n closeEventSource();\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastChangedAt: Date.now(),\r\n status: \"closed\"\r\n }));\r\n };\r\n\r\n useEffect(() => {\r\n if (!supported) {\r\n eventSourceKeyRef.current = null;\r\n commitState((current) => ({\r\n ...current,\r\n status: \"closed\"\r\n }));\r\n return;\r\n }\r\n\r\n if (resolvedUrl === null) {\r\n eventSourceKeyRef.current = null;\r\n closeEventSource();\r\n commitState((current) => ({\r\n ...current,\r\n status: \"closed\"\r\n }));\r\n return;\r\n }\r\n\r\n const shouldConnect =\r\n (connect && !manualCloseRef.current) ||\r\n manualOpenRef.current ||\r\n reconnect.status === \"running\";\r\n const nextEventSourceKey = [\r\n resolvedUrl,\r\n options.withCredentials ? \"credentials\" : \"anonymous\",\r\n eventsDependency\r\n ].join(\"::\");\r\n\r\n if (!shouldConnect) {\r\n if (eventSourceRef.current !== null) {\r\n suppressReconnectRef.current = true;\r\n closeEventSource();\r\n }\r\n\r\n eventSourceKeyRef.current = null;\r\n commitState((current) => ({\r\n ...current,\r\n status: manualCloseRef.current ? \"closed\" : \"idle\"\r\n }));\r\n return;\r\n }\r\n\r\n if (\r\n eventSourceRef.current !== null &&\r\n eventSourceKeyRef.current !== nextEventSourceKey\r\n ) {\r\n suppressReconnectRef.current = true;\r\n closeEventSource();\r\n }\r\n\r\n if (eventSourceRef.current !== null) {\r\n return;\r\n }\r\n\r\n const source = new EventSource(resolvedUrl, {\r\n withCredentials: options.withCredentials ?? false\r\n });\r\n\r\n eventSourceRef.current = source;\r\n eventSourceKeyRef.current = nextEventSourceKey;\r\n\r\n commitState((current) => ({\r\n ...current,\r\n lastChangedAt: Date.now(),\r\n status:\r\n reconnect.status === \"running\" || reconnect.status === \"scheduled\"\r\n ? \"reconnecting\"\r\n : \"connecting\"\r\n }));\r\n\r\n const handleSourceOpen = (event: Event): void => {\r\n handleOpen(event, source);\r\n };\r\n const handleSourceMessage = (event: Event): void => {\r\n commitParsedMessage(\"message\", event as MessageEvent<string>, false);\r\n };\r\n const namedEventHandlers = new Map<\r\n string,\r\n (event: Event) => void\r\n >();\r\n const handleSourceError = (event: Event): void => {\r\n handleError(event, source);\r\n };\r\n\r\n source.addEventListener(\"open\", handleSourceOpen);\r\n source.addEventListener(\"message\", handleSourceMessage);\r\n\r\n for (const eventName of namedEvents) {\r\n const handler = (event: Event): void => {\r\n commitParsedMessage(eventName, event as MessageEvent<string>, true);\r\n };\r\n\r\n namedEventHandlers.set(eventName, handler);\r\n source.addEventListener(eventName, handler);\r\n }\r\n\r\n source.addEventListener(\"error\", handleSourceError);\r\n\r\n return () => {\r\n source.removeEventListener(\"open\", handleSourceOpen);\r\n source.removeEventListener(\"message\", handleSourceMessage);\r\n\r\n for (const [eventName, handler] of namedEventHandlers) {\r\n source.removeEventListener(eventName, handler);\r\n }\r\n\r\n source.removeEventListener(\"error\", handleSourceError);\r\n };\r\n }, [\r\n connect,\r\n eventsDependency,\r\n namedEvents,\r\n openNonce,\r\n options.withCredentials,\r\n reconnect.status,\r\n resolvedUrl,\r\n supported\r\n ]);\r\n\r\n useEffect(() => () => {\r\n suppressReconnectRef.current = true;\r\n eventSourceKeyRef.current = null;\r\n\r\n const source = eventSourceRef.current;\r\n eventSourceRef.current = null;\r\n\r\n if (source !== null) {\r\n source.close();\r\n }\r\n }, []);\r\n\r\n const status =\r\n (reconnect.status === \"scheduled\" || reconnect.status === \"running\") &&\r\n state.status !== \"open\"\r\n ? \"reconnecting\"\r\n : state.status;\r\n\r\n const snapshot = createConnectionStateSnapshot(status, {\r\n isSupported: supported,\r\n lastChangedAt: state.lastChangedAt\r\n });\r\n const reconnectState =\r\n options.reconnect === false\r\n ? null\r\n : {\r\n attempt: reconnect.attempt,\r\n isScheduled: reconnect.isScheduled,\r\n nextDelayMs: reconnect.nextDelayMs,\r\n status: reconnect.status\r\n };\r\n const commonResult = {\r\n close,\r\n lastError: state.lastError,\r\n lastEventName: state.lastEventName,\r\n lastMessage: state.lastMessage,\r\n lastMessageEvent: state.lastMessageEvent,\r\n open,\r\n reconnect: reconnectNow,\r\n reconnectState,\r\n transport: \"eventsource\" as const\r\n };\r\n const eventSource = eventSourceRef.current;\r\n\r\n if (snapshot.status === \"open\") {\r\n return {\r\n ...snapshot,\r\n ...commonResult,\r\n eventSource: eventSource as EventSource\r\n };\r\n }\r\n\r\n return {\r\n ...snapshot,\r\n ...commonResult,\r\n eventSource\r\n };\r\n};\r\n"]}
@@ -0,0 +1,216 @@
1
+ interface UseOnlineStatusOptions {
2
+ initialOnline?: boolean;
3
+ trackTransitions?: boolean;
4
+ }
5
+ interface UseOnlineStatusResult {
6
+ isOnline: boolean;
7
+ isSupported: boolean;
8
+ lastChangedAt: number | null;
9
+ wentOnlineAt: number | null;
10
+ wentOfflineAt: number | null;
11
+ }
12
+ type UseOnlineStatusHook = (options?: UseOnlineStatusOptions) => UseOnlineStatusResult;
13
+
14
+ declare const useOnlineStatus: UseOnlineStatusHook;
15
+
16
+ type ReconnectStatus = "idle" | "scheduled" | "running" | "stopped";
17
+ type ReconnectTrigger = "mount" | "manual" | "close" | "error" | "heartbeat-timeout" | "offline" | "online" | "visibility";
18
+ interface ReconnectAttempt {
19
+ attempt: number;
20
+ delayMs: number;
21
+ trigger: ReconnectTrigger;
22
+ scheduledAt: number;
23
+ }
24
+ interface ReconnectDelayContext {
25
+ attempt: number;
26
+ lastDelayMs: number | null;
27
+ initialDelayMs: number;
28
+ maxDelayMs: number;
29
+ backoffFactor: number;
30
+ jitterRatio: number;
31
+ }
32
+ type ReconnectDelayStrategy = (context: ReconnectDelayContext) => number;
33
+ interface UseReconnectOptions {
34
+ enabled?: boolean;
35
+ maxAttempts?: number | null;
36
+ initialDelayMs?: number;
37
+ maxDelayMs?: number;
38
+ backoffFactor?: number;
39
+ jitterRatio?: number;
40
+ getDelayMs?: ReconnectDelayStrategy;
41
+ resetOnSuccess?: boolean;
42
+ onSchedule?: (attempt: ReconnectAttempt) => void;
43
+ onCancel?: () => void;
44
+ onReset?: () => void;
45
+ }
46
+ interface UseReconnectResult {
47
+ status: ReconnectStatus;
48
+ attempt: number;
49
+ nextDelayMs: number | null;
50
+ isActive: boolean;
51
+ isScheduled: boolean;
52
+ schedule: (trigger?: ReconnectTrigger) => void;
53
+ cancel: () => void;
54
+ reset: () => void;
55
+ markConnected: () => void;
56
+ }
57
+ type UseReconnectHook = (options?: UseReconnectOptions) => UseReconnectResult;
58
+
59
+ declare const useReconnect: UseReconnectHook;
60
+
61
+ type HeartbeatBeatFn = () => void | boolean | Promise<void | boolean>;
62
+ type HeartbeatAckMatcher<TMessage> = (message: TMessage) => boolean;
63
+ interface UseHeartbeatOptions<TOutgoing = unknown, TIncoming = TOutgoing> {
64
+ enabled?: boolean;
65
+ intervalMs: number;
66
+ timeoutMs?: number;
67
+ message?: TOutgoing | (() => TOutgoing);
68
+ beat?: HeartbeatBeatFn;
69
+ matchesAck?: HeartbeatAckMatcher<TIncoming>;
70
+ startOnMount?: boolean;
71
+ onBeat?: () => void;
72
+ onTimeout?: () => void;
73
+ }
74
+ interface UseHeartbeatResult<TIncoming = unknown> {
75
+ isRunning: boolean;
76
+ hasTimedOut: boolean;
77
+ lastBeatAt: number | null;
78
+ lastAckAt: number | null;
79
+ latencyMs: number | null;
80
+ start: () => void;
81
+ stop: () => void;
82
+ beat: () => void;
83
+ notifyAck: (message: TIncoming) => boolean;
84
+ }
85
+ type UseHeartbeatHook = <TOutgoing = unknown, TIncoming = TOutgoing>(options: UseHeartbeatOptions<TOutgoing, TIncoming>) => UseHeartbeatResult<TIncoming>;
86
+
87
+ declare const useHeartbeat: <TOutgoing = unknown, TIncoming = TOutgoing>(options: UseHeartbeatOptions<TOutgoing, TIncoming>) => UseHeartbeatResult<TIncoming>;
88
+
89
+ type RealtimeConnectionStatus = "idle" | "connecting" | "open" | "closing" | "closed" | "reconnecting" | "error";
90
+ type RealtimeTransport = "websocket" | "eventsource";
91
+ type Milliseconds = number;
92
+ type UrlProvider = string | URL | (() => string | URL | null);
93
+ type ConnectionStateSnapshotBase = {
94
+ isSupported: boolean;
95
+ lastChangedAt: number | null;
96
+ };
97
+ type ConnectionStateSnapshot = (ConnectionStateSnapshotBase & {
98
+ isClosed: false;
99
+ isConnected: true;
100
+ isConnecting: false;
101
+ status: "open";
102
+ }) | (ConnectionStateSnapshotBase & {
103
+ isClosed: false;
104
+ isConnected: false;
105
+ isConnecting: true;
106
+ status: "connecting" | "reconnecting";
107
+ }) | (ConnectionStateSnapshotBase & {
108
+ isClosed: false;
109
+ isConnected: false;
110
+ isConnecting: false;
111
+ status: "closing";
112
+ }) | (ConnectionStateSnapshotBase & {
113
+ isClosed: true;
114
+ isConnected: false;
115
+ isConnecting: false;
116
+ status: "idle" | "closed" | "error";
117
+ });
118
+ type MessageParser<TMessage> = (event: MessageEvent<unknown>) => TMessage;
119
+ type MessageSerializer<TMessage> = (message: TMessage) => string | ArrayBufferLike | Blob | ArrayBufferView;
120
+
121
+ interface UseWebSocketOptions<TIncoming = unknown, TOutgoing = TIncoming> {
122
+ url: UrlProvider;
123
+ protocols?: string | string[];
124
+ connect?: boolean;
125
+ binaryType?: BinaryType;
126
+ parseMessage?: MessageParser<TIncoming>;
127
+ serializeMessage?: MessageSerializer<TOutgoing>;
128
+ reconnect?: false | UseReconnectOptions;
129
+ heartbeat?: false | UseHeartbeatOptions<TOutgoing, TIncoming>;
130
+ shouldReconnect?: (event: CloseEvent | Event | undefined) => boolean;
131
+ onOpen?: (event: Event, socket: WebSocket) => void;
132
+ onMessage?: (message: TIncoming, event: MessageEvent<unknown>) => void;
133
+ onError?: (event: Event) => void;
134
+ onClose?: (event: CloseEvent) => void;
135
+ }
136
+ type UseWebSocketResultBase<TIncoming, TOutgoing> = {
137
+ transport: Extract<RealtimeTransport, "websocket">;
138
+ lastMessage: TIncoming | null;
139
+ lastMessageEvent: MessageEvent<unknown> | null;
140
+ lastCloseEvent: CloseEvent | null;
141
+ lastError: Event | null;
142
+ bufferedAmount: number;
143
+ reconnectState: Pick<UseReconnectResult, "status" | "attempt" | "nextDelayMs" | "isScheduled"> | null;
144
+ heartbeatState: Pick<UseHeartbeatResult<TIncoming>, "isRunning" | "hasTimedOut" | "lastBeatAt" | "lastAckAt" | "latencyMs"> | null;
145
+ open: () => void;
146
+ close: (code?: number, reason?: string) => void;
147
+ reconnect: () => void;
148
+ send: (message: TOutgoing) => boolean;
149
+ };
150
+ type UseWebSocketResult<TIncoming = unknown, TOutgoing = TIncoming> = (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
151
+ status: "open";
152
+ }> & {
153
+ socket: WebSocket;
154
+ }) | (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
155
+ status: "connecting" | "reconnecting";
156
+ }> & {
157
+ socket: WebSocket | null;
158
+ }) | (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
159
+ status: "closing";
160
+ }> & {
161
+ socket: WebSocket | null;
162
+ }) | (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
163
+ status: "idle" | "closed" | "error";
164
+ }> & {
165
+ socket: WebSocket | null;
166
+ });
167
+ type UseWebSocketHook = <TIncoming = unknown, TOutgoing = TIncoming>(options: UseWebSocketOptions<TIncoming, TOutgoing>) => UseWebSocketResult<TIncoming, TOutgoing>;
168
+
169
+ declare const useWebSocket: UseWebSocketHook;
170
+
171
+ interface UseEventSourceOptions<TMessage = unknown> {
172
+ url: UrlProvider;
173
+ withCredentials?: boolean;
174
+ connect?: boolean;
175
+ events?: readonly string[];
176
+ parseMessage?: MessageParser<TMessage>;
177
+ reconnect?: false | UseReconnectOptions;
178
+ shouldReconnect?: (event: Event | undefined) => boolean;
179
+ onOpen?: (event: Event, source: EventSource) => void;
180
+ onMessage?: (message: TMessage, event: MessageEvent<string>) => void;
181
+ onError?: (event: Event) => void;
182
+ onEvent?: (eventName: string, message: TMessage, event: MessageEvent<string>) => void;
183
+ }
184
+ type UseEventSourceResultBase<TMessage> = {
185
+ transport: Extract<RealtimeTransport, "eventsource">;
186
+ lastEventName: string | null;
187
+ lastMessage: TMessage | null;
188
+ lastMessageEvent: MessageEvent<string> | null;
189
+ lastError: Event | null;
190
+ reconnectState: Pick<UseReconnectResult, "status" | "attempt" | "nextDelayMs" | "isScheduled"> | null;
191
+ open: () => void;
192
+ close: () => void;
193
+ reconnect: () => void;
194
+ };
195
+ type UseEventSourceResult<TMessage = unknown> = (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
196
+ status: "open";
197
+ }> & {
198
+ eventSource: EventSource;
199
+ }) | (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
200
+ status: "connecting" | "reconnecting";
201
+ }> & {
202
+ eventSource: EventSource | null;
203
+ }) | (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
204
+ status: "closing";
205
+ }> & {
206
+ eventSource: EventSource | null;
207
+ }) | (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
208
+ status: "idle" | "closed" | "error";
209
+ }> & {
210
+ eventSource: EventSource | null;
211
+ });
212
+ type UseEventSourceHook = <TMessage = unknown>(options: UseEventSourceOptions<TMessage>) => UseEventSourceResult<TMessage>;
213
+
214
+ declare const useEventSource: UseEventSourceHook;
215
+
216
+ export { type ConnectionStateSnapshot, type HeartbeatAckMatcher, type HeartbeatBeatFn, type MessageParser, type MessageSerializer, type Milliseconds, type RealtimeConnectionStatus, type RealtimeTransport, type ReconnectAttempt, type ReconnectDelayContext, type ReconnectDelayStrategy, type ReconnectStatus, type ReconnectTrigger, type UrlProvider, type UseEventSourceHook, type UseEventSourceOptions, type UseEventSourceResult, type UseHeartbeatHook, type UseHeartbeatOptions, type UseHeartbeatResult, type UseOnlineStatusHook, type UseOnlineStatusOptions, type UseOnlineStatusResult, type UseReconnectHook, type UseReconnectOptions, type UseReconnectResult, type UseWebSocketHook, type UseWebSocketOptions, type UseWebSocketResult, useEventSource, useHeartbeat, useOnlineStatus, useReconnect, useWebSocket };
@@ -0,0 +1,216 @@
1
+ interface UseOnlineStatusOptions {
2
+ initialOnline?: boolean;
3
+ trackTransitions?: boolean;
4
+ }
5
+ interface UseOnlineStatusResult {
6
+ isOnline: boolean;
7
+ isSupported: boolean;
8
+ lastChangedAt: number | null;
9
+ wentOnlineAt: number | null;
10
+ wentOfflineAt: number | null;
11
+ }
12
+ type UseOnlineStatusHook = (options?: UseOnlineStatusOptions) => UseOnlineStatusResult;
13
+
14
+ declare const useOnlineStatus: UseOnlineStatusHook;
15
+
16
+ type ReconnectStatus = "idle" | "scheduled" | "running" | "stopped";
17
+ type ReconnectTrigger = "mount" | "manual" | "close" | "error" | "heartbeat-timeout" | "offline" | "online" | "visibility";
18
+ interface ReconnectAttempt {
19
+ attempt: number;
20
+ delayMs: number;
21
+ trigger: ReconnectTrigger;
22
+ scheduledAt: number;
23
+ }
24
+ interface ReconnectDelayContext {
25
+ attempt: number;
26
+ lastDelayMs: number | null;
27
+ initialDelayMs: number;
28
+ maxDelayMs: number;
29
+ backoffFactor: number;
30
+ jitterRatio: number;
31
+ }
32
+ type ReconnectDelayStrategy = (context: ReconnectDelayContext) => number;
33
+ interface UseReconnectOptions {
34
+ enabled?: boolean;
35
+ maxAttempts?: number | null;
36
+ initialDelayMs?: number;
37
+ maxDelayMs?: number;
38
+ backoffFactor?: number;
39
+ jitterRatio?: number;
40
+ getDelayMs?: ReconnectDelayStrategy;
41
+ resetOnSuccess?: boolean;
42
+ onSchedule?: (attempt: ReconnectAttempt) => void;
43
+ onCancel?: () => void;
44
+ onReset?: () => void;
45
+ }
46
+ interface UseReconnectResult {
47
+ status: ReconnectStatus;
48
+ attempt: number;
49
+ nextDelayMs: number | null;
50
+ isActive: boolean;
51
+ isScheduled: boolean;
52
+ schedule: (trigger?: ReconnectTrigger) => void;
53
+ cancel: () => void;
54
+ reset: () => void;
55
+ markConnected: () => void;
56
+ }
57
+ type UseReconnectHook = (options?: UseReconnectOptions) => UseReconnectResult;
58
+
59
+ declare const useReconnect: UseReconnectHook;
60
+
61
+ type HeartbeatBeatFn = () => void | boolean | Promise<void | boolean>;
62
+ type HeartbeatAckMatcher<TMessage> = (message: TMessage) => boolean;
63
+ interface UseHeartbeatOptions<TOutgoing = unknown, TIncoming = TOutgoing> {
64
+ enabled?: boolean;
65
+ intervalMs: number;
66
+ timeoutMs?: number;
67
+ message?: TOutgoing | (() => TOutgoing);
68
+ beat?: HeartbeatBeatFn;
69
+ matchesAck?: HeartbeatAckMatcher<TIncoming>;
70
+ startOnMount?: boolean;
71
+ onBeat?: () => void;
72
+ onTimeout?: () => void;
73
+ }
74
+ interface UseHeartbeatResult<TIncoming = unknown> {
75
+ isRunning: boolean;
76
+ hasTimedOut: boolean;
77
+ lastBeatAt: number | null;
78
+ lastAckAt: number | null;
79
+ latencyMs: number | null;
80
+ start: () => void;
81
+ stop: () => void;
82
+ beat: () => void;
83
+ notifyAck: (message: TIncoming) => boolean;
84
+ }
85
+ type UseHeartbeatHook = <TOutgoing = unknown, TIncoming = TOutgoing>(options: UseHeartbeatOptions<TOutgoing, TIncoming>) => UseHeartbeatResult<TIncoming>;
86
+
87
+ declare const useHeartbeat: <TOutgoing = unknown, TIncoming = TOutgoing>(options: UseHeartbeatOptions<TOutgoing, TIncoming>) => UseHeartbeatResult<TIncoming>;
88
+
89
+ type RealtimeConnectionStatus = "idle" | "connecting" | "open" | "closing" | "closed" | "reconnecting" | "error";
90
+ type RealtimeTransport = "websocket" | "eventsource";
91
+ type Milliseconds = number;
92
+ type UrlProvider = string | URL | (() => string | URL | null);
93
+ type ConnectionStateSnapshotBase = {
94
+ isSupported: boolean;
95
+ lastChangedAt: number | null;
96
+ };
97
+ type ConnectionStateSnapshot = (ConnectionStateSnapshotBase & {
98
+ isClosed: false;
99
+ isConnected: true;
100
+ isConnecting: false;
101
+ status: "open";
102
+ }) | (ConnectionStateSnapshotBase & {
103
+ isClosed: false;
104
+ isConnected: false;
105
+ isConnecting: true;
106
+ status: "connecting" | "reconnecting";
107
+ }) | (ConnectionStateSnapshotBase & {
108
+ isClosed: false;
109
+ isConnected: false;
110
+ isConnecting: false;
111
+ status: "closing";
112
+ }) | (ConnectionStateSnapshotBase & {
113
+ isClosed: true;
114
+ isConnected: false;
115
+ isConnecting: false;
116
+ status: "idle" | "closed" | "error";
117
+ });
118
+ type MessageParser<TMessage> = (event: MessageEvent<unknown>) => TMessage;
119
+ type MessageSerializer<TMessage> = (message: TMessage) => string | ArrayBufferLike | Blob | ArrayBufferView;
120
+
121
+ interface UseWebSocketOptions<TIncoming = unknown, TOutgoing = TIncoming> {
122
+ url: UrlProvider;
123
+ protocols?: string | string[];
124
+ connect?: boolean;
125
+ binaryType?: BinaryType;
126
+ parseMessage?: MessageParser<TIncoming>;
127
+ serializeMessage?: MessageSerializer<TOutgoing>;
128
+ reconnect?: false | UseReconnectOptions;
129
+ heartbeat?: false | UseHeartbeatOptions<TOutgoing, TIncoming>;
130
+ shouldReconnect?: (event: CloseEvent | Event | undefined) => boolean;
131
+ onOpen?: (event: Event, socket: WebSocket) => void;
132
+ onMessage?: (message: TIncoming, event: MessageEvent<unknown>) => void;
133
+ onError?: (event: Event) => void;
134
+ onClose?: (event: CloseEvent) => void;
135
+ }
136
+ type UseWebSocketResultBase<TIncoming, TOutgoing> = {
137
+ transport: Extract<RealtimeTransport, "websocket">;
138
+ lastMessage: TIncoming | null;
139
+ lastMessageEvent: MessageEvent<unknown> | null;
140
+ lastCloseEvent: CloseEvent | null;
141
+ lastError: Event | null;
142
+ bufferedAmount: number;
143
+ reconnectState: Pick<UseReconnectResult, "status" | "attempt" | "nextDelayMs" | "isScheduled"> | null;
144
+ heartbeatState: Pick<UseHeartbeatResult<TIncoming>, "isRunning" | "hasTimedOut" | "lastBeatAt" | "lastAckAt" | "latencyMs"> | null;
145
+ open: () => void;
146
+ close: (code?: number, reason?: string) => void;
147
+ reconnect: () => void;
148
+ send: (message: TOutgoing) => boolean;
149
+ };
150
+ type UseWebSocketResult<TIncoming = unknown, TOutgoing = TIncoming> = (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
151
+ status: "open";
152
+ }> & {
153
+ socket: WebSocket;
154
+ }) | (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
155
+ status: "connecting" | "reconnecting";
156
+ }> & {
157
+ socket: WebSocket | null;
158
+ }) | (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
159
+ status: "closing";
160
+ }> & {
161
+ socket: WebSocket | null;
162
+ }) | (UseWebSocketResultBase<TIncoming, TOutgoing> & Extract<ConnectionStateSnapshot, {
163
+ status: "idle" | "closed" | "error";
164
+ }> & {
165
+ socket: WebSocket | null;
166
+ });
167
+ type UseWebSocketHook = <TIncoming = unknown, TOutgoing = TIncoming>(options: UseWebSocketOptions<TIncoming, TOutgoing>) => UseWebSocketResult<TIncoming, TOutgoing>;
168
+
169
+ declare const useWebSocket: UseWebSocketHook;
170
+
171
+ interface UseEventSourceOptions<TMessage = unknown> {
172
+ url: UrlProvider;
173
+ withCredentials?: boolean;
174
+ connect?: boolean;
175
+ events?: readonly string[];
176
+ parseMessage?: MessageParser<TMessage>;
177
+ reconnect?: false | UseReconnectOptions;
178
+ shouldReconnect?: (event: Event | undefined) => boolean;
179
+ onOpen?: (event: Event, source: EventSource) => void;
180
+ onMessage?: (message: TMessage, event: MessageEvent<string>) => void;
181
+ onError?: (event: Event) => void;
182
+ onEvent?: (eventName: string, message: TMessage, event: MessageEvent<string>) => void;
183
+ }
184
+ type UseEventSourceResultBase<TMessage> = {
185
+ transport: Extract<RealtimeTransport, "eventsource">;
186
+ lastEventName: string | null;
187
+ lastMessage: TMessage | null;
188
+ lastMessageEvent: MessageEvent<string> | null;
189
+ lastError: Event | null;
190
+ reconnectState: Pick<UseReconnectResult, "status" | "attempt" | "nextDelayMs" | "isScheduled"> | null;
191
+ open: () => void;
192
+ close: () => void;
193
+ reconnect: () => void;
194
+ };
195
+ type UseEventSourceResult<TMessage = unknown> = (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
196
+ status: "open";
197
+ }> & {
198
+ eventSource: EventSource;
199
+ }) | (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
200
+ status: "connecting" | "reconnecting";
201
+ }> & {
202
+ eventSource: EventSource | null;
203
+ }) | (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
204
+ status: "closing";
205
+ }> & {
206
+ eventSource: EventSource | null;
207
+ }) | (UseEventSourceResultBase<TMessage> & Extract<ConnectionStateSnapshot, {
208
+ status: "idle" | "closed" | "error";
209
+ }> & {
210
+ eventSource: EventSource | null;
211
+ });
212
+ type UseEventSourceHook = <TMessage = unknown>(options: UseEventSourceOptions<TMessage>) => UseEventSourceResult<TMessage>;
213
+
214
+ declare const useEventSource: UseEventSourceHook;
215
+
216
+ export { type ConnectionStateSnapshot, type HeartbeatAckMatcher, type HeartbeatBeatFn, type MessageParser, type MessageSerializer, type Milliseconds, type RealtimeConnectionStatus, type RealtimeTransport, type ReconnectAttempt, type ReconnectDelayContext, type ReconnectDelayStrategy, type ReconnectStatus, type ReconnectTrigger, type UrlProvider, type UseEventSourceHook, type UseEventSourceOptions, type UseEventSourceResult, type UseHeartbeatHook, type UseHeartbeatOptions, type UseHeartbeatResult, type UseOnlineStatusHook, type UseOnlineStatusOptions, type UseOnlineStatusResult, type UseReconnectHook, type UseReconnectOptions, type UseReconnectResult, type UseWebSocketHook, type UseWebSocketOptions, type UseWebSocketResult, useEventSource, useHeartbeat, useOnlineStatus, useReconnect, useWebSocket };