@getlimelight/sdk 0.1.1
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.
- package/LICENSE.md +21 -0
- package/README.md +488 -0
- package/dist/index.d.mts +399 -0
- package/dist/index.d.ts +399 -0
- package/dist/index.js +1244 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1207 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types/console.ts","../src/types/core.ts","../src/types/graphql.ts","../src/helpers/detection/detectConsoleType.ts","../src/helpers/detection/detectSource.ts","../src/helpers/detection/getInitiator.ts","../src/helpers/graphql/detectGraphQlOperationType.ts","../src/helpers/graphql/isGraphQLRequest.ts","../src/helpers/graphql/parseGraphQL.ts","../src/constants/index.ts","../src/helpers/safety/redactSensitiveHeaders.ts","../src/helpers/safety/safeStringify.ts","../src/helpers/utils/serializeBody.ts","../src/helpers/utils/isDevelopment.ts","../src/helpers/utils/formatRequestName.ts","../src/limelight/interceptors/ConsoleInterceptor.ts","../src/protocol/protocol.ts","../src/limelight/interceptors/NetworkInterceptor.ts","../src/limelight/interceptors/XHRInterceptor.ts","../src/limelight/LimelightClient.ts"],"sourcesContent":["export { Limelight } from \"./limelight\";\nexport type { LimelightConfig } from \"./types\";\nexport * from \"./types\";\n","import { EventType } from \"./core\";\n\n/**\n * Console log levels\n */\nexport enum ConsoleLevel {\n LOG = \"log\",\n WARN = \"warn\",\n ERROR = \"error\",\n INFO = \"info\",\n DEBUG = \"debug\",\n TRACE = \"trace\",\n}\n\n/**\n * Where logs originate from\n */\nexport enum ConsoleSource {\n APP = \"app\",\n LIBRARY = \"library\",\n REACT_NATIVE = \"react-native\",\n NATIVE = \"native\",\n}\n\n/**\n * Type of console log\n */\nexport enum ConsoleType {\n EXCEPTION = \"exception\",\n WARNING = \"warning\",\n NETWORK = \"network\",\n PERFORMANCE = \"performance\",\n GENERAL = \"general\",\n}\n\n/**\n * Console log event from the app\n */\nexport interface ConsoleEvent {\n id: string;\n phase: \"CONSOLE\";\n type: EventType.CONSOLE;\n level: ConsoleLevel;\n timestamp: number;\n sessionId: string;\n source: ConsoleSource;\n consoleType: ConsoleType;\n args: string[];\n stackTrace?: string;\n}\n","import {\n GraphqlOprtation,\n GraphQLRequest,\n GraphQLResponse,\n ConsoleEvent,\n} from \"./index\";\n\n// ============================================================================\n// ENUMS\n// ============================================================================\n\nexport enum NetworkType {\n FETCH = \"fetch\",\n XHR = \"xhr\",\n GRAPHQL = \"graphql\",\n}\n\nexport enum NetworkPhase {\n CONNECT = \"CONNECT\",\n REQUEST = \"REQUEST\",\n RESPONSE = \"RESPONSE\",\n ERROR = \"ERROR\",\n}\n\nexport enum BodyFormat {\n TEXT = \"TEXT\",\n JSON = \"JSON\",\n FORM_DATA = \"FORM_DATA\",\n BLOB = \"BLOB\",\n ARRAY_BUFFER = \"ARRAY_BUFFER\",\n NONE = \"NONE\",\n UNSERIALIZABLE = \"UNSERIALIZABLE\",\n}\n\nexport enum HttpMethod {\n GET = \"GET\",\n POST = \"POST\",\n PUT = \"PUT\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n HEAD = \"HEAD\",\n OPTIONS = \"OPTIONS\",\n TRACE = \"TRACE\",\n CONNECT = \"CONNECT\",\n}\n\nexport enum HttpStatusClass {\n INFORMATIONAL = 100,\n SUCCESS = 200,\n REDIRECTION = 300,\n CLIENT_ERROR = 400,\n SERVER_ERROR = 500,\n}\n\n// ============================================================================\n// BODY SERIALIZATION\n// ============================================================================\n\n/**\n * Normalized serialized body format\n */\nexport interface SerializedBody {\n format: BodyFormat;\n size: number; // bytes (approx)\n preview: string; // truncated view (\"{...}\", \"[FormData]\", \"[Blob]\")\n raw?: string; // optional full string version when feasible\n}\n\n// ============================================================================\n// NETWORK EVENTS (sent by SDK)\n// ============================================================================\n\n/**\n * Base shape all network events share\n */\nexport interface BaseNetworkEvent {\n id: string; // request ID linking request/response/error\n sessionId: string;\n timestamp: number; // unix ms\n phase: NetworkPhase;\n networkType: NetworkType;\n graphql?: {\n operationName?: string;\n operationType?: GraphqlOprtation | null;\n variables?: any;\n query?: string;\n };\n}\n\n/**\n * The REQUEST event your RN client sends first\n */\nexport interface NetworkRequest extends BaseNetworkEvent {\n phase: NetworkPhase.REQUEST;\n url: string;\n method: HttpMethod;\n headers: Record<string, string>;\n body?: SerializedBody;\n name: string; // short friendly name (\"/posts\", \"countries\")\n initiator: string; // \"fetch()\", \"graphql()\", \"axios\", etc\n requestSize: number; // estimated byte size of outbound payload\n}\n\n/**\n * The RESPONSE event (2nd step)\n */\nexport interface NetworkResponse extends BaseNetworkEvent {\n phase: NetworkPhase.RESPONSE;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body?: SerializedBody;\n duration: number; // ms\n responseSize: number; // bytes\n redirected: boolean;\n ok: boolean;\n}\n\n/**\n * NETWORK ERROR (3rd possible outcome)\n */\nexport interface NetworkErrorEvent extends BaseNetworkEvent {\n phase: NetworkPhase.ERROR;\n errorMessage: string;\n stack?: string;\n}\n\n/**\n * CONNECT event (session start)\n */\nexport interface ConnectEvent {\n phase: NetworkPhase.CONNECT;\n sessionId: string;\n timestamp: number;\n data: {\n appName: string;\n platform: \"ios\" | \"android\";\n };\n}\n\n// ============================================================================\n// WEB UI HELPER TYPES\n// ============================================================================\n\n/**\n * Request with its corresponding response (for UI display)\n */\nexport interface NetworkRequestWithResponse extends NetworkRequest {\n response?: NetworkResponse;\n status?: number;\n duration?: number;\n error?: NetworkErrorEvent;\n}\n\nexport enum EventType {\n NETWORK = \"NETWORK\",\n CONSOLE = \"CONSOLE\",\n}\n\n// ============================================================================\n// UNION TYPES\n// ============================================================================\n/**\n * All possible events that can be sent over WebSocket\n */\nexport type NetworkEvent =\n | ConnectEvent\n | NetworkRequest\n | NetworkResponse\n | NetworkErrorEvent\n | GraphQLRequest\n | GraphQLResponse;\n\nexport type LimelightEvent = NetworkEvent | ConsoleEvent;\n\n// ============================================================================\n// SESSION\n// ============================================================================\nexport interface Session {\n id: string;\n appName: string;\n platform: \"ios\" | \"android\";\n connectedAt: number;\n}\n\n// ============================================================================\n// WEB UI HELPER TYPES\n// ============================================================================\n/**\n * Request with its corresponding response (for UI display)\n */\nexport interface NetworkRequestWithResponse extends NetworkRequest {\n response?: NetworkResponse;\n status?: number;\n duration?: number;\n}\n","import { NetworkRequest, NetworkResponse, NetworkType } from \"./index\";\n\n/**\n * GRAPHQL EXTENSIONS\n */\nexport interface GraphQLRequest extends NetworkRequest {\n networkType: NetworkType.GRAPHQL;\n query: string;\n variables?: Record<string, any>;\n operationName?: string;\n}\n\n/**\n * GRAPHQL Response\n */\nexport interface GraphQLResponse extends NetworkResponse {\n networkType: NetworkType.GRAPHQL;\n data?: any;\n errors?: any[];\n}\n\nexport enum GraphqlOprtation {\n QUERY = \"QUERY\",\n MUTATION = \"MUTATION\",\n SUB = \"SUBSCRIPTION\",\n}\n","import { ConsoleType } from \"@/types\";\n\n/**\n * Detects the type of console message based on its level and content.\n * @param level - The console log level (e.g., \"log\", \"warn\", \"error\", \"info\", \"debug\").\n * @param args - The arguments passed to the console method.\n * @returns The detected ConsoleType.\n */\nexport const detectConsoleType = (\n level: \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\" | \"trace\",\n args: any[]\n): ConsoleType => {\n const messageStr = args\n .map((arg) => {\n try {\n return typeof arg === \"object\" ? JSON.stringify(arg) : String(arg);\n } catch {\n return String(arg);\n }\n })\n .join(\" \")\n .toLowerCase();\n\n if (level === \"error\") {\n if (\n messageStr.includes(\"error:\") ||\n messageStr.includes(\"exception\") ||\n messageStr.includes(\"uncaught\") ||\n messageStr.includes(\"unhandled\") ||\n args.some((arg) => arg instanceof Error)\n ) {\n return ConsoleType.EXCEPTION;\n }\n }\n\n if (level === \"warn\") {\n return ConsoleType.WARNING;\n }\n\n if (\n messageStr.includes(\"network\") ||\n messageStr.includes(\"fetch\") ||\n messageStr.includes(\"request\") ||\n messageStr.includes(\"response\") ||\n messageStr.includes(\"http\") ||\n messageStr.includes(\"api\") ||\n messageStr.includes(\"graphql\") ||\n messageStr.includes(\"xhr\")\n ) {\n return ConsoleType.NETWORK;\n }\n\n if (\n messageStr.includes(\"performance\") ||\n messageStr.includes(\"slow\") ||\n messageStr.includes(\"render\") ||\n messageStr.includes(\"fps\") ||\n messageStr.includes(\"memory\") ||\n messageStr.includes(\"optimization\") ||\n messageStr.includes(\"bottleneck\")\n ) {\n return ConsoleType.PERFORMANCE;\n }\n\n return ConsoleType.GENERAL;\n};\n","import { ConsoleSource } from \"@/types\";\n/**\n * Detects the source of a console log by analyzing the stack trace.\n * @return {ConsoleSource} The detected source of the console log.\n */\nexport const detectLogSource = (): ConsoleSource => {\n try {\n const stack = new Error().stack;\n\n if (!stack) return ConsoleSource.APP;\n\n const stackLines = stack.split(\"\\n\");\n\n for (let i = 3; i < stackLines.length; i++) {\n const line = stackLines[i];\n\n if (line === undefined) return ConsoleSource.APP;\n\n if (\n line.includes(\"node_modules/react-native/\") ||\n line.includes(\"react-native/Libraries/\") ||\n line.includes(\"MessageQueue.js\") ||\n line.includes(\"BatchedBridge\")\n ) {\n return ConsoleSource.REACT_NATIVE;\n }\n\n if (line.includes(\"[native code]\") || line.includes(\"NativeModules\")) {\n return ConsoleSource.NATIVE;\n }\n\n if (!line.includes(\"node_modules/\")) {\n return ConsoleSource.APP;\n }\n\n if (!line.includes(\"node_modules/\")) {\n return ConsoleSource.APP;\n }\n }\n\n return ConsoleSource.APP;\n } catch {\n return ConsoleSource.APP;\n }\n};\n","/**\n * Gets the function name and file location of the caller that initiated the current function.\n * @returns A string representing the initiator function and its file location.\n */\nexport const getInitiator = (): string => {\n try {\n const stack = new Error().stack;\n if (!stack) return \"unknown\";\n\n const lines = stack.split(\"\\n\");\n const callerLine = lines[4] || lines[3];\n\n if (!callerLine) return \"unknown\";\n\n const match = callerLine.match(/at (.+) \\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n const [, functionName, filePath, line] = match;\n const fileName = filePath?.split(\"/\").pop();\n\n return `${functionName} (${fileName}:${line})`;\n }\n\n return callerLine.trim();\n } catch {\n return \"unknown\";\n }\n};\n","import { GraphqlOprtation } from \"@/types\";\n\n/**\n * Detects the GraphQL operation type from a query string.\n * @param query - The GraphQL query string.\n * @returns The detected GraphQL operation type or null if not detectable.\n */\nexport const detectGraphQlOperationType = (\n query?: string\n): GraphqlOprtation | null => {\n if (!query) return null;\n if (query.trim().startsWith(\"mutation\")) return GraphqlOprtation.MUTATION;\n if (query.trim().startsWith(\"subscription\")) return GraphqlOprtation.SUB;\n\n return GraphqlOprtation.QUERY;\n};\n","/**\n * Determines if a given request is a GraphQL request based on the URL and body content.\n */\nexport const isGraphQLRequest = (url: string, body: any): boolean => {\n const isGraphqlUrl = url.toLowerCase().includes(\"graphql\");\n\n const rawBody = typeof body === \"object\" && body !== null ? body.raw : body;\n\n if (typeof rawBody !== \"string\") return isGraphqlUrl;\n\n try {\n if (rawBody.includes('\"query\"') || rawBody.includes('\"operationName\"')) {\n return true;\n }\n } catch {}\n\n return isGraphqlUrl;\n};\n","import { NetworkRequest } from \"@/types\";\nimport { detectGraphQlOperationType } from \"./detectGraphQlOperationType\";\n\n/**\n * WARNING: Do NOT include raw variables or query literals in production payloads.\n * Variables and literals may contain sensitive user information.\n * Only operationName and operationType are safe to send at launch.\n *\n * Parses a GraphQL request body and extracts relevant information.\n * @param body - The request body to parse.\n * @returns An object containing GraphQL operation details or null if parsing fails.\n */\nexport const parseGraphQL = (body: any): NetworkRequest[\"graphql\"] | null => {\n try {\n // 1. Get the JSON object regardless of what's passed\n const parsed = typeof body === \"string\" ? JSON.parse(body) : body;\n\n // 2. Defensive check: ensure 'parsed' is an object and not null\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n\n // 3. Only return if there is at least a query (standard GraphQL)\n if (!parsed.query && !parsed.operationName) {\n return null;\n }\n\n return {\n operationName: parsed.operationName || undefined,\n operationType: detectGraphQlOperationType(parsed.query),\n variables: parsed.variables || undefined,\n query: parsed.query || undefined,\n };\n } catch {\n return null;\n }\n};\n","/**\n * Constants used throughout the Limelight application.\n */\nexport const SENSITIVE_HEADERS = [\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"x-api-key\",\n \"x-auth-token\",\n \"x-access-token\",\n \"api-key\",\n \"apikey\",\n \"proxy-authorization\",\n \"x-csrf-token\",\n \"x-xsrf-token\",\n \"x-auth\",\n \"auth-token\",\n \"access-token\",\n \"secret\",\n \"x-secret\",\n \"bearer\",\n];\n\n/**\n * The current protocol version used by Limelight.\n */\nexport const PROTOCOL_VERSION = \"0.1.0\";\n\n/**\n * Default port number for the Limelight WebSocket server.\n */\nexport const DEFAULT_PORT = 9090;\n\n/**\n * The WebSocket path for Limelight connections.\n */\nexport const WS_PATH = \"/limelight\";\n","import { SENSITIVE_HEADERS } from \"@/constants\";\n\n/**\n * Redacts sensitive headers from a given headers object.\n * @param {Record<string, string>} headers - The headers object to redact.\n */\nexport const redactSensitiveHeaders = (\n headers: Record<string, string>\n): Record<string, string> => {\n const redacted = { ...headers };\n\n Object.keys(redacted).forEach((key) => {\n if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n redacted[key] = \"[REDACTED]\";\n }\n });\n\n return redacted;\n};\n","/**\n * Safely stringifies a value, handling circular references, special types,\n * and non-serializable values.\n * @param {unknown} value - The value to stringify.\n * @param {number} [maxDepth=10] - Maximum depth to traverse objects.\n * @param {boolean} [pretty=false] - Whether to pretty-print the JSON.\n * @returns {string} The safely stringified JSON string.\n */\nexport const safeStringify = (\n value: unknown,\n maxDepth = 10,\n pretty = false\n): string => {\n const seen = new WeakMap<object, true>();\n\n const process = (val: unknown, currentDepth: number): any => {\n if (val === null) return null;\n if (val === undefined) return \"[undefined]\";\n if (typeof val === \"bigint\") return `${val}n`;\n if (typeof val === \"symbol\") return val.toString();\n if (typeof val === \"function\") {\n return `[Function: ${val.name || \"anonymous\"}]`;\n }\n if (typeof val !== \"object\") return val;\n\n if (currentDepth >= maxDepth) {\n return \"[Max Depth]\";\n }\n\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.set(val, true);\n\n if (val instanceof Error) {\n return {\n __type: \"Error\",\n name: val.name,\n message: val.message,\n stack: val.stack,\n };\n }\n\n if (val instanceof Date) {\n return val.toISOString();\n }\n\n if (val instanceof RegExp) {\n return val.toString();\n }\n\n if (val instanceof Map) {\n const obj: Record<string, any> = {};\n val.forEach((v, k) => {\n const key = typeof k === \"string\" ? k : String(k);\n obj[key] = process(v, currentDepth + 1);\n });\n return obj;\n }\n\n if (val instanceof Set) {\n return Array.from(val).map((v) => process(v, currentDepth + 1));\n }\n\n if (ArrayBuffer.isView(val)) {\n return `[${val.constructor.name}(${(val as any).length})]`;\n }\n\n if (Array.isArray(val)) {\n return val.map((item) => process(item, currentDepth + 1));\n }\n\n const result: Record<string, any> = {};\n for (const key in val) {\n if (Object.prototype.hasOwnProperty.call(val, key)) {\n result[key] = process((val as any)[key], currentDepth + 1);\n }\n }\n\n return result;\n };\n\n try {\n const processed = process(value, 0);\n return JSON.stringify(processed, null, pretty ? 2 : 0);\n } catch (error) {\n return JSON.stringify({\n __error: \"Stringification failed\",\n message: error instanceof Error ? error.message : String(error),\n });\n }\n};\n","import { BodyFormat, SerializedBody } from \"@/types\";\n\n/**\n * Serializes various body types into a normalized format.\n * Handles JSON, text, FormData, Blob, ArrayBuffer, and others.\n * Returns size estimates and previews for easy display.\n *\n * @param input The body input to serialize\n * @returns SerializedBody object or undefined\n */\nexport const serializeBody = (\n input: any,\n disableBodyCapture?: boolean\n): SerializedBody | undefined => {\n if (disableBodyCapture) {\n return { format: BodyFormat.NONE, size: 0, preview: \"\" };\n }\n\n if (!input) {\n return {\n format: BodyFormat.NONE,\n size: 0,\n preview: \"\",\n };\n }\n\n try {\n // JSON\n if (typeof input === \"object\") {\n const json = JSON.stringify(input);\n return {\n format: BodyFormat.JSON,\n size: json.length,\n preview: json.slice(0, 200),\n raw: json,\n };\n }\n\n // Text\n if (typeof input === \"string\") {\n return {\n format: BodyFormat.TEXT,\n size: input.length,\n preview: input.slice(0, 200),\n raw: input,\n };\n }\n\n // FormData\n if (typeof FormData !== \"undefined\" && input instanceof FormData) {\n return {\n format: BodyFormat.FORM_DATA,\n size: 0,\n preview: \"[FormData]\",\n };\n }\n\n // Blob\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n return {\n format: BodyFormat.BLOB,\n size: input.size,\n preview: \"[Blob]\",\n };\n }\n\n // ArrayBuffer\n if (input instanceof ArrayBuffer) {\n return {\n format: BodyFormat.ARRAY_BUFFER,\n size: input.byteLength,\n preview: \"[ArrayBuffer]\",\n };\n }\n\n // Fallback\n return {\n format: BodyFormat.UNSERIALIZABLE,\n size: 0,\n preview: String(input),\n };\n } catch {\n return {\n format: BodyFormat.UNSERIALIZABLE,\n size: 0,\n preview: \"[Unserializable]\",\n };\n }\n};\n","/**\n * Detects if the current environment is a development environment.\n * Supports React Native, Node.js, Vite, and Webpack.\n */\nexport const isDevelopment = (): boolean => {\n try {\n const g = globalThis as any;\n\n // 1. React Native (Hermes/Metro)\n // Check this first as it's the most specific\n if (typeof g.__DEV__ !== \"undefined\") return !!g.__DEV__;\n\n // 2. Node.js / Standard Bundlers\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV) {\n return process.env.NODE_ENV !== \"production\";\n }\n\n /**\n * 3. Vite / Modern ESM\n * We avoid using 'import.meta' literal to prevent Hermes/React Native from\n * throwing a Syntax Error during the parsing phase.\n */\n const importMeta = (g as any).import?.meta;\n if (importMeta?.env?.DEV) {\n return true;\n }\n\n // Fallback for Vite if the above doesn't catch it\n // @ts-ignore\n if (typeof g.import !== \"undefined\" && g.import.meta?.env?.DEV) {\n return true;\n }\n } catch (e) {\n // If anything fails (like a strict CSP), default to true for Dev tools\n return true;\n }\n\n return true;\n};\n","/**\n * Formats a request name based on the URL.\n * * Extracts the last segment of the URL path to use as the request name.\n * * If the URL is invalid, it returns the original URL.\n * * @param {string} url - The URL of the request.\n * * @returns {string} - The formatted request name.\n */\nexport const formatRequestName = (url: string) => {\n try {\n const urlObj = new URL(url);\n const path = urlObj.pathname;\n const segments = path.split(\"/\").filter(Boolean);\n return segments[segments.length - 1] || path || url;\n } catch {\n return url;\n }\n};\n","import { detectConsoleType, detectLogSource, safeStringify } from \"@/helpers\";\nimport {\n ConsoleEvent,\n ConsoleLevel,\n EventType,\n LimelightConfig,\n LimelightMessage,\n} from \"@/types\";\n\nexport class ConsoleInterceptor {\n private originalConsole: Partial<Console> = {};\n private counter = 0;\n private isSetup = false;\n private isInternalLog = false;\n private config: LimelightConfig | null = null;\n\n constructor(\n private sendMessage: (message: LimelightMessage) => void,\n private getSessionId: () => string\n ) {}\n\n /**\n * Sets up console interception by wrapping console methods.\n * Intercepts log, warn, error, info, debug, trace methods to capture console output.\n * Prevents double setup and infinite loops from internal logging.\n * @param {LimelightConfig} config - Configuration object for Limelight\n * @returns {void}\n */\n setup(config: LimelightConfig) {\n if (this.isSetup) {\n console.warn(\"[Limelight] Console interceptor already set up\");\n return;\n }\n this.isSetup = true;\n this.config = config;\n\n const self = this;\n const methods: ConsoleLevel[] = [\n ConsoleLevel.LOG,\n ConsoleLevel.WARN,\n ConsoleLevel.ERROR,\n ConsoleLevel.INFO,\n ConsoleLevel.DEBUG,\n ConsoleLevel.TRACE,\n ];\n\n methods.forEach((level) => {\n const original = console[level];\n this.originalConsole[level] = original;\n\n console[level] = function (...args: any[]) {\n if (self.isInternalLog) {\n return original.apply(console, args);\n }\n\n self.isInternalLog = true;\n\n try {\n const source = detectLogSource();\n const consoleType = detectConsoleType(level, args);\n const stackTrace = self.captureStackTrace();\n\n let consoleEvent: ConsoleEvent = {\n id: `${self.getSessionId()}-${Date.now()}-${self.counter++}`,\n phase: \"CONSOLE\",\n type: EventType.CONSOLE,\n level: level,\n timestamp: Date.now(),\n sessionId: self.getSessionId(),\n source: source,\n consoleType: consoleType,\n args: args.map((arg) => safeStringify(arg)),\n stackTrace: stackTrace,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(consoleEvent);\n\n if (!modifiedEvent) {\n return original.apply(console, args);\n }\n\n if (modifiedEvent.phase !== \"CONSOLE\") {\n console.error(\n \"[Limelight] beforeSend must return same event type\"\n );\n return original.apply(console, args);\n }\n\n consoleEvent = modifiedEvent as ConsoleEvent;\n }\n\n self.sendMessage(consoleEvent);\n } catch (error) {\n // Silently fail to avoid breaking user's console.log\n } finally {\n self.isInternalLog = false;\n }\n\n return original.apply(console, args);\n };\n });\n }\n\n /**\n * Captures the current stack trace, filtering out internal frames.\n * @private\n * @returns {string | undefined} Formatted stack trace or undefined if unavailable\n */\n private captureStackTrace(): string | undefined {\n try {\n const error = new Error();\n const stack = error.stack;\n\n if (!stack) return undefined;\n\n const relevantLines = stack\n .split(\"\\n\")\n .slice(3)\n .filter(\n (line) =>\n !line.includes(\"ConsoleInterceptor\") && !line.includes(\"limelight\")\n );\n\n return relevantLines.length > 0 ? relevantLines.join(\"\\n\") : undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Restores original console methods and removes all interception.\n * @returns {void}\n */\n cleanup() {\n if (!this.isSetup) {\n console.warn(\"[Limelight] Console interceptor not set up\");\n return;\n }\n this.isSetup = false;\n\n Object.entries(this.originalConsole).forEach(([method, fn]) => {\n if (fn) {\n (console as any)[method] = fn;\n }\n });\n\n this.originalConsole = {};\n }\n}\n","/**\n * Generates a unique session ID using the current timestamp and a random string.\n *\n * @return A unique session ID.\n */\nexport const createSessionId = (): string => {\n return `${Date.now()}-${Math.random().toString(36).substring(7)}`;\n};\n\n/**\n * Generates a unique request ID using the current timestamp and a random string.\n *\n * @return A unique request ID.\n */\nexport const generateRequestId = (): string => {\n return `req-${Date.now()}-${Math.random().toString(36).substring(7)}`;\n};\n","import {\n HttpMethod,\n LimelightConfig,\n LimelightMessage,\n NetworkErrorEvent,\n NetworkPhase,\n NetworkRequest,\n NetworkType,\n} from \"@/types\";\nimport {\n formatRequestName,\n getInitiator,\n isGraphQLRequest,\n parseGraphQL,\n redactSensitiveHeaders,\n serializeBody,\n} from \"@/helpers\";\nimport { generateRequestId } from \"@/protocol\";\n\nexport class NetworkInterceptor {\n private originalFetch: typeof fetch;\n private config: LimelightConfig | null = null;\n private isSetup = false;\n\n constructor(\n private sendMessage: (message: LimelightMessage) => void,\n private getSessionId: () => string\n ) {\n this.originalFetch = global.fetch;\n }\n\n /**\n * Sets up fetch interception by wrapping the global fetch function.\n * Intercepts all fetch requests to capture network events.\n * Prevents double setup to avoid losing original fetch reference.\n * @param {LimelightConfig} config - Configuration object for Limelight\n * @returns {void}\n */\n setup(config: LimelightConfig) {\n if (this.isSetup) {\n console.warn(\"[Limelight] Network interceptor already set up\");\n return;\n }\n this.isSetup = true;\n\n this.config = config;\n const self = this;\n\n global.fetch = async function (\n input: string | Request | URL,\n init: RequestInit = {}\n ): Promise<Response> {\n const requestId = generateRequestId();\n const startTime = Date.now();\n\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n const method = (init.method || \"GET\") as HttpMethod;\n\n const modifiedInit = { ...init };\n\n const headers: Record<string, string> = {};\n\n if (modifiedInit.headers instanceof Headers) {\n modifiedInit.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n } else if (modifiedInit.headers) {\n Object.entries(modifiedInit.headers).forEach(([key, value]) => {\n headers[key.toLowerCase()] = value;\n });\n }\n\n headers[\"x-limelight-intercepted\"] = \"fetch\";\n\n modifiedInit.headers = new Headers(headers);\n\n let requestBodyToSerialize = init.body;\n\n if (input instanceof Request && !requestBodyToSerialize) {\n try {\n const clonedRequest = input.clone();\n const contentType = clonedRequest.headers.get(\"content-type\") || \"\";\n\n if (\n contentType.includes(\"application/json\") ||\n contentType.includes(\"text/\")\n ) {\n requestBodyToSerialize = await clonedRequest.text();\n } else {\n requestBodyToSerialize = await clonedRequest.blob();\n }\n } catch {\n requestBodyToSerialize = undefined;\n console.warn(\n \"[Limelight] Failed to read request body from Request object\"\n );\n }\n }\n\n const requestBody = serializeBody(\n requestBodyToSerialize,\n self.config?.disableBodyCapture\n );\n\n let graphqlData: NetworkRequest[\"graphql\"] = undefined;\n\n if (self.config?.enableGraphQL && isGraphQLRequest(url, requestBody)) {\n // Pass the raw string to the parser, not the serialized object\n const rawBody = requestBody?.raw;\n if (rawBody) {\n graphqlData = parseGraphQL(rawBody) ?? undefined;\n }\n }\n\n let requestEvent: LimelightMessage = {\n id: requestId,\n sessionId: self.getSessionId(),\n timestamp: startTime,\n phase: NetworkPhase.REQUEST,\n networkType: NetworkType.FETCH,\n url,\n method: method,\n headers: redactSensitiveHeaders(headers),\n body: requestBody,\n name: formatRequestName(url),\n initiator: getInitiator(),\n requestSize: requestBody?.size ?? 0,\n graphql: graphqlData,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(requestEvent);\n\n if (!modifiedEvent) {\n return self.originalFetch(input, modifiedInit);\n }\n\n if (modifiedEvent.phase !== NetworkPhase.REQUEST) {\n console.error(\"[Limelight] beforeSend must return same event type\");\n return self.originalFetch(input, modifiedInit);\n }\n\n requestEvent = modifiedEvent;\n }\n\n self.sendMessage(requestEvent);\n\n try {\n const response = await self.originalFetch(input, modifiedInit);\n const clone = response.clone();\n const endTime = Date.now();\n const duration = endTime - startTime;\n const responseHeaders: Record<string, string> = {};\n\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n\n let responseText: string | undefined;\n\n try {\n responseText = await clone.text();\n } catch (cloneError) {\n responseText = undefined;\n }\n\n const responseBody = serializeBody(\n responseText,\n self.config?.disableBodyCapture\n );\n\n let responseEvent: LimelightMessage = {\n id: requestId,\n sessionId: self.getSessionId(),\n timestamp: endTime,\n phase: NetworkPhase.RESPONSE,\n networkType: NetworkType.FETCH,\n status: response.status,\n statusText: response.statusText,\n headers: redactSensitiveHeaders(responseHeaders),\n body: responseBody,\n duration,\n responseSize: responseBody?.size ?? 0,\n redirected: response.redirected,\n ok: response.ok,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(responseEvent);\n\n if (!modifiedEvent) {\n return response;\n }\n\n if (modifiedEvent.phase !== NetworkPhase.RESPONSE) {\n console.error(\"[Limelight] beforeSend must return same event type\");\n return response;\n }\n\n responseEvent = modifiedEvent;\n }\n\n self.sendMessage(responseEvent);\n return response;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n\n let errorEvent: NetworkErrorEvent = {\n id: requestId,\n sessionId: self.getSessionId(),\n timestamp: Date.now(),\n phase: NetworkPhase.ERROR,\n networkType: NetworkType.FETCH,\n errorMessage: errorMessage,\n stack: errorStack,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(errorEvent);\n\n if (modifiedEvent && modifiedEvent.phase === NetworkPhase.ERROR) {\n errorEvent = modifiedEvent;\n }\n }\n\n self.sendMessage(errorEvent);\n\n throw err;\n }\n };\n }\n\n /**\n * Restores the original fetch function and removes all interception.\n * @returns {void}\n */\n cleanup() {\n if (!this.isSetup) {\n console.warn(\"[Limelight] Network interceptor not set up\");\n return;\n }\n this.isSetup = false;\n\n global.fetch = this.originalFetch;\n }\n}\n","import {\n LimelightConfig,\n LimelightMessage,\n HttpMethod,\n NetworkErrorEvent,\n NetworkPhase,\n NetworkType,\n} from \"@/types\";\nimport {\n redactSensitiveHeaders,\n serializeBody,\n formatRequestName,\n getInitiator,\n} from \"@/helpers\";\nimport { generateRequestId } from \"@/protocol\";\n\ntype XHROpenArgs = Parameters<typeof XMLHttpRequest.prototype.open>;\n\ndeclare global {\n interface XMLHttpRequest {\n _limelightData?: {\n id: string;\n method: string;\n url: string;\n headers: Record<string, string>;\n startTime: number;\n skipIntercept?: boolean;\n listeners?: Map<string, EventListener>;\n };\n }\n}\n\nexport class XHRInterceptor {\n private originalXHROpen: typeof XMLHttpRequest.prototype.open;\n private originalXHRSend: typeof XMLHttpRequest.prototype.send;\n private originalXHRSetRequestHeader: typeof XMLHttpRequest.prototype.setRequestHeader;\n\n private isSetup = false;\n private config: LimelightConfig | null = null;\n\n constructor(\n private sendMessage: (message: LimelightMessage) => void,\n private getSessionId: () => string\n ) {\n this.originalXHROpen = XMLHttpRequest.prototype.open;\n this.originalXHRSend = XMLHttpRequest.prototype.send;\n this.originalXHRSetRequestHeader =\n XMLHttpRequest.prototype.setRequestHeader;\n }\n\n /**\n * Sets up XHR interception by wrapping XMLHttpRequest methods.\n * Intercepts open, setRequestHeader, and send to capture network events.\n * Prevents double setup to avoid losing original method references.\n * @param {LimelightConfig} config - Configuration object for Limelight\n * @returns {void}\n */\n setup(config: LimelightConfig) {\n if (this.isSetup) {\n console.warn(\"[Limelight] XHR interceptor already set up\");\n return;\n }\n this.isSetup = true;\n this.config = config;\n\n const self = this;\n\n XMLHttpRequest.prototype.open = function (method: string, url: string) {\n this._limelightData = {\n id: generateRequestId(),\n method,\n url,\n headers: {},\n startTime: Date.now(),\n listeners: new Map(),\n };\n\n return self.originalXHROpen.apply(\n this,\n arguments as unknown as XHROpenArgs\n );\n };\n\n XMLHttpRequest.prototype.setRequestHeader = function (\n header: string,\n value: string\n ) {\n if (this._limelightData) {\n this._limelightData.headers[header] = value;\n\n if (\n header.toLowerCase() === \"x-limelight-intercepted\" &&\n value === \"fetch\"\n ) {\n this._limelightData.skipIntercept = true;\n }\n }\n\n return self.originalXHRSetRequestHeader.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (body) {\n const data = this._limelightData;\n\n if (data?.skipIntercept) {\n return self.originalXHRSend.apply(this, arguments as any);\n }\n\n if (data) {\n const requestBody = serializeBody(\n body,\n self.config?.disableBodyCapture\n );\n\n let requestEvent: LimelightMessage = {\n id: data.id,\n sessionId: self.getSessionId(),\n timestamp: data.startTime,\n phase: NetworkPhase.REQUEST,\n networkType: NetworkType.XHR,\n url: data.url,\n method: data.method as HttpMethod,\n headers: redactSensitiveHeaders(data.headers),\n body: requestBody,\n name: formatRequestName(data.url),\n initiator: getInitiator(),\n requestSize: requestBody?.size ?? 0,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(requestEvent);\n\n if (!modifiedEvent) {\n return self.originalXHRSend.apply(this, arguments as any);\n }\n\n if (modifiedEvent.phase !== NetworkPhase.REQUEST) {\n console.error(\"[Limelight] beforeSend must return same event type\");\n return self.originalXHRSend.apply(this, arguments as any);\n }\n\n requestEvent = modifiedEvent;\n }\n\n self.sendMessage(requestEvent);\n\n let responseSent = false;\n\n /**\n * Removes all event listeners and cleans up after request completion.\n */\n const cleanup = () => {\n if (data.listeners) {\n data.listeners.forEach((listener, event) => {\n this.removeEventListener(event, listener);\n });\n data.listeners.clear();\n }\n // Clear the data to allow GC\n delete this._limelightData;\n };\n\n /**\n * Sends the response event.\n * Ensures response is only sent once using responseSent flag.\n */\n const sendResponse = () => {\n if (responseSent) return;\n responseSent = true;\n\n const endTime = Date.now();\n const duration = endTime - data.startTime;\n const responseHeaders = self.parseResponseHeaders(\n this.getAllResponseHeaders()\n );\n\n const responseBody = serializeBody(\n this.responseText || this.response,\n self.config?.disableBodyCapture\n );\n\n let responseEvent: LimelightMessage = {\n id: data.id,\n sessionId: self.getSessionId(),\n timestamp: endTime,\n phase: NetworkPhase.RESPONSE,\n networkType: NetworkType.XHR,\n status: this.status,\n statusText: this.statusText,\n headers: redactSensitiveHeaders(responseHeaders),\n body: responseBody,\n duration: duration,\n responseSize: responseBody?.size ?? 0,\n redirected: false,\n ok: this.status >= 200 && this.status < 300,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(responseEvent);\n\n if (!modifiedEvent) {\n return;\n }\n\n if (modifiedEvent.phase !== NetworkPhase.RESPONSE) {\n console.error(\n \"[Limelight] beforeSend must return same event type\"\n );\n return;\n }\n\n responseEvent = modifiedEvent;\n }\n\n self.sendMessage(responseEvent);\n cleanup.call(this);\n };\n\n /**\n * Sends an error event.\n * Also sets responseSent to prevent duplicate response events.\n */\n const sendError = (errorMessage: string) => {\n if (responseSent) return;\n responseSent = true;\n\n let errorEvent: NetworkErrorEvent = {\n id: data.id,\n sessionId: self.getSessionId(),\n timestamp: Date.now(),\n phase: NetworkPhase.ERROR,\n networkType: NetworkType.XHR,\n errorMessage: errorMessage,\n };\n\n if (self.config?.beforeSend) {\n const modifiedEvent = self.config.beforeSend(errorEvent);\n\n if (modifiedEvent && modifiedEvent.phase === NetworkPhase.ERROR) {\n errorEvent = modifiedEvent;\n }\n }\n\n self.sendMessage(errorEvent);\n cleanup.call(this);\n };\n\n const readyStateChangeHandler = function (this: XMLHttpRequest) {\n if (\n (this.readyState === 3 || this.readyState === 4) &&\n this.status !== 0\n ) {\n sendResponse.call(this);\n }\n };\n\n const loadHandler = function (this: XMLHttpRequest) {\n sendResponse.call(this);\n };\n\n const errorHandler = function (this: XMLHttpRequest) {\n sendError(\"Network request failed\");\n cleanup.call(this);\n };\n\n const abortHandler = function (this: XMLHttpRequest) {\n sendError(\"Request aborted\");\n cleanup.call(this);\n };\n\n const timeoutHandler = function (this: XMLHttpRequest) {\n sendError(\"Request timeout\");\n cleanup.call(this);\n };\n\n const loadEndHandler = function (this: XMLHttpRequest) {\n cleanup.call(this);\n };\n\n this.addEventListener(\"readystatechange\", readyStateChangeHandler);\n this.addEventListener(\"load\", loadHandler);\n this.addEventListener(\"error\", errorHandler);\n this.addEventListener(\"abort\", abortHandler);\n this.addEventListener(\"timeout\", timeoutHandler);\n this.addEventListener(\"loadend\", loadEndHandler);\n\n data.listeners!.set(\"readystatechange\", readyStateChangeHandler);\n data.listeners!.set(\"load\", loadHandler);\n data.listeners!.set(\"error\", errorHandler);\n data.listeners!.set(\"abort\", abortHandler);\n data.listeners!.set(\"timeout\", timeoutHandler);\n data.listeners!.set(\"loadend\", loadEndHandler);\n }\n\n return self.originalXHRSend.apply(this, arguments as any);\n };\n }\n\n /**\n * Parses raw HTTP header string into a key-value object.\n * @private\n * @param {string} headerString - Raw header string from getAllResponseHeaders()\n * @returns {Record<string, string>} Parsed headers object\n */\n private parseResponseHeaders(headerString: string): Record<string, string> {\n const headers: Record<string, string> = {};\n\n headerString.split(\"\\r\\n\").forEach((line) => {\n const colonIndex = line.indexOf(\": \");\n if (colonIndex > 0) {\n const key = line.substring(0, colonIndex);\n const value = line.substring(colonIndex + 2);\n headers[key] = value;\n }\n });\n\n return headers;\n }\n\n /**\n * Restores original XMLHttpRequest methods and removes all interception.\n * @returns {void}\n */\n cleanup() {\n if (!this.isSetup) {\n console.warn(\"[Limelight] XHR interceptor not set up\");\n return;\n }\n this.isSetup = false;\n\n XMLHttpRequest.prototype.open = this.originalXHROpen;\n XMLHttpRequest.prototype.send = this.originalXHRSend;\n XMLHttpRequest.prototype.setRequestHeader =\n this.originalXHRSetRequestHeader;\n }\n}\n","import { LimelightConfig, LimelightMessage } from \"@/types\";\nimport {\n ConsoleInterceptor,\n NetworkInterceptor,\n XHRInterceptor,\n} from \"@/limelight/interceptors\";\nimport { isDevelopment, safeStringify } from \"@/helpers\";\nimport { DEFAULT_PORT, WS_PATH } from \"@/constants\";\nimport { createSessionId } from \"@/protocol\";\n\nclass LimelightClient {\n private ws: WebSocket | null = null;\n private config: LimelightConfig | null = null;\n private sessionId: string = \"\";\n\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private reconnectDelay = 1000;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n private messageQueue: LimelightMessage[] = [];\n private maxQueueSize = 100;\n\n private networkInterceptor: NetworkInterceptor;\n private xhrInterceptor: XHRInterceptor;\n private consoleInterceptor: ConsoleInterceptor;\n\n constructor() {\n this.networkInterceptor = new NetworkInterceptor(\n this.sendMessage.bind(this),\n () => this.sessionId\n );\n this.xhrInterceptor = new XHRInterceptor(\n this.sendMessage.bind(this),\n () => this.sessionId\n );\n this.consoleInterceptor = new ConsoleInterceptor(\n this.sendMessage.bind(this),\n () => this.sessionId\n );\n }\n\n /**\n * Configures the Limelight client with the provided settings.\n * Sets up network, XHR, and console interceptors based on the configuration.\n * @internal\n * @private\n * @param {LimelightConfig} config - Configuration object for Limelight\n * @returns {void}\n */\n private configure(config: LimelightConfig) {\n const isEnabled = config.enabled ?? isDevelopment();\n\n this.config = {\n appName: \"Limelight App\",\n serverUrl: `ws://localhost:${DEFAULT_PORT}${WS_PATH}`,\n enabled: isEnabled,\n enableNetworkInspector: true,\n enableConsole: true,\n enableGraphQL: true,\n ...config,\n };\n\n if (!this.config.enabled) {\n return;\n }\n\n this.sessionId = createSessionId();\n\n try {\n if (this.config.enableNetworkInspector) {\n this.networkInterceptor.setup(this.config);\n this.xhrInterceptor.setup(this.config);\n }\n\n if (this.config.enableConsole) {\n this.consoleInterceptor.setup(this.config);\n }\n } catch (error) {\n console.error(\"[Limelight] Failed to setup interceptors:\", error);\n }\n }\n\n /**\n * Establishes a WebSocket connection to the Limelight server.\n * If a config object is provided, it will configure the client before connecting.\n *\n * If no config is provided and the client hasn't been configured, it will use default settings.\n *\n * Prevents multiple simultaneous connections and handles reconnection logic.\n *\n * @param {LimelightConfig} [config] - Optional configuration object.\n * @returns {void}\n */\n connect(config?: LimelightConfig) {\n if (config) {\n this.configure(config);\n } else if (!this.config) {\n this.configure({});\n }\n\n if (!this.config?.enabled) {\n return;\n }\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n console.warn(\"[Limelight] Already connected. Call disconnect() first.\");\n return;\n }\n\n if (this.ws) {\n const oldWs = this.ws;\n\n oldWs.onclose = null;\n oldWs.onerror = null;\n oldWs.onopen = null;\n\n // 1 is OPEN\n if (oldWs.readyState === 1) {\n oldWs.close();\n }\n\n this.ws = null;\n }\n const { serverUrl, appName, platform } = this.config;\n\n if (!serverUrl) {\n console.error(\"[Limelight] serverUrl missing in configuration.\");\n return;\n }\n\n try {\n this.ws = new WebSocket(serverUrl);\n\n const message: LimelightMessage = {\n phase: \"CONNECT\",\n sessionId: this.sessionId,\n timestamp: Date.now(),\n data: {\n appName: appName,\n platform: platform || \"react-native\",\n },\n };\n\n this.ws.onopen = () => {\n this.reconnectAttempts = 0;\n this.flushMessageQueue();\n this.sendMessage(message);\n };\n\n this.ws.onerror = (error) => {\n console.error(\"[Limelight] WebSocket error:\", error);\n };\n\n this.ws.onclose = () => {\n this.attemptReconnect();\n };\n } catch (error) {\n console.error(\"[Limelight] Failed to connect:\", error);\n this.attemptReconnect();\n }\n }\n\n /**\n * Attempts to reconnect to the Limelight server using exponential backoff.\n * Will retry up to maxReconnectAttempts times with increasing delays.\n * Maximum delay is capped at 30 seconds.\n * @private\n * @returns {void}\n */\n private attemptReconnect() {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n return;\n }\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n this.reconnectAttempts++;\n const delay = Math.min(\n this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n 30000\n );\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n }\n\n /**\n * Sends all queued messages to the server.\n * Only executes if the WebSocket connection is open.\n * @private\n * @returns {void}\n */\n private flushMessageQueue() {\n if (this.ws?.readyState !== WebSocket.OPEN) return;\n\n while (this.messageQueue.length > 0) {\n const message = this.messageQueue.shift();\n try {\n this.ws.send(safeStringify(message));\n } catch (error) {\n console.error(\"[Limelight] Failed to send queued message:\", error);\n }\n }\n }\n\n /**\n * Sends a message to the Limelight server or queues it if not connected.\n * Messages are automatically queued when the connection is not open.\n * If the queue is full, the oldest message will be dropped.\n * @private\n * @param {LimelightMessage} message - The message to send\n * @returns {void}\n */\n private sendMessage(message: LimelightMessage) {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.flushMessageQueue();\n\n if (this.ws?.readyState === WebSocket.OPEN) {\n try {\n this.ws.send(safeStringify(message));\n } catch (error) {\n console.error(\"[Limelight] Failed to send message:\", error);\n this.messageQueue.push(message);\n }\n } else {\n this.messageQueue.push(message);\n }\n } else {\n if (this.messageQueue.length >= this.maxQueueSize) {\n console.warn(\"[Limelight] Message queue full, dropping oldest message\");\n this.messageQueue.shift();\n }\n this.messageQueue.push(message);\n }\n }\n\n /**\n * Disconnects from the Limelight server and cleans up resources.\n * Closes the WebSocket connection, removes all interceptors, and resets connection state.\n * Preserves configuration and session ID for potential reconnection.\n * @returns {void}\n */\n disconnect() {\n if (this.ws) {\n // 1. Detach all listeners first so no logic runs after this\n this.ws.onopen = null;\n this.ws.onerror = null;\n this.ws.onclose = null;\n\n try {\n // 2. Only attempt to close if it's not already closed/closing\n if (this.ws.readyState === 0 || this.ws.readyState === 1) {\n // We use terminate if available (Node ws), otherwise close (Browser)\n if (\n \"terminate\" in this.ws &&\n typeof (this.ws as any).terminate === \"function\"\n ) {\n // For Node ws: check if socket exists before terminating\n // This prevents \"closed before established\" errors\n if ((this.ws as any)._socket) {\n (this.ws as any).terminate();\n } else {\n // If socket doesn't exist yet, just set readyState to CLOSED\n // to prevent the connection from completing\n (this.ws as any).readyState = 3; // CLOSED\n }\n } else {\n this.ws.close();\n }\n }\n } catch (e) {\n // Silently ignore WebSocket closure errors during cleanup\n }\n\n this.ws = null;\n }\n\n // Clear timers and interceptors...\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n this.networkInterceptor.cleanup();\n this.xhrInterceptor.cleanup();\n this.consoleInterceptor.cleanup();\n\n this.reconnectAttempts = 0;\n this.messageQueue = [];\n }\n\n /**\n * Performs a complete reset of the Limelight client.\n * Disconnects from the server and clears all configuration and session data.\n * After calling reset(), connect() must be called again.\n * @returns {void}\n */\n reset() {\n this.disconnect();\n this.config = null;\n this.sessionId = \"\";\n }\n}\n\nexport const Limelight = new LimelightClient();\nexport { LimelightClient };\n"],"mappings":"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","names":["ConsoleLevel","ConsoleSource","ConsoleType","NetworkType","NetworkPhase","BodyFormat","HttpMethod","HttpStatusClass","EventType","GraphqlOprtation","process"]}
|