import WebSocket from 'ws'; import { BaseWebSocketConnection } from './base-websocket'; export interface AppSyncNotification { id: string; table: string; pk: string; sk: string; tenantCode: string; action: string; content: Record; } interface AppSyncMessage { id?: string; type: string; payload?: Record; } export declare class AppSyncSubscriber extends BaseWebSocketConnection { private readonly realtimeUrl; private readonly host; /** * Agent token (`{tenantCode}:{tokenId}:{rawToken}`) sent via the * `Authorization` header. The AppSync Lambda authorizer validates it and * enforces tenant scope. This replaces the former master API key. */ private readonly authToken; private subscriptionId; private tenantCode; private messageHandler; private reconnectCallback; private persistentFailureCallback; private keepAliveTimer; private keepAliveTimeoutMs; /** * Whether the current connection attempt reached connection_ack. Reset to * false at the start of each attempt (in onWebSocketClose, after counting) * and set true on connection_ack. Used to distinguish a real, established * connection from an attempt that closed before ever acking (handshake * rejection or an immediate post-open drop). */ private ackedThisConnection; /** Consecutive connection attempts that closed without ever acking. */ private consecutiveConnectFailures; /** Guards the persistent-failure escalation so it fires at most once per streak. */ private persistentFailureNotified; constructor(appsyncUrl: string, authToken: string); subscribe(tenantCode: string, onMessage: (notification: AppSyncNotification) => void): void; onReconnect(callback: () => void): void; /** * Registers a callback fired when AppSync has failed to establish a working * realtime connection (never reaching connection_ack) for * APPSYNC_CONNECT_FAILURE_ESCALATION_THRESHOLD consecutive attempts. This is * the signal-agnostic degraded-state escalation: it covers a handshake * rejection (HTTP 401), an invalid/expired/empty agent token, and a Lambda * authorizer that is not enabled for the environment, all of which surface as * "closed without ack". Reconnection continues (transient issues self-heal); * the callback exists so the listener can surface the degraded state. Fires * at most once per failure streak (a successful ack resets it). Distinct from * onReconnect, which signals a successful transient recovery. */ onPersistentFailure(callback: () => void): void; protected createWebSocket(): WebSocket; protected onOpen(ws: WebSocket): void; protected onParsedMessage(msg: AppSyncMessage, resolveConnect?: (value: void) => void): void; protected onDisconnect(): void; protected onWebSocketClose(): void; protected onReconnected(): void; private buildConnectionUrl; private sendSubscription; private resetKeepAliveTimer; private clearKeepAliveTimer; } export {}; //# sourceMappingURL=appsync-subscriber.d.ts.map