import { CID } from 'multiformats/cid'; import { type Options as PartysocketOptions } from 'partysocket/ws'; export type { PartysocketOptions }; export interface W3NameRecord { value: string; seq?: number; validity?: string; } /** * Debug info provided when a stale WebSocket connection is detected. */ export interface StaleConnectionInfo { /** When the WebSocket connection was established */ connectedAt: Date; /** When we last received a WebSocket message */ lastMessageAt: Date | null; /** How long since last message (ms) */ silenceDuration: number; /** The stale value from WebSocket */ staleValue: string | null; /** The current value from HTTP */ currentValue: string; } /** * Enriched IPNS update with parsed CID and change detection. * Backwards compatible - `.value` still works as before. */ export interface IpnsUpdate { /** Raw IPNS value string (e.g. '/ipfs/bafy...') — same as W3NameRecord.value */ value: string; /** Parsed CID if value is valid IPFS path, null otherwise */ cid: CID | null; /** Previous value (null on first update) */ lastValue: string | null; /** Whether this is a change from lastValue */ isNew: boolean; /** Original W3NameRecord for access to seq/validity */ record: W3NameRecord; } export interface WatchRawOptions { /** Called when the IPNS record is updated */ onUpdate: (record: W3NameRecord) => void; /** Called when an error occurs */ onError?: (error: Event | Error) => void; /** Called when the connection is opened */ onOpen?: () => void; /** Called when the connection is closed */ onClose?: (event: CloseEvent) => void; } export interface WatchRawSubscription { /** Close the WebSocket connection */ close: () => void; /** The underlying WebSocket instance */ ws: WebSocket; } /** * Low-level WebSocket watcher for IPNS (no reconnect logic). * Use this when you want full control over connection lifecycle. * For most cases, prefer `watchName` or `IpnsWatcher` which handle reconnection. * * @param nameBaseUrl - Base URL of a naming service that supports `/name//watch` (WebSocket) and `/name/` (HTTP) * @param name - The IPNS name/key to watch * @param options - Callback options * @returns Subscription with close() and ws * * @example * ```ts * const sub = watchNameRaw('https://name.example.com', 'k51qzi5u...', { * onUpdate: (record) => console.log('Update:', record.value), * onClose: () => console.log('Disconnected - handle reconnect yourself'), * }) * ``` */ export declare function watchNameRaw(nameBaseUrl: string, name: string, options: WatchRawOptions): WatchRawSubscription; export interface IpnsWatcherOptions { /** Called when the IPNS record is updated (enriched payload with CID and change detection) */ onUpdate: (update: IpnsUpdate) => void | Promise; /** Called when an error occurs */ onError?: (error: Error | Event) => void; /** Called when the connection is opened/reconnected */ onConnected?: () => void; /** Called when the connection is closed */ onDisconnected?: () => void; /** Fetch current IPNS state on first connect (default: false) */ fetchInitialState?: boolean; /** Fetch current IPNS state on reconnect to catch missed updates (default: true) */ catchUpOnReconnect?: boolean; /** If true, call onUpdate even when value hasn't changed (default: false) */ includeUnchanged?: boolean; /** * Enable periodic liveness checks via HTTP to detect zombie connections (default: true). * When enabled, periodically fetches current IPNS value and forces reconnect if it * differs from the last WebSocket update. */ livenessCheck?: boolean; /** * Liveness check interval in milliseconds (default: 3600000 = 1 hour). * Only used when livenessCheck is enabled. */ livenessCheckInterval?: number; /** * Called when a stale connection is detected (WebSocket missed updates). * Provides debug info about the connection state. */ onStaleConnection?: (info: StaleConnectionInfo) => void; /** * Partysocket options (passed through to ReconnectingWebSocket). * Useful options: startClosed, maxReconnectionDelay, minReconnectionDelay, etc. * @see https://github.com/partykit/partykit/tree/main/packages/partysocket */ wsOptions?: PartysocketOptions; } export declare class IpnsWatcher { private name; private nameBaseUrl; private ws; private lastKnownValue; private options; private isFirstConnect; private livenessTimer; private connectedAt; private lastMessageAt; constructor(nameBaseUrl: string, name: string, options: IpnsWatcherOptions); /** * Resolve current IPNS value via HTTP API to catch missed updates */ private checkForMissedUpdates; /** * Start periodic liveness checks to detect zombie connections. */ private startLivenessCheck; /** * Stop periodic liveness checks. */ private stopLivenessCheck; /** * Perform a single liveness check via HTTP. * If the HTTP value differs from lastKnownValue, the connection is stale. */ private performLivenessCheck; /** * Manually start/reconnect the WebSocket. * Only needed if you used `wsOptions: { startClosed: true }`. */ start(): void; /** * Alias for close() - for backward compatibility */ stop(): void; /** * Close the WebSocket connection and stop watching */ close(): void; /** * Get the last known IPNS value */ get lastValue(): string | null; /** * Get the WebSocket ready state */ get readyState(): number; } /** * Create an IPNS watcher with auto-reconnect and catch-up logic. * Convenience function that creates and returns an IpnsWatcher instance. * * @param nameBaseUrl - Base URL of a naming service that supports `/name//watch` (WebSocket) and `/name/` (HTTP) * @param name - The IPNS name/key to watch (e.g. "k51qzi5u...") * @param options - Callback options for handling events * @returns An IpnsWatcher instance with close() method */ export declare function watchName(nameBaseUrl: string, name: string, options: IpnsWatcherOptions): IpnsWatcher; /** * Watch an IPNS name and return updates as an async iterator. * Includes auto-reconnect - iterator continues through disconnections. * * @param nameBaseUrl - Base URL of a naming service that supports `/name//watch` (WebSocket) and `/name/` (HTTP) * @param name - The IPNS name/key to watch * @param signal - Optional AbortSignal to stop the watch * * @example * ```ts * const controller = new AbortController() * for await (const update of watchNameIterator('https://name.example.com', 'k51qzi5u...', controller.signal)) { * console.log('Update:', update.cid?.toString()) * } * ``` */ export declare function watchNameIterator(nameBaseUrl: string, name: string, signal?: AbortSignal): AsyncGenerator; //# sourceMappingURL=ipns-watcher.d.ts.map