@agg-build/sdk 4.25.0 → 4.27.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.
Files changed (42) hide show
  1. package/dist/agg-websocket-BstVWtLA.d.mts +6004 -0
  2. package/dist/agg-websocket-BstVWtLA.d.mts.map +1 -0
  3. package/dist/agg-websocket-BstVWtLA.d.ts +6004 -0
  4. package/dist/agg-websocket-BstVWtLA.d.ts.map +1 -0
  5. package/dist/agg-websocket-CK2iXfti.mjs +1427 -0
  6. package/dist/agg-websocket-CK2iXfti.mjs.map +1 -0
  7. package/dist/agg-websocket-DJbIfxKb.js +1478 -0
  8. package/dist/browser.d.mts +67 -66
  9. package/dist/browser.d.mts.map +1 -0
  10. package/dist/browser.d.ts +67 -66
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +720 -2047
  13. package/dist/browser.mjs +423 -799
  14. package/dist/browser.mjs.map +1 -0
  15. package/dist/candle-builder-BNewIe9K.mjs +148 -0
  16. package/dist/candle-builder-BNewIe9K.mjs.map +1 -0
  17. package/dist/candle-builder-BULYdxB4.js +151 -0
  18. package/dist/index.d.mts +2 -1342
  19. package/dist/index.d.ts +2 -1342
  20. package/dist/index.js +2794 -4656
  21. package/dist/index.mjs +2788 -2486
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/market-data.d.mts +6 -6
  24. package/dist/market-data.d.mts.map +1 -0
  25. package/dist/market-data.d.ts +6 -6
  26. package/dist/market-data.d.ts.map +1 -0
  27. package/dist/market-data.js +314 -1774
  28. package/dist/market-data.mjs +314 -350
  29. package/dist/market-data.mjs.map +1 -0
  30. package/dist/server.d.mts +235 -234
  31. package/dist/server.d.mts.map +1 -0
  32. package/dist/server.d.ts +235 -234
  33. package/dist/server.d.ts.map +1 -0
  34. package/dist/server.js +168 -296
  35. package/dist/server.mjs +163 -234
  36. package/dist/server.mjs.map +1 -0
  37. package/package.json +4 -4
  38. package/dist/agg-websocket-Bxt9PzTz.d.mts +0 -4479
  39. package/dist/agg-websocket-Bxt9PzTz.d.ts +0 -4479
  40. package/dist/chunk-QXBVA5TW.mjs +0 -2073
  41. package/dist/chunk-VD5UTAVD.mjs +0 -158
  42. package/dist/chunk-WNQUEZJF.mjs +0 -58
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agg-websocket-CK2iXfti.mjs","names":["crc32"],"sources":["../../common/src/orderbook-checksum.ts","../src/market-data/history-decoder.ts","../src/market-data/validate.ts","../src/market-history.ts","../src/orderbook-utils.ts","../src/agg-websocket.ts"],"sourcesContent":["/** IEEE CRC32 used by the existing orderbook protocol. */\nexport function orderbookCrc32(value: string): number {\n let crc = 0xffffffff;\n for (let i = 0; i < value.length; i++) {\n crc ^= value.charCodeAt(i);\n for (let bit = 0; bit < 8; bit++) crc = (crc >>> 1) ^ (crc & 1 ? 0xedb88320 : 0);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/** Checksum of exactly the supplied levels, independent of depth/venue attribution. */\nexport function projectedOrderbookChecksum(book: {\n bids: ReadonlyArray<{ price: number; size: number }>;\n asks: ReadonlyArray<{ price: number; size: number }>;\n}): number {\n let result = 0;\n for (const level of book.bids) result ^= orderbookCrc32(`B${level.price}:${level.size}`);\n for (const level of book.asks) result ^= orderbookCrc32(`A${level.price}:${level.size}`);\n return result >>> 0;\n}\n","import type { ChartBarsResponse } from \"../types\";\n\n/** Decode bounded dynamic history where processing lives; retain milliseconds and optional mean. */\nexport function decodeChartHistory(payload: string): ChartBarsResponse {\n // One MiB UTF-16 characters bounds parse work; valid 5000-point API responses fit comfortably.\n if (payload.length > 1_048_576) throw new Error(\"Chart history exceeds decode budget\");\n const body = JSON.parse(payload) as ChartBarsResponse;\n if (\n !body ||\n !Array.isArray(body.data) ||\n body.data.length > 5000 ||\n typeof body.venueMarketOutcomeId !== \"string\" ||\n typeof body.venue !== \"string\" ||\n ![\"1m\", \"5m\", \"1h\", \"1d\"].includes(body.resolution) ||\n !body.meta\n )\n throw new Error(\"Invalid chart history response\");\n const price = (value: unknown) =>\n typeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= 1;\n for (const bar of body.data) {\n if (\n !Number.isSafeInteger(bar.t) ||\n bar.t < 0 ||\n ![bar.o, bar.h, bar.l, bar.c].every(price) ||\n bar.l > Math.min(bar.o, bar.c) ||\n bar.h < Math.max(bar.o, bar.c) ||\n (bar.v !== null && (!Number.isFinite(bar.v) || bar.v < 0)) ||\n (bar.mean !== undefined && !price(bar.mean))\n )\n throw new Error(\"Invalid chart history candle\");\n }\n const data = [...body.data].sort((a, b) => a.t - b.t);\n if (data.some((bar, index) => index > 0 && data[index - 1]!.t === bar.t))\n throw new Error(\"Duplicate chart history timestamp\");\n return { ...body, data };\n}\n\n/** Bound received bytes before JSON parsing, including chunked responses without Content-Length. */\nexport async function readChartHistoryText(response: Response): Promise<string> {\n const maxBytes = 1_048_576;\n if (Number(response.headers.get(\"content-length\")) > maxBytes) {\n await response.body?.cancel();\n throw new Error(\"Chart history exceeds decode budget\");\n }\n if (!response.body?.getReader) {\n const text = await response.text();\n if (new TextEncoder().encode(text).byteLength > maxBytes)\n throw new Error(\"Chart history exceeds decode budget\");\n return text;\n }\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let size = 0;\n let text = \"\";\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) return text + decoder.decode();\n size += value.byteLength;\n if (size > maxBytes) {\n await reader.cancel();\n throw new Error(\"Chart history exceeds decode budget\");\n }\n text += decoder.decode(value, { stream: true });\n }\n } finally {\n reader.releaseLock();\n }\n}\n","/** Bounds work before processing untrusted market frames. Protocol semantics remain in AggWebSocket. */\nconst object = (value: unknown): value is Record<string, unknown> =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\nconst finite = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\nconst nullable = (value: unknown) => value === null || finite(value);\nconst levels = (value: unknown, attributed: boolean): boolean =>\n Array.isArray(value) &&\n value.length <= 10_000 &&\n value.every(\n (level) =>\n Array.isArray(level) &&\n finite(level[0]) &&\n level[0] >= 0 &&\n finite(level[1]) &&\n level[1] >= 0 &&\n (!attributed ||\n (object(level[2]) && Object.values(level[2]).every((size) => finite(size) && size >= 0))),\n );\nexport function validMarketFrame(frame: Record<string, unknown>): boolean {\n if (\n typeof frame.outcomeId !== \"string\" ||\n !frame.outcomeId ||\n !finite(frame.timestamp) ||\n frame.timestamp < 0\n )\n return false;\n if (frame.type === \"trade\")\n return (\n finite(frame.price) &&\n frame.price >= 0 &&\n finite(frame.size) &&\n frame.size >= 0 &&\n typeof frame.venue === \"string\" &&\n (frame.side === \"buy\" || frame.side === \"sell\")\n );\n if (\n !Number.isSafeInteger(frame.seq) ||\n (frame.seq as number) < 0 ||\n !Number.isInteger(frame.checksum) ||\n (frame.checksum as number) < 0 ||\n (frame.checksum as number) > 0xffffffff ||\n !nullable(frame.midpoint) ||\n !nullable(frame.spread) ||\n !object(frame.venues)\n )\n return false;\n for (const info of Object.values(frame.venues))\n if (!object(info) || !nullable(info.bestBid) || !nullable(info.bestAsk)) return false;\n const snapshot = frame.type === \"orderbook_snapshot\";\n if (\n !levels(frame[snapshot ? \"bids\" : \"bidChanges\"], true) ||\n !levels(frame[snapshot ? \"asks\" : \"askChanges\"], true)\n )\n return false;\n const books = frame[snapshot ? \"venueOrderbooks\" : \"venueDeltaBooks\"];\n return (\n object(books) &&\n Object.values(books).every(\n (book) =>\n object(book) &&\n levels(book[snapshot ? \"bids\" : \"bidChanges\"], false) &&\n levels(book[snapshot ? \"asks\" : \"askChanges\"], false),\n )\n );\n}\n","import type { ChartCandle, ChartHistoryManifest } from \"./types\";\n\nexport type LoadImmutableHistoryOptions = {\n manifest: ChartHistoryManifest;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n /** Runtimes without WebCrypto can supply SHA-256 without adding a browser dependency. */\n digest?: (bytes: Uint8Array) => Promise<string>;\n};\n\nasync function readBoundedBody(\n response: Response,\n signal: AbortSignal,\n): Promise<Uint8Array<ArrayBuffer>> {\n if (!response.body) throw new Error(\"Missing history body\");\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n const abort = () => {\n void reader.cancel(signal.reason).catch(() => undefined);\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n try {\n while (true) {\n if (signal.aborted) throw signal.reason ?? new Error(\"History request aborted\");\n const { done, value } = await reader.read();\n if (signal.aborted) throw signal.reason ?? new Error(\"History request aborted\");\n if (done) break;\n size += value.byteLength;\n if (size > 262_144) {\n await reader.cancel();\n throw new Error(\"Oversized history object\");\n }\n chunks.push(value);\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n } finally {\n signal.removeEventListener(\"abort\", abort);\n reader.releaseLock();\n }\n}\n\n/** Download immutable CDN objects directly. Safe to run in the browser Worker or Node. */\nexport async function loadImmutableHistory({\n manifest,\n fetch: fetcher = globalThis.fetch,\n signal,\n digest,\n}: LoadImmutableHistoryOptions): Promise<ChartCandle[]> {\n if (\n manifest.version !== 1 ||\n ![\"venue-ohlcv-v1\", \"polymarket-price-samples-v1\", \"kalshi-ohlcv-quote-fallback-v2\"].includes(\n manifest.semantics,\n ) ||\n manifest.chunks.length > 8 ||\n manifest.chunks.reduce((n, c) => n + c.points, 0) > 4096 ||\n !manifest.meta.complete\n ) {\n throw new Error(\"History manifest is incomplete or unsupported\");\n }\n const hash =\n digest ??\n (async (bytes: Uint8Array<ArrayBuffer>) => {\n if (!globalThis.crypto?.subtle)\n throw new Error(\n \"History integrity requires WebCrypto or an injected SHA-256 implementation\",\n );\n const value = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return Array.from(new Uint8Array(value), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n });\n const results: ChartCandle[][] = new Array(manifest.chunks.length);\n let next = 0;\n const controller = new AbortController();\n const deadline = setTimeout(\n () => controller.abort(new Error(\"History download budget exhausted\")),\n 2000,\n );\n const abort = () => controller.abort(signal?.reason);\n signal?.addEventListener(\"abort\", abort, { once: true });\n if (signal?.aborted) abort();\n try {\n await Promise.all(\n Array.from({ length: Math.min(2, manifest.chunks.length) }, async () => {\n while (next < manifest.chunks.length) {\n if (controller.signal.aborted)\n throw controller.signal.reason ?? new Error(\"History request aborted\");\n const index = next++;\n const chunk = manifest.chunks[index];\n if (\n chunk.points < 0 ||\n chunk.points > 512 ||\n chunk.from >= chunk.to ||\n new URL(chunk.url).protocol !== \"https:\"\n )\n throw new Error(\"Invalid history reference\");\n const response = await fetcher(chunk.url, {\n signal: controller.signal,\n credentials: \"omit\",\n });\n if (!response.ok) throw new Error(`History download failed (${response.status})`);\n if (Number(response.headers.get(\"content-length\")) > 262_144)\n throw new Error(\"Oversized history object\");\n const bytes = await readBoundedBody(response, controller.signal);\n if (bytes.byteLength > 262_144 || (await hash(bytes)) !== chunk.sha256)\n throw new Error(\"History integrity mismatch\");\n const object = JSON.parse(new TextDecoder().decode(bytes));\n if (\n object.version !== 1 ||\n object.venueMarketOutcomeId !== manifest.venueMarketOutcomeId ||\n object.venue !== manifest.venue ||\n object.resolution !== manifest.resolution ||\n object.semantics !== manifest.semantics ||\n object.from !== chunk.from ||\n object.to !== chunk.to ||\n !Array.isArray(object.data) ||\n object.data.length !== chunk.points\n ) {\n throw new Error(\"History identity mismatch\");\n }\n let previous = -Infinity;\n for (const bar of object.data as ChartCandle[]) {\n if (\n !Number.isSafeInteger(bar.t) ||\n bar.t <= previous ||\n bar.t < chunk.from ||\n bar.t >= chunk.to ||\n ![bar.o, bar.h, bar.l, bar.c].every((v) => Number.isFinite(v) && v >= 0 && v <= 1) ||\n bar.l > Math.min(bar.o, bar.c) ||\n bar.h < Math.max(bar.o, bar.c) ||\n (bar.v !== null && (!Number.isFinite(bar.v) || bar.v < 0)) ||\n (bar.mean !== undefined &&\n (!Number.isFinite(bar.mean) || bar.mean < 0 || bar.mean > 1))\n )\n throw new Error(\"Invalid history candle\");\n previous = bar.t;\n }\n results[index] = object.data;\n }\n }),\n );\n const bars = results\n .flat()\n .filter((b) => b.t >= manifest.from && b.t < manifest.to)\n .sort((a, b) => a.t - b.t);\n if (bars.some((b, i) => i > 0 && bars[i - 1].t === b.t))\n throw new Error(\"Overlapping history chunks\");\n return bars;\n } catch (error) {\n controller.abort(error);\n throw error;\n } finally {\n clearTimeout(deadline);\n signal?.removeEventListener(\"abort\", abort);\n }\n}\n","import { orderbookCrc32 as crc32, projectedOrderbookChecksum } from \"@agg/common/types-only\";\n/**\n * Immutable orderbook utility functions for the SDK.\n * Applies WS deltas to local book state, computes checksums for integrity verification.\n * Every function returns a **new object** — never mutates inputs.\n */\n\nimport type {\n WsAttributedLevel,\n WsVenueLevel,\n WsVenueInfo,\n WsVenueBook,\n WsOrderbookSnapshot,\n WsOrderbookDelta,\n} from \"./ws-types\";\n\n// ── Types ──\n\nexport interface OrderbookLevel {\n price: number;\n size: number;\n venues: Record<string, number>;\n}\n\nexport interface VenueOrderbookLevel {\n price: number;\n size: number;\n}\n\nexport interface OrderbookState {\n marketId: string;\n /** The outcome whose price the midpoint represents (e.g. the \"Yes\" outcome in binary markets). */\n outcomeId?: string | null;\n bids: OrderbookLevel[];\n asks: OrderbookLevel[];\n venueOrderbooks: Record<string, { bids: VenueOrderbookLevel[]; asks: VenueOrderbookLevel[] }>;\n venues: Record<string, WsVenueInfo>;\n midpoint: number | null;\n spread: number | null;\n seq: number;\n checksum: number;\n /** @unit seconds */\n timestamp: number;\n}\n\nconst PRICE_KEY_SCALE = 1_000_000_000;\n\n// ── CRC32 (IEEE polynomial, matches server implementation) ──\n\n/**\n * Compute the XOR-based checksum of an orderbook.\n * Matches the Rust engine's checksum: XOR of crc32(\"B{price}:{size}\") for each\n * bid and crc32(\"A{price}:{size}\") for each ask, independently hashed then XOR'd.\n */\nexport function computeChecksum(book: { bids: OrderbookLevel[]; asks: OrderbookLevel[] }): number {\n return projectedOrderbookChecksum(book);\n}\n\n// ── Wire format converters ──\n\nfunction attributedToLevel(wire: WsAttributedLevel): OrderbookLevel {\n return { price: wire[0], size: wire[1], venues: { ...wire[2] } };\n}\n\nfunction venueLevelToLevel(wire: WsVenueLevel): VenueOrderbookLevel {\n return { price: wire[0], size: wire[1] };\n}\n\nfunction convertVenueBooks(\n raw: Record<string, WsVenueBook>,\n): Record<string, { bids: VenueOrderbookLevel[]; asks: VenueOrderbookLevel[] }> {\n const result: Record<string, { bids: VenueOrderbookLevel[]; asks: VenueOrderbookLevel[] }> = {};\n for (const [venue, book] of Object.entries(raw)) {\n result[venue] = {\n bids: book.bids.map(venueLevelToLevel),\n asks: book.asks.map(venueLevelToLevel),\n };\n }\n return result;\n}\n\n// ── Public API ──\n\n/**\n * Convert a WS snapshot message into local OrderbookState.\n * Timestamp is expected to already be in seconds (converted by AggWebSocket).\n */\nexport function snapshotToOrderbook(snapshot: WsOrderbookSnapshot): OrderbookState {\n return {\n marketId: snapshot.outcomeId,\n outcomeId: snapshot.outcomeId,\n bids: snapshot.bids.map(attributedToLevel),\n asks: snapshot.asks.map(attributedToLevel),\n venueOrderbooks: convertVenueBooks(snapshot.venueOrderbooks),\n venues: { ...snapshot.venues },\n midpoint: snapshot.midpoint,\n spread: snapshot.spread,\n seq: snapshot.seq,\n checksum: snapshot.checksum,\n timestamp: snapshot.timestamp,\n };\n}\n\n/**\n * Apply a WS delta to an existing OrderbookState, returning a new state.\n * Bids sorted descending, asks ascending (maintained invariant).\n */\nexport function applyOrderbookDelta(\n state: OrderbookState,\n delta: WsOrderbookDelta,\n): OrderbookState {\n const bids = applyChanges([...state.bids], delta.bidChanges, \"desc\");\n const asks = applyChanges([...state.asks], delta.askChanges, \"asc\");\n\n const impliedBidChangesByVenue = deriveVenueChangesFromAttributedChanges(\n state.bids,\n delta.bidChanges,\n );\n const impliedAskChangesByVenue = deriveVenueChangesFromAttributedChanges(\n state.asks,\n delta.askChanges,\n );\n\n const venueOrderbooks = { ...state.venueOrderbooks };\n const venuesWithDelta = new Set<string>([\n ...Object.keys(delta.venueDeltaBooks),\n ...Object.keys(impliedBidChangesByVenue),\n ...Object.keys(impliedAskChangesByVenue),\n ]);\n\n for (const venue of venuesWithDelta) {\n const explicitChanges = delta.venueDeltaBooks[venue];\n const bidChanges = mergeVenueLevelChanges(\n explicitChanges?.bidChanges,\n impliedBidChangesByVenue[venue],\n );\n const askChanges = mergeVenueLevelChanges(\n explicitChanges?.askChanges,\n impliedAskChangesByVenue[venue],\n );\n\n if (bidChanges.length === 0 && askChanges.length === 0) continue;\n\n const existing = venueOrderbooks[venue] ?? { bids: [], asks: [] };\n venueOrderbooks[venue] = {\n bids: applyVenueChanges([...existing.bids], bidChanges, \"desc\"),\n asks: applyVenueChanges([...existing.asks], askChanges, \"asc\"),\n };\n }\n\n return {\n marketId: state.marketId,\n outcomeId: state.outcomeId ?? delta.outcomeId,\n bids,\n asks,\n venueOrderbooks,\n venues: { ...state.venues, ...delta.venues },\n midpoint: delta.midpoint,\n spread: delta.spread,\n seq: delta.seq,\n checksum: delta.checksum,\n timestamp: delta.timestamp,\n };\n}\n\n// ── Internal helpers ──\n\nfunction toPriceKey(price: number): string {\n return String(Math.round(price * PRICE_KEY_SCALE));\n}\n\nfunction applyChanges(\n levels: OrderbookLevel[],\n changes: WsAttributedLevel[],\n sort: \"asc\" | \"desc\",\n): OrderbookLevel[] {\n const levelsByPrice = new Map(levels.map((level) => [toPriceKey(level.price), level]));\n\n for (const [price, size, venues] of changes) {\n const key = toPriceKey(price);\n if (size === 0) {\n levelsByPrice.delete(key);\n continue;\n }\n\n levelsByPrice.set(key, {\n price,\n size,\n venues: { ...(venues ?? {}) },\n });\n }\n\n levels = [...levelsByPrice.values()];\n levels.sort(sort === \"desc\" ? (a, b) => b.price - a.price : (a, b) => a.price - b.price);\n return levels;\n}\n\nfunction applyVenueChanges(\n levels: VenueOrderbookLevel[],\n changes: WsVenueLevel[],\n sort: \"asc\" | \"desc\",\n): VenueOrderbookLevel[] {\n const levelsByPrice = new Map(levels.map((level) => [toPriceKey(level.price), level]));\n\n for (const [price, size] of changes) {\n const key = toPriceKey(price);\n if (size === 0) {\n levelsByPrice.delete(key);\n continue;\n }\n\n levelsByPrice.set(key, { price, size });\n }\n\n levels = [...levelsByPrice.values()];\n levels.sort(sort === \"desc\" ? (a, b) => b.price - a.price : (a, b) => a.price - b.price);\n return levels;\n}\n\nfunction mergeVenueLevelChanges(\n primary: WsVenueLevel[] | undefined,\n fallback: WsVenueLevel[] | undefined,\n): WsVenueLevel[] {\n if (!primary?.length) return fallback ? [...fallback] : [];\n if (!fallback?.length) return [...primary];\n\n const changesByPrice = new Map<string, WsVenueLevel>();\n for (const change of fallback) {\n changesByPrice.set(toPriceKey(change[0]), change);\n }\n for (const change of primary) {\n changesByPrice.set(toPriceKey(change[0]), change);\n }\n\n return [...changesByPrice.values()];\n}\n\nfunction deriveVenueChangesFromAttributedChanges(\n previousLevels: OrderbookLevel[],\n changes: WsAttributedLevel[],\n): Record<string, WsVenueLevel[]> {\n const previousLevelsByPrice = new Map(\n previousLevels.map((level) => [toPriceKey(level.price), level]),\n );\n const venueChanges: Record<string, WsVenueLevel[]> = {};\n\n for (const [price, size, nextVenuesRaw] of changes) {\n const key = toPriceKey(price);\n const previousLevel = previousLevelsByPrice.get(key);\n const previousVenues = previousLevel?.venues ?? {};\n const nextVenues = nextVenuesRaw ?? {};\n const affectedVenues = new Set([...Object.keys(previousVenues), ...Object.keys(nextVenues)]);\n\n for (const venue of affectedVenues) {\n const nextSize = Number(nextVenues[venue] ?? 0);\n if (!Number.isFinite(nextSize)) continue;\n\n if (!venueChanges[venue]) {\n venueChanges[venue] = [];\n }\n venueChanges[venue].push([price, nextSize]);\n }\n\n if (size === 0) {\n previousLevelsByPrice.delete(key);\n continue;\n }\n\n previousLevelsByPrice.set(key, {\n price,\n size,\n venues: { ...nextVenues },\n });\n }\n\n return venueChanges;\n}\n\n/** Private mutable representation for ordered feeds; immutable views are built only on demand. */\nexport class IndexedOrderbook {\n private bids: Map<string, OrderbookLevel>;\n private asks: Map<string, OrderbookLevel>;\n private venueBooks = new Map<\n string,\n { bids: Map<string, VenueOrderbookLevel>; asks: Map<string, VenueOrderbookLevel> }\n >();\n private metadata: Omit<OrderbookState, \"bids\" | \"asks\" | \"venueOrderbooks\">;\n private cached: OrderbookState | null;\n private checksumValue: number;\n\n constructor(state: OrderbookState) {\n this.bids = new Map(state.bids.map((level) => [toPriceKey(level.price), level]));\n this.asks = new Map(state.asks.map((level) => [toPriceKey(level.price), level]));\n for (const [venue, book] of Object.entries(state.venueOrderbooks)) {\n this.venueBooks.set(venue, {\n bids: new Map(book.bids.map((level) => [toPriceKey(level.price), level])),\n asks: new Map(book.asks.map((level) => [toPriceKey(level.price), level])),\n });\n }\n const { bids: _bids, asks: _asks, venueOrderbooks: _venueBooks, ...metadata } = state;\n this.metadata = metadata;\n this.cached = state;\n this.checksumValue = computeChecksum(state);\n }\n\n get seq(): number {\n return this.metadata.seq;\n }\n get checksum(): number {\n return this.checksumValue;\n }\n\n /** Verify before committing, including duplicate-price changes within a frame. */\n apply(delta: WsOrderbookDelta): number {\n let checksum = this.checksumValue;\n for (const [levels, changes, side] of [\n [this.bids, delta.bidChanges, \"B\"],\n [this.asks, delta.askChanges, \"A\"],\n ] as const) {\n const changed = new Map<string, OrderbookLevel | undefined>();\n for (const [price, size, venues] of changes) {\n const key = toPriceKey(price);\n const previous = changed.has(key) ? changed.get(key) : levels.get(key);\n if (previous) checksum ^= crc32(`${side}${previous.price}:${previous.size}`);\n if (size !== 0) checksum ^= crc32(`${side}${price}:${size}`);\n changed.set(key, size === 0 ? undefined : { price, size, venues: { ...venues } });\n }\n }\n checksum >>>= 0;\n if (checksum !== delta.checksum) return checksum;\n\n const previousBids = delta.bidChanges.flatMap(\n ([price]) => this.bids.get(toPriceKey(price)) ?? [],\n );\n const previousAsks = delta.askChanges.flatMap(\n ([price]) => this.asks.get(toPriceKey(price)) ?? [],\n );\n const impliedBids = deriveVenueChangesFromAttributedChanges(previousBids, delta.bidChanges);\n const impliedAsks = deriveVenueChangesFromAttributedChanges(previousAsks, delta.askChanges);\n for (const venue of new Set([\n ...Object.keys(delta.venueDeltaBooks),\n ...Object.keys(impliedBids),\n ...Object.keys(impliedAsks),\n ])) {\n let book = this.venueBooks.get(venue);\n if (!book) {\n book = { bids: new Map(), asks: new Map() };\n this.venueBooks.set(venue, book);\n }\n const explicit = delta.venueDeltaBooks[venue];\n for (const [levels, changes] of [\n [book.bids, mergeVenueLevelChanges(explicit?.bidChanges, impliedBids[venue])],\n [book.asks, mergeVenueLevelChanges(explicit?.askChanges, impliedAsks[venue])],\n ] as const) {\n for (const [price, size] of changes) {\n if (size === 0) levels.delete(toPriceKey(price));\n else levels.set(toPriceKey(price), { price, size });\n }\n }\n }\n for (const [levels, changes] of [\n [this.bids, delta.bidChanges],\n [this.asks, delta.askChanges],\n ] as const) {\n for (const [price, size, venues] of changes) {\n if (size === 0) levels.delete(toPriceKey(price));\n else levels.set(toPriceKey(price), { price, size, venues: { ...venues } });\n }\n }\n this.metadata = {\n ...this.metadata,\n outcomeId: this.metadata.outcomeId ?? delta.outcomeId,\n venues: { ...this.metadata.venues, ...delta.venues },\n midpoint: delta.midpoint,\n spread: delta.spread,\n seq: delta.seq,\n checksum: delta.checksum,\n timestamp: delta.timestamp,\n };\n this.checksumValue = checksum;\n this.cached = null;\n return checksum;\n }\n\n view(): OrderbookState {\n if (this.cached) return this.cached;\n const bids = (levels: Map<string, VenueOrderbookLevel>) =>\n [...levels.values()].sort((a, b) => b.price - a.price);\n const asks = (levels: Map<string, VenueOrderbookLevel>) =>\n [...levels.values()].sort((a, b) => a.price - b.price);\n this.cached = {\n ...this.metadata,\n bids: bids(this.bids) as OrderbookLevel[],\n asks: asks(this.asks) as OrderbookLevel[],\n venueOrderbooks: Object.fromEntries(\n [...this.venueBooks].map(([venue, book]) => [\n venue,\n { bids: bids(book.bids), asks: asks(book.asks) },\n ]),\n ),\n };\n return this.cached;\n }\n}\n","/**\n * Agg platform WebSocket client.\n *\n * Single connection, refcounted subscriptions. Orderbook/trades subscriptions\n * are keyed by venueMarketOutcomeId (the `outcomes[].id` on REST market\n * responses — NOT a venueMarketId); arb subscriptions are keyed by marketId.\n * Maintains in-memory orderbook state per subscribed outcome id.\n * All timestamps converted from server ms to seconds before invoking callbacks.\n *\n * Recovery: seq gap or checksum mismatch → resnapshot request.\n * Stale delta guard: deltas with seq <= current book seq are silently dropped.\n * Liveness: no message for 45s → reconnect (server sends heartbeat every 30s).\n * Book watchdog (optional): books silent for 5 min are checked against REST\n * `seq`; a mismatch triggers a resnapshot, a repeat mismatch a resubscribe.\n */\n\nimport { decodeChartHistory } from \"./market-data/history-decoder\";\nimport { validMarketFrame } from \"./market-data/validate\";\nimport { loadImmutableHistory } from \"./market-history\";\nimport type { ChartHistoryManifest, ChartCandle, ChartBarsResponse } from \"./types\";\nimport { IndexedOrderbook, snapshotToOrderbook, type OrderbookState } from \"./orderbook-utils\";\nimport type {\n DiagnosticCallback,\n DiagnosticEvent,\n WsArbFeedBatch,\n WsArbMarketUpdate,\n WsAuthenticated,\n WsBalanceUpdate,\n WsConnected,\n WsError,\n WsHeartbeat,\n WsMarketResolved,\n WsOrderbookDelta,\n WsOrderbookSnapshot,\n WsOrderEvent,\n WsOrderSubmitted,\n WsRedeemEvent,\n WsSubscribed,\n WsTrade,\n WsUnsubscribed,\n WsWithdrawalLifecycleEvent,\n} from \"./ws-types\";\n\n// ── Constants ──\n\nconst RECONNECT_BASE_MS = 1000;\nconst RECONNECT_MAX_MS = 30_000;\nconst STALE_TIMEOUT_MS = 45_000;\nconst ORDERBOOK_DEBUG_TOP_LEVELS = 5;\nconst WATCHDOG_SILENCE_MS = 5 * 60_000;\nconst WATCHDOG_CHECK_INTERVAL_MS = 60_000;\n/** `GET /orderbooks/outcomes` accepts at most 100 ids per call. */\nconst WATCHDOG_BATCH_MAX = 100;\n/** A watchdog REST check that takes longer than this is abandoned. */\nconst WATCHDOG_REQUEST_TIMEOUT_MS = 15_000;\n\n// ── Callback types ──\n\nexport interface AggWebSocketCallbacks {\n /** Local receipt clock, distinct from venue/source timestamps. */\n onFrameReceived?: (receivedAtMs: number) => void;\n /** Pre-accumulated live views from the optional processing engine. */\n onMarketView?: (view: import(\"./market-data/engine\").MarketView) => void;\n /** Invoked with the venueMarketOutcomeId the snapshot belongs to. */\n onSnapshot?: (outcomeId: string, book: OrderbookState) => void;\n /** Invoked with the venueMarketOutcomeId the delta belongs to. */\n onDelta?: (outcomeId: string, book: OrderbookState) => void;\n onTrade?: (trade: WsTrade) => void;\n /** Every validated update, before optional view batching. Timestamps are seconds. */\n onBookTick?: (\n outcomeId: string,\n tick: { midpoint: number | null; timestamp: number; source: \"snapshot\" | \"delta\" },\n ) => void;\n onHeartbeat?: (hb: WsHeartbeat) => void;\n onSubscribed?: (msg: WsSubscribed) => void;\n onUnsubscribed?: (msg: WsUnsubscribed) => void;\n onConnected?: (msg: WsConnected) => void;\n onAuthenticated?: (msg: WsAuthenticated) => void;\n onMarketResolved?: (msg: WsMarketResolved) => void;\n onError?: (msg: WsError) => void;\n onOrderSubmitted?: (msg: WsOrderSubmitted) => void;\n onBalanceUpdate?: (msg: WsBalanceUpdate) => void;\n onOrderEvent?: (msg: WsOrderEvent) => void;\n /** Optional delivery timing; server/client clock skew yields a null delay. */\n onOrderEventReceipt?: (timing: {\n orderId: string;\n event: WsOrderEvent[\"event\"];\n serverTimestampMs: number | null;\n receivedAtMs: number;\n deliveryDelayMs: number | null;\n }) => void;\n onRedeemEvent?: (msg: WsRedeemEvent) => void;\n onWithdrawalLifecycle?: (msg: WsWithdrawalLifecycleEvent) => void;\n onArbMarket?: (msg: WsArbMarketUpdate) => void;\n onArbFeed?: (batch: WsArbFeedBatch) => void;\n onDiagnostics?: DiagnosticCallback;\n onConnectionStateChange?: (connected: boolean) => void;\n}\n\nexport interface AggWebSocketDiagnostics {\n connected: boolean;\n transport: \"direct\" | \"worker\" | \"disposed\";\n orderbookOutcomeIds: string[];\n tradeOutcomeIds: string[];\n arbMarketIds: string[];\n arbFeedSubscribers: number;\n cachedBooks: number;\n cachedArb: number;\n resyncingBooks: number;\n pendingResnapshots: number;\n pendingHistoryRequests: number;\n workerAttached?: boolean;\n bridgeListeners?: number;\n host?: Record<string, unknown>;\n}\n\n/**\n * Per-outcome staleness check against REST. Plain data (no functions) so it\n * can be passed into the market-data Worker.\n */\nexport interface BookWatchdogOptions {\n /** REST API base URL, e.g. `https://api.agg.market`. */\n baseUrl: string;\n /** Headers for `GET /orderbooks/outcomes` (`x-app-id`, optional `x-app-api-key`). */\n headers?: Record<string, string>;\n /** A book with no update for this long is checked. Default 5 minutes. */\n silenceMs?: number;\n /** How often silent books are looked for. Default 1 minute. */\n checkIntervalMs?: number;\n}\n\nexport interface AggWebSocketOptions {\n /** Full WebSocket URL including query params (appId). Token should NOT be in the URL. */\n url: string;\n callbacks?: AggWebSocketCallbacks;\n /** JWT to send via the authenticate message after connecting (avoids token in URL/logs). */\n initialToken?: string;\n /** Enable websocket debug logs. Default: false. */\n enableLogs?: boolean;\n /** Engine-only: read immutable books through getBook at presentation cadence. */\n deferBookViews?: boolean;\n /** Check silent books against REST and heal any that drifted. Off when omitted. */\n bookWatchdog?: BookWatchdogOptions;\n}\n\n// ── Per-market subscription state ──\n\ninterface MarketSub {\n /** Number of active subscribe() calls for this market. */\n refCount: number;\n /** Whether we've subscribed to trades for this market. */\n tradeRefs: number;\n}\n\n/**\n * Agg WebSocket client. Single WS connection with refcounted market subscriptions.\n */\nexport class AggWebSocket {\n private ws: WebSocket | null = null;\n private readonly url: string;\n private callbacks: AggWebSocketCallbacks;\n\n // ── Subscription tracking ──\n private readonly subs = new Map<string, MarketSub>();\n private readonly pendingSubs = new Set<string>();\n private readonly pendingTradeSubs = new Set<string>();\n private readonly pendingResnapshots = new Set<string>();\n\n // ── Post-connect batching (coalesces same-tick sub/unsub calls into one frame) ──\n private readonly pendingFlushSubs = new Set<string>();\n private readonly pendingFlushUnsubs = new Set<string>();\n private readonly pendingFlushTradeSubs = new Set<string>();\n private readonly pendingFlushTradeUnsubs = new Set<string>();\n private readonly pendingFlushArbSubs = new Set<string>();\n private readonly pendingFlushArbUnsubs = new Set<string>();\n private flushScheduled = false;\n\n // ── Arb subscriptions ──\n private readonly arbSubs = new Map<\n string,\n { refCount: number; cbs: Set<(m: WsArbMarketUpdate) => void> }\n >();\n private readonly arbFeedCbs = new Set<(b: WsArbFeedBatch) => void>();\n /** Latest arb market update per marketId (last-value-wins, loss-tolerant). */\n private readonly latestArb = new Map<string, WsArbMarketUpdate>();\n\n // ── Orderbook state per market ──\n private readonly books = new Map<string, IndexedOrderbook>();\n private readonly deferBookViews: boolean;\n /** Markets currently resyncing (awaiting snapshot after seq gap / checksum mismatch). */\n private readonly resyncing = new Set<string>();\n\n // ── Book watchdog ──\n private readonly bookWatchdog?: BookWatchdogOptions;\n /**\n * Per subscribed orderbook outcome: last time it made progress (subscribe,\n * snapshot, applied delta) or was checked against REST (ms). Tracked from\n * subscribe, not from the first snapshot, so a book that never arrives or\n * is stuck resyncing is still found by the watchdog.\n */\n private readonly bookCheckedAt = new Map<string, number>();\n /** Outcomes the watchdog already resnapshotted; a repeat mismatch resubscribes. */\n private readonly watchdogResnapshotted = new Set<string>();\n private watchdogTimer: ReturnType<typeof setInterval> | null = null;\n private watchdogAbort: AbortController | null = null;\n private watchdogPausedUntil = 0;\n\n // ── Connection state ──\n private connecting = false;\n private _connected = false;\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private staleTimer: ReturnType<typeof setTimeout> | null = null;\n private lastMessageTime = 0;\n private destroyed = false;\n private historyControllers = new Set<AbortController>();\n private hostDiagnostics?: () => Record<string, unknown>;\n\n private initialToken?: string;\n private readonly enableLogs: boolean;\n\n constructor(options: AggWebSocketOptions) {\n this.deferBookViews = options.deferBookViews ?? false;\n this.url = options.url;\n this.callbacks = options.callbacks ?? {};\n this.initialToken = options.initialToken;\n this.enableLogs = options.enableLogs ?? false;\n this.bookWatchdog = options.bookWatchdog;\n }\n\n // ── Public API ──\n\n get connected(): boolean {\n return this._connected;\n }\n\n /** Decode dynamic authenticated REST bytes in the same processing environment as live data. */\n async decodeHistory(payload: string): Promise<ChartBarsResponse> {\n return decodeChartHistory(payload);\n }\n\n /** Immutable history decoder. Browser adapters execute this inside their Worker. */\n async loadHistory(\n manifest: ChartHistoryManifest,\n options?: { signal?: AbortSignal },\n ): Promise<ChartCandle[]> {\n if (this.destroyed) throw new Error(\"Market-data client disposed\");\n const controller = new AbortController();\n const abort = () => controller.abort(options?.signal?.reason);\n options?.signal?.addEventListener(\"abort\", abort, { once: true });\n if (options?.signal?.aborted) abort();\n this.historyControllers.add(controller);\n try {\n controller.signal.throwIfAborted();\n const result = await loadImmutableHistory({ manifest, signal: controller.signal });\n controller.signal.throwIfAborted();\n return result;\n } finally {\n this.historyControllers.delete(controller);\n options?.signal?.removeEventListener(\"abort\", abort);\n }\n }\n\n /** Optional framework-independent host diagnostics, cleared on disposal. */\n setHostDiagnostics(provider?: () => Record<string, unknown>): void {\n this.hostDiagnostics = provider;\n }\n\n /** On-demand ownership diagnostics; contains no credentials or user/account data. */\n getDiagnostics(): AggWebSocketDiagnostics {\n return {\n connected: this.connected,\n host: this.hostDiagnostics?.(),\n transport: this.destroyed ? \"disposed\" : \"direct\",\n orderbookOutcomeIds: this.activeOrderbookMarkets(),\n tradeOutcomeIds: this.activeTradeMarkets(),\n arbMarketIds: this.activeArbMarkets(),\n arbFeedSubscribers: this.arbFeedCbs.size,\n cachedBooks: this.books.size,\n cachedArb: this.latestArb.size,\n resyncingBooks: this.resyncing.size,\n pendingResnapshots: this.pendingResnapshots.size,\n pendingHistoryRequests: this.historyControllers.size,\n };\n }\n\n /** Get the current orderbook state for an outcome (or null if no snapshot received yet). */\n getBook(outcomeId: string): OrderbookState | null {\n return this.books.get(outcomeId)?.view() ?? null;\n }\n\n /** Whether an outcome is currently resyncing (waiting for fresh snapshot). */\n isResyncing(outcomeId: string): boolean {\n return this.resyncing.has(outcomeId);\n }\n\n /** Get the latest arb update for a market (or null if none received yet). */\n getArb(marketId: string): WsArbMarketUpdate | null {\n return this.latestArb.get(marketId) ?? null;\n }\n\n /**\n * Subscribe to per-market arb updates for a given marketId.\n * Ref-counted: multiple callers for the same marketId share one server subscription.\n * Returns an unsubscribe function.\n */\n subscribeArb(marketId: string, cb: (m: WsArbMarketUpdate) => void): () => void {\n let entry = this.arbSubs.get(marketId);\n if (!entry) {\n entry = { refCount: 0, cbs: new Set() };\n this.arbSubs.set(marketId, entry);\n this.ensureConnected();\n if (this._connected) {\n this.pendingFlushArbUnsubs.delete(marketId);\n this.pendingFlushArbSubs.add(marketId);\n this.scheduleFlush();\n }\n }\n entry.cbs.add(cb);\n entry.refCount++;\n\n return () => {\n const e = this.arbSubs.get(marketId);\n if (!e) return;\n e.cbs.delete(cb);\n e.refCount--;\n if (e.refCount <= 0) {\n this.arbSubs.delete(marketId);\n if (this._connected) {\n if (this.pendingFlushArbSubs.has(marketId)) {\n // Net-zero pair: sub frame not yet sent — just cancel it.\n this.pendingFlushArbSubs.delete(marketId);\n } else {\n this.pendingFlushArbUnsubs.add(marketId);\n this.scheduleFlush();\n }\n }\n }\n };\n }\n\n /**\n * Subscribe to the global arb-feed batches.\n * Only one server subscription is maintained regardless of how many callers.\n * Returns an unsubscribe function.\n */\n subscribeArbFeed(cb: (b: WsArbFeedBatch) => void): () => void {\n const wasEmpty = this.arbFeedCbs.size === 0;\n this.arbFeedCbs.add(cb);\n if (wasEmpty) {\n this.ensureConnected();\n if (this._connected) {\n this.send({ action: \"subscribe\", channel: \"arb-feed\" });\n }\n }\n\n return () => {\n this.arbFeedCbs.delete(cb);\n if (this.arbFeedCbs.size === 0 && this._connected) {\n this.send({ action: \"unsubscribe\", channel: \"arb-feed\" });\n }\n };\n }\n\n /**\n * Subscribe to a feed by outcome ID.\n * @param outcomeId The venueMarketOutcomeId to subscribe to.\n * @param channel \"orderbook\" (default) or \"trades\".\n * Returns an unsubscribe function (ref-counted).\n */\n subscribe(outcomeId: string, channel: \"orderbook\" | \"trades\" = \"orderbook\"): () => void {\n if (channel === \"trades\") {\n return this._subscribeTrades(outcomeId);\n }\n\n let sub = this.subs.get(outcomeId);\n if (!sub) {\n sub = { refCount: 0, tradeRefs: 0 };\n this.subs.set(outcomeId, sub);\n }\n if (sub.refCount === 0) {\n this.bookCheckedAt.set(outcomeId, Date.now());\n this.pendingSubs.add(outcomeId);\n this.ensureConnected();\n if (this._connected) {\n // Queue for microtask-batched flush. Cancel any queued unsub for this id.\n this.pendingFlushUnsubs.delete(outcomeId);\n this.pendingFlushSubs.add(outcomeId);\n this.pendingSubs.delete(outcomeId);\n this.scheduleFlush();\n }\n }\n sub.refCount++;\n let released = false;\n\n return () => {\n if (released) return;\n released = true;\n const s = this.subs.get(outcomeId);\n if (!s) return;\n s.refCount--;\n if (s.refCount <= 0) {\n s.refCount = 0;\n if (s.tradeRefs <= 0) {\n this.subs.delete(outcomeId);\n this.books.delete(outcomeId);\n }\n this.resyncing.delete(outcomeId);\n this.bookCheckedAt.delete(outcomeId);\n this.watchdogResnapshotted.delete(outcomeId);\n if (this._connected) {\n // If a sub frame for this id is still queued, the server has NOT\n // seen a subscribe for it yet — just cancel the queued sub and\n // don't emit an unsubscribe (net-zero pair).\n if (this.pendingFlushSubs.has(outcomeId)) {\n this.pendingFlushSubs.delete(outcomeId);\n } else {\n // Server already knows about this sub — queue the unsubscribe.\n this.pendingFlushUnsubs.add(outcomeId);\n this.scheduleFlush();\n }\n }\n this.pendingSubs.delete(outcomeId);\n this.pendingResnapshots.delete(outcomeId);\n }\n };\n }\n\n /**\n * Subscribe to an outcome's trade feed.\n * @deprecated Use `subscribe(outcomeId, \"trades\")` instead.\n * Returns an unsubscribe function.\n */\n subscribeTrades(outcomeId: string): () => void {\n return this._subscribeTrades(outcomeId);\n }\n\n private _subscribeTrades(outcomeId: string): () => void {\n let sub = this.subs.get(outcomeId);\n if (!sub) {\n sub = { refCount: 0, tradeRefs: 0 };\n this.subs.set(outcomeId, sub);\n }\n if (sub.tradeRefs === 0) {\n this.pendingTradeSubs.add(outcomeId);\n this.ensureConnected();\n if (this._connected) {\n // Queue for microtask-batched flush. Cancel any queued unsub for this id.\n this.pendingFlushTradeUnsubs.delete(outcomeId);\n this.pendingFlushTradeSubs.add(outcomeId);\n this.pendingTradeSubs.delete(outcomeId);\n this.scheduleFlush();\n }\n }\n sub.tradeRefs++;\n let released = false;\n\n return () => {\n if (released) return;\n released = true;\n const s = this.subs.get(outcomeId);\n if (!s) return;\n s.tradeRefs--;\n if (s.tradeRefs <= 0) {\n s.tradeRefs = 0;\n if (this._connected) {\n // If a sub frame for this id is still queued, the server has NOT\n // seen a subscribe for it yet — just cancel the queued sub and\n // don't emit an unsubscribe (net-zero pair).\n if (this.pendingFlushTradeSubs.has(outcomeId)) {\n this.pendingFlushTradeSubs.delete(outcomeId);\n } else {\n // Server already knows about this trade sub — queue the unsubscribe.\n this.pendingFlushTradeUnsubs.add(outcomeId);\n this.scheduleFlush();\n }\n }\n this.pendingTradeSubs.delete(outcomeId);\n this.pendingResnapshots.delete(outcomeId);\n if (s.refCount <= 0) {\n this.subs.delete(outcomeId);\n this.books.delete(outcomeId);\n this.resyncing.delete(outcomeId);\n }\n }\n };\n }\n\n /** Send a JWT to authenticate (or re-authenticate) the connection. */\n authenticate(token: string): void {\n // Reconnects authenticate with the latest token, not the one from construction.\n this.initialToken = token;\n if (this._connected) {\n this.send({ action: \"authenticate\", token });\n }\n }\n\n /** Request a fresh snapshot for one or more subscribed outcomes. */\n resnapshot(outcomeIdOrIds: string | string[]): void {\n const outcomeIds = Array.isArray(outcomeIdOrIds) ? outcomeIdOrIds : [outcomeIdOrIds];\n\n outcomeIds.forEach((outcomeId) => {\n this.requestResnapshot(outcomeId, true);\n });\n }\n\n /** Connect (idempotent). Called automatically on first subscribe. */\n connect(): void {\n this.ensureConnected();\n }\n\n /** Disconnect and clean up. Reusable — call connect() to reconnect. */\n disconnect(): void {\n this.cancelReconnect();\n this.cancelStaleTimer();\n this._connected = false;\n this.connecting = false;\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect loop\n this.ws.close();\n this.ws = null;\n }\n this.callbacks.onConnectionStateChange?.(false);\n }\n\n /** Permanently destroy. Cannot reconnect after this. */\n destroy(): void {\n this.destroyed = true;\n for (const controller of this.historyControllers)\n controller.abort(new Error(\"Market-data client disposed\"));\n this.historyControllers.clear();\n this.disconnect();\n this.hostDiagnostics = undefined;\n this.callbacks = {};\n this.subs.clear();\n this.books.clear();\n this.resyncing.clear();\n if (this.watchdogTimer) clearInterval(this.watchdogTimer);\n this.watchdogTimer = null;\n this.watchdogAbort?.abort();\n this.watchdogAbort = null;\n this.bookCheckedAt.clear();\n this.watchdogResnapshotted.clear();\n this.pendingSubs.clear();\n this.pendingTradeSubs.clear();\n this.pendingResnapshots.clear();\n this.pendingFlushSubs.clear();\n this.pendingFlushUnsubs.clear();\n this.pendingFlushTradeSubs.clear();\n this.pendingFlushTradeUnsubs.clear();\n this.arbSubs.clear();\n this.arbFeedCbs.clear();\n this.latestArb.clear();\n this.pendingFlushArbSubs.clear();\n this.pendingFlushArbUnsubs.clear();\n this.flushScheduled = false;\n }\n\n /** Update callbacks (e.g., after React re-render). */\n setCallbacks(callbacks: AggWebSocketCallbacks): void {\n this.callbacks = callbacks;\n }\n\n // ── Connection management ──\n\n private ensureConnected(): void {\n if (this.destroyed) return;\n if (this.ws?.readyState === WebSocket.OPEN || this.connecting) return;\n this.doConnect();\n }\n\n private doConnect(): void {\n if (this.destroyed) return;\n this.connecting = true;\n const ws = new WebSocket(this.url);\n this.ws = ws;\n\n ws.onopen = () => {\n if (this.destroyed || this.ws !== ws) return;\n this.connecting = false;\n this.reconnectAttempts = 0;\n this.resetStaleTimer();\n\n // Authenticate before subscribing (token is sent over the open connection, not in the URL).\n // Auth is safe to send immediately on open — it doesn't depend on the\n // server's \"connected\" confirmation.\n if (this.initialToken) {\n this.send({ action: \"authenticate\", token: this.initialToken });\n }\n\n // Don't set _connected or flush pending subs here — wait for the\n // server's { type: \"connected\" } message to ensure the gateway has\n // validated our appId and is ready to accept subscriptions.\n };\n\n ws.onmessage = (event: MessageEvent) => {\n if (this.destroyed || this.ws !== ws) return;\n this.lastMessageTime = Date.now();\n this.callbacks.onFrameReceived?.(this.lastMessageTime);\n this.resetStaleTimer();\n try {\n const raw = JSON.parse(event.data as string) as Record<string, unknown>;\n this.handleMessage(raw);\n } catch {\n // Ignore parse errors\n }\n };\n\n ws.onclose = () => {\n this.ws = null;\n this.connecting = false;\n const wasConnected = this._connected;\n this._connected = false;\n this.cancelStaleTimer();\n\n if (wasConnected) {\n this.callbacks.onConnectionStateChange?.(false);\n }\n\n // Only reconnect if we have active subs and aren't destroyed\n if (\n !this.destroyed &&\n (this.subs.size > 0 || this.arbSubs.size > 0 || this.arbFeedCbs.size > 0)\n ) {\n this.scheduleReconnect();\n }\n };\n\n ws.onerror = () => {\n // onclose fires after onerror\n };\n }\n\n private scheduleReconnect(): void {\n this.cancelReconnect();\n const delay = Math.min(\n RECONNECT_BASE_MS * Math.pow(2, this.reconnectAttempts),\n RECONNECT_MAX_MS,\n );\n this.reconnectAttempts++;\n this.emitDiagnostic({ type: \"reconnect\", attempt: this.reconnectAttempts, delayMs: delay });\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.doConnect();\n }, delay);\n }\n\n private cancelReconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n // ── Staleness detection ──\n\n private resetStaleTimer(): void {\n this.cancelStaleTimer();\n this.staleTimer = setTimeout(() => {\n const age = Date.now() - this.lastMessageTime;\n this.emitDiagnostic({ type: \"stale_connection\", lastMessageAge: age });\n // Force reconnect\n if (this.ws) {\n this.ws.close();\n }\n }, STALE_TIMEOUT_MS);\n }\n\n private cancelStaleTimer(): void {\n if (this.staleTimer) {\n clearTimeout(this.staleTimer);\n this.staleTimer = null;\n }\n }\n\n // ── Message handling ──\n\n private handleMessage(raw: Record<string, unknown>): void {\n const type = raw.type as string;\n if (\n [\"orderbook_snapshot\", \"orderbook_delta\", \"trade\"].includes(type) &&\n !validMarketFrame(raw)\n ) {\n this.callbacks.onError?.({ type: \"error\", message: \"Invalid market-data frame\" });\n if (typeof raw.outcomeId === \"string\" && this.subs.has(raw.outcomeId))\n this.requestResnapshot(raw.outcomeId);\n return;\n }\n switch (type) {\n case \"orderbook_snapshot\":\n this.handleSnapshot(raw as unknown as WsOrderbookSnapshot);\n break;\n case \"orderbook_delta\":\n this.handleDelta(raw as unknown as WsOrderbookDelta);\n break;\n case \"trade\":\n this.handleTrade(raw as unknown as WsTrade);\n break;\n case \"heartbeat\":\n this.handleHeartbeat(raw as unknown as WsHeartbeat);\n break;\n case \"subscribed\":\n this.callbacks.onSubscribed?.(raw as unknown as WsSubscribed);\n break;\n case \"unsubscribed\":\n this.callbacks.onUnsubscribed?.(raw as unknown as WsUnsubscribed);\n break;\n case \"connected\":\n this.handleConnected(raw as unknown as WsConnected);\n break;\n case \"authenticated\":\n this.callbacks.onAuthenticated?.(raw as unknown as WsAuthenticated);\n break;\n case \"market_resolved\":\n this.handleMarketResolved(raw as unknown as WsMarketResolved);\n break;\n case \"error\":\n this.callbacks.onError?.(raw as unknown as WsError);\n break;\n case \"order_submitted\":\n this.handleOrderSubmitted(raw as unknown as WsOrderSubmitted);\n break;\n case \"balance_update\":\n this.handleBalanceUpdate(raw as unknown as WsBalanceUpdate);\n break;\n case \"order_event\":\n if (this.callbacks.onOrderEventReceipt) {\n const receivedAtMs = Date.now();\n const serverTimestampMs =\n typeof raw.timestamp === \"number\" && Number.isFinite(raw.timestamp) && raw.timestamp > 0\n ? raw.timestamp\n : null;\n try {\n this.callbacks.onOrderEventReceipt({\n orderId: String(raw.orderId ?? \"\"),\n event: (raw as unknown as WsOrderEvent).event,\n serverTimestampMs,\n receivedAtMs,\n deliveryDelayMs:\n serverTimestampMs !== null && receivedAtMs >= serverTimestampMs\n ? receivedAtMs - serverTimestampMs\n : null,\n });\n } catch {\n /* Telemetry must never suppress the order event. */\n }\n }\n this.callbacks.onOrderEvent?.(raw as unknown as WsOrderEvent);\n break;\n case \"redeem_event\":\n this.handleRedeemEvent(raw as unknown as WsRedeemEvent);\n break;\n case \"withdrawal_lifecycle\":\n // Timestamp left as raw ms — the SDK type explicitly documents this\n // event's timestamp as milliseconds (matches WsOrderEvent), unlike\n // the orderbook/trade events which are normalized to seconds.\n this.callbacks.onWithdrawalLifecycle?.(raw as unknown as WsWithdrawalLifecycleEvent);\n break;\n case \"arb_market_update\": {\n const arbMsg = raw as unknown as WsArbMarketUpdate;\n this.latestArb.set(arbMsg.marketId, arbMsg);\n const arbEntry = this.arbSubs.get(arbMsg.marketId);\n if (arbEntry) {\n for (const cb of arbEntry.cbs) cb(arbMsg);\n }\n this.callbacks.onArbMarket?.(arbMsg);\n break;\n }\n case \"arb_feed_batch\": {\n const feedMsg = raw as unknown as WsArbFeedBatch;\n for (const cb of this.arbFeedCbs) cb(feedMsg);\n this.callbacks.onArbFeed?.(feedMsg);\n break;\n }\n }\n }\n\n /**\n * Server confirmed the connection — gateway has validated our appId and is\n * ready to accept subscriptions. Now flush all pending subs.\n */\n private handleConnected(msg: WsConnected): void {\n this._connected = true;\n if (this.bookWatchdog && !this.watchdogTimer && !this.destroyed) {\n this.watchdogTimer = setInterval(\n () => void this.checkSilentBooks(),\n this.bookWatchdog.checkIntervalMs ?? WATCHDOG_CHECK_INTERVAL_MS,\n );\n }\n this.callbacks.onConnectionStateChange?.(true);\n this.callbacks.onConnected?.(msg);\n\n // Flush pending orderbook subscriptions. The active-subscription resend\n // invariant means we resubscribe every market with refCount > 0 on every\n // (re)connect, merged with any pre-connect pendingSubs.\n const orderbookSet = new Set(this.activeOrderbookMarkets());\n const reconnectedAt = Date.now();\n for (const id of orderbookSet) {\n if (this.bookCheckedAt.has(id)) this.bookCheckedAt.set(id, reconnectedAt);\n }\n this.pendingSubs.forEach((id) => orderbookSet.add(id));\n this.pendingFlushSubs.forEach((id) => orderbookSet.add(id));\n const orderbookIds = Array.from(orderbookSet);\n if (orderbookIds.length > 0) {\n this.sendSubscribe(orderbookIds);\n }\n this.pendingSubs.clear();\n this.pendingFlushSubs.clear();\n // Any queued unsubs are already reflected in activeOrderbookMarkets()\n // (their refCount went to zero and their entry was deleted from subs),\n // so we just discard them — nothing to unsubscribe from the server's\n // perspective on a fresh connection.\n this.pendingFlushUnsubs.clear();\n\n // Flush pending trade subscriptions\n const tradeSet = new Set(this.activeTradeMarkets());\n this.pendingTradeSubs.forEach((id) => tradeSet.add(id));\n this.pendingFlushTradeSubs.forEach((id) => tradeSet.add(id));\n const tradeIds = Array.from(tradeSet);\n if (tradeIds.length > 0) {\n this.send({ action: \"subscribe\", channel: \"trades\", outcomeIds: tradeIds });\n }\n this.pendingTradeSubs.clear();\n this.pendingFlushTradeSubs.clear();\n this.pendingFlushTradeUnsubs.clear();\n\n // Flush pending resnapshots\n const resnapshotIds = Array.from(this.pendingResnapshots);\n if (resnapshotIds.length > 0) {\n this.send({ action: \"resnapshot\", channel: \"orderbook\", outcomeIds: resnapshotIds });\n }\n this.pendingResnapshots.clear();\n\n // Flush arb-market subscriptions (active + any pre-connect queued)\n const arbSet = new Set(this.activeArbMarkets());\n this.pendingFlushArbSubs.forEach((id) => arbSet.add(id));\n const arbIds = Array.from(arbSet);\n if (arbIds.length > 0) {\n this.send({ action: \"subscribe\", channel: \"arb\", marketIds: arbIds });\n }\n this.pendingFlushArbSubs.clear();\n this.pendingFlushArbUnsubs.clear();\n\n // Re-subscribe arb-feed if there are active listeners\n if (this.arbFeedCbs.size > 0) {\n this.send({ action: \"subscribe\", channel: \"arb-feed\" });\n }\n }\n\n private handleSnapshot(raw: WsOrderbookSnapshot): void {\n if (!this.subs.has(raw.outcomeId)) return;\n // Normalize timestamps: ms → seconds\n const msg: WsOrderbookSnapshot = { ...raw, timestamp: raw.timestamp / 1000 };\n const book = snapshotToOrderbook(msg);\n this.books.set(msg.outcomeId, new IndexedOrderbook(book));\n this.bookCheckedAt.set(msg.outcomeId, Date.now());\n this.resyncing.delete(msg.outcomeId);\n this.pendingResnapshots.delete(msg.outcomeId);\n this.debugOrderbook(\"snapshot_applied\", {\n outcomeId: msg.outcomeId,\n seq: msg.seq,\n checksum: msg.checksum,\n bidsTop: this.summarizeTopLevels(book.bids),\n asksTop: this.summarizeTopLevels(book.asks),\n });\n this.callbacks.onBookTick?.(msg.outcomeId, {\n midpoint: msg.midpoint,\n timestamp: msg.timestamp,\n source: \"snapshot\",\n });\n if (!this.deferBookViews) this.callbacks.onSnapshot?.(msg.outcomeId, book);\n }\n\n private handleDelta(raw: WsOrderbookDelta): void {\n if (!this.subs.has(raw.outcomeId)) return;\n const outcomeId = raw.outcomeId;\n const current = this.books.get(outcomeId);\n if (!current) {\n // No snapshot yet — request one\n this.debugOrderbook(\"delta_missing_snapshot\", { outcomeId, seq: raw.seq });\n this.requestResnapshot(outcomeId);\n return;\n }\n\n // Stale delta — already included in our snapshot. With the gateway's\n // snapshot-sync gate this should be rare (the gateway filters stale\n // replays itself), but we keep the SDK-side drop as defense in depth\n // against any pre-snapshot delta that slips through.\n if (raw.seq <= current.seq) {\n this.debugOrderbook(\"delta_stale_ignored\", {\n outcomeId,\n currentSeq: current.seq,\n receivedSeq: raw.seq,\n });\n return;\n }\n\n // Seq gap detection — with the gateway's atomic snapshot+replay this\n // should not fire under normal operation; if it does, request a\n // resnapshot rather than apply a delta to a divergent local book.\n if (raw.seq > current.seq + 1) {\n this.debugOrderbook(\"delta_seq_gap\", {\n outcomeId,\n expectedSeq: current.seq + 1,\n receivedSeq: raw.seq,\n });\n this.emitDiagnostic({\n type: \"seq_gap\",\n marketId: outcomeId,\n outcomeId,\n expected: current.seq + 1,\n received: raw.seq,\n });\n this.requestResnapshot(outcomeId);\n return;\n }\n\n // Normalize timestamps: ms → seconds\n const msg: WsOrderbookDelta = { ...raw, timestamp: raw.timestamp / 1000 };\n const computed = current.apply(msg);\n if (computed !== msg.checksum) {\n this.debugOrderbook(\"delta_checksum_mismatch\", {\n outcomeId,\n seq: msg.seq,\n expected: msg.checksum,\n computed,\n });\n this.emitDiagnostic({\n type: \"checksum_mismatch\",\n marketId: outcomeId,\n outcomeId,\n expected: msg.checksum,\n computed,\n });\n this.requestResnapshot(outcomeId);\n return;\n }\n\n this.bookCheckedAt.set(outcomeId, Date.now());\n this.watchdogResnapshotted.delete(outcomeId);\n this.callbacks.onBookTick?.(outcomeId, {\n midpoint: msg.midpoint,\n timestamp: msg.timestamp,\n source: \"delta\",\n });\n if (!this.deferBookViews) this.callbacks.onDelta?.(outcomeId, current.view());\n }\n\n private handleTrade(raw: WsTrade): void {\n if (!this.subs.has(raw.outcomeId)) return;\n const msg: WsTrade = { ...raw, timestamp: raw.timestamp / 1000 };\n this.callbacks.onTrade?.(msg);\n }\n\n private handleHeartbeat(raw: WsHeartbeat): void {\n const msg: WsHeartbeat = { ...raw, ts: raw.ts / 1000 };\n this.callbacks.onHeartbeat?.(msg);\n }\n\n private handleMarketResolved(raw: WsMarketResolved): void {\n const msg: WsMarketResolved = { ...raw, timestamp: raw.timestamp / 1000 };\n this.books.delete(msg.outcomeId);\n this.bookCheckedAt.delete(msg.outcomeId);\n this.watchdogResnapshotted.delete(msg.outcomeId);\n this.pendingResnapshots.delete(msg.outcomeId);\n this.resyncing.delete(msg.outcomeId);\n this.callbacks.onMarketResolved?.(msg);\n }\n\n private handleOrderSubmitted(raw: WsOrderSubmitted): void {\n const msg: WsOrderSubmitted = { ...raw, timestamp: raw.timestamp / 1000 };\n this.callbacks.onOrderSubmitted?.(msg);\n }\n\n private handleBalanceUpdate(raw: WsBalanceUpdate): void {\n const msg: WsBalanceUpdate = { ...raw, timestamp: raw.timestamp / 1000 };\n this.callbacks.onBalanceUpdate?.(msg);\n }\n\n private handleRedeemEvent(raw: WsRedeemEvent): void {\n const msg: WsRedeemEvent = { ...raw, timestamp: raw.timestamp / 1000 };\n this.callbacks.onRedeemEvent?.(msg);\n }\n\n // ── Book watchdog ──\n\n /**\n * Heartbeats prove the socket, not each stream. Every subscribed outcome\n * with no progress for `silenceMs` is checked against the REST `seq`:\n *\n * - book present, not resyncing, same `seq` → the market is just quiet;\n * - different `seq`, no book (snapshot never arrived, or a resubscribe's\n * snapshot was lost), or stuck resyncing (any recovery whose snapshot\n * was lost) → resnapshot, then resubscribe on the next overdue check;\n * - REST can't serve it (`null`) → counted as an attempt, so the next\n * batch moves on to other outcomes instead of retrying the same 100.\n */\n private async checkSilentBooks(): Promise<void> {\n const opts = this.bookWatchdog;\n if (!opts || !this._connected || this.watchdogAbort) return;\n const now = Date.now();\n if (now < this.watchdogPausedUntil) return;\n const silenceMs = opts.silenceMs ?? WATCHDOG_SILENCE_MS;\n const silent = this.activeOrderbookMarkets()\n .filter((id) => this.bookCheckedAt.has(id))\n .filter((id) => now - this.bookCheckedAt.get(id)! >= silenceMs)\n .sort((a, b) => this.bookCheckedAt.get(a)! - this.bookCheckedAt.get(b)!)\n .slice(0, WATCHDOG_BATCH_MAX);\n if (silent.length === 0) return;\n\n const checkedAt = new Map(silent.map((id) => [id, this.bookCheckedAt.get(id)]));\n const abort = new AbortController();\n this.watchdogAbort = abort;\n const timeout = setTimeout(() => abort.abort(), WATCHDOG_REQUEST_TIMEOUT_MS);\n try {\n const url = new URL(`${opts.baseUrl.replace(/\\/$/, \"\")}/orderbooks/outcomes`);\n url.searchParams.set(\"venueMarketOutcomeIds\", silent.join(\",\"));\n url.searchParams.set(\"depth\", \"1\");\n const response = await fetch(url, { headers: opts.headers, signal: abort.signal });\n if (!response.ok) {\n const retryAfterS = Number(response.headers.get(\"retry-after\"));\n if (response.status === 429 && retryAfterS > 0) {\n this.watchdogPausedUntil = Date.now() + retryAfterS * 1000;\n }\n this.emitDiagnostic({ type: \"book_watchdog_error\", status: response.status });\n return;\n }\n const body = (await response.json()) as { data: Array<{ seq: number } | null> };\n if (this.destroyed) return;\n silent.forEach((outcomeId, i) => {\n // Skip outcomes that progressed (or were unsubscribed) while we asked.\n if (this.bookCheckedAt.get(outcomeId) !== checkedAt.get(outcomeId)) return;\n const server = body.data?.[i];\n if (!server) {\n this.bookCheckedAt.set(outcomeId, Date.now());\n return;\n }\n const book = this.books.get(outcomeId);\n if (book && !this.resyncing.has(outcomeId) && server.seq === book.seq) {\n this.bookCheckedAt.set(outcomeId, Date.now());\n this.watchdogResnapshotted.delete(outcomeId);\n return;\n }\n const action = this.watchdogResnapshotted.has(outcomeId) ? \"resubscribe\" : \"resnapshot\";\n this.emitDiagnostic({\n type: \"book_watchdog_resync\",\n outcomeId,\n localSeq: book?.seq ?? null,\n serverSeq: server.seq,\n action,\n });\n // Either way the recovery gets a full silence window to land.\n this.bookCheckedAt.set(outcomeId, Date.now());\n if (action === \"resubscribe\") {\n this.watchdogResnapshotted.delete(outcomeId);\n this.books.delete(outcomeId);\n this.resyncing.add(outcomeId);\n this.send({ action: \"unsubscribe\", channel: \"orderbook\", outcomeIds: [outcomeId] });\n this.sendSubscribe([outcomeId]);\n } else {\n this.watchdogResnapshotted.add(outcomeId);\n this.requestResnapshot(outcomeId, true);\n }\n });\n } catch {\n if (!this.destroyed) this.emitDiagnostic({ type: \"book_watchdog_error\", status: null });\n } finally {\n clearTimeout(timeout);\n if (this.watchdogAbort === abort) this.watchdogAbort = null;\n }\n }\n\n // ── Resnapshot ──\n\n private requestResnapshot(outcomeId: string, force = false): void {\n if (this.resyncing.has(outcomeId) && !force) return;\n this.resyncing.add(outcomeId);\n if (this._connected) {\n this.send({ action: \"resnapshot\", channel: \"orderbook\", outcomeIds: [outcomeId] });\n this.pendingResnapshots.delete(outcomeId);\n return;\n }\n\n this.pendingResnapshots.add(outcomeId);\n this.ensureConnected();\n }\n\n // ── Helpers ──\n\n /**\n * Schedule a microtask that flushes queued subscribe/unsubscribe frames.\n * Coalesces multiple same-tick sub/unsub calls into at most one frame per\n * channel+action pair.\n */\n private scheduleFlush(): void {\n if (this.flushScheduled) return;\n this.flushScheduled = true;\n queueMicrotask(() => {\n this.flushScheduled = false;\n // If we lost the connection before the microtask ran, drop the queues —\n // handleConnected will resend the full active-subscription set on\n // reconnect, which is the correct source of truth.\n if (!this._connected) {\n this.pendingFlushSubs.clear();\n this.pendingFlushUnsubs.clear();\n this.pendingFlushTradeSubs.clear();\n this.pendingFlushTradeUnsubs.clear();\n this.pendingFlushArbSubs.clear();\n this.pendingFlushArbUnsubs.clear();\n return;\n }\n this.flushPending();\n });\n }\n\n private flushPending(): void {\n // Orderbook: drop net-zero pairs before emitting.\n for (const id of [...this.pendingFlushSubs]) {\n if (this.pendingFlushUnsubs.has(id)) {\n this.pendingFlushSubs.delete(id);\n this.pendingFlushUnsubs.delete(id);\n }\n }\n if (this.pendingFlushSubs.size > 0) {\n this.sendSubscribe(Array.from(this.pendingFlushSubs));\n this.pendingFlushSubs.clear();\n }\n if (this.pendingFlushUnsubs.size > 0) {\n this.send({\n action: \"unsubscribe\",\n channel: \"orderbook\",\n outcomeIds: Array.from(this.pendingFlushUnsubs),\n });\n this.pendingFlushUnsubs.clear();\n }\n\n // Trades: same net-zero cancellation.\n for (const id of [...this.pendingFlushTradeSubs]) {\n if (this.pendingFlushTradeUnsubs.has(id)) {\n this.pendingFlushTradeSubs.delete(id);\n this.pendingFlushTradeUnsubs.delete(id);\n }\n }\n if (this.pendingFlushTradeSubs.size > 0) {\n this.send({\n action: \"subscribe\",\n channel: \"trades\",\n outcomeIds: Array.from(this.pendingFlushTradeSubs),\n });\n this.pendingFlushTradeSubs.clear();\n }\n if (this.pendingFlushTradeUnsubs.size > 0) {\n this.send({\n action: \"unsubscribe\",\n channel: \"trades\",\n outcomeIds: Array.from(this.pendingFlushTradeUnsubs),\n });\n this.pendingFlushTradeUnsubs.clear();\n }\n\n // Arb: same net-zero cancellation.\n for (const id of [...this.pendingFlushArbSubs]) {\n if (this.pendingFlushArbUnsubs.has(id)) {\n this.pendingFlushArbSubs.delete(id);\n this.pendingFlushArbUnsubs.delete(id);\n }\n }\n if (this.pendingFlushArbSubs.size > 0) {\n this.send({\n action: \"subscribe\",\n channel: \"arb\",\n marketIds: Array.from(this.pendingFlushArbSubs),\n });\n this.pendingFlushArbSubs.clear();\n }\n if (this.pendingFlushArbUnsubs.size > 0) {\n this.send({\n action: \"unsubscribe\",\n channel: \"arb\",\n marketIds: Array.from(this.pendingFlushArbUnsubs),\n });\n this.pendingFlushArbUnsubs.clear();\n }\n }\n\n private sendSubscribe(outcomeIds: string[]): void {\n this.send({ action: \"subscribe\", channel: \"orderbook\", outcomeIds });\n }\n\n private send(msg: unknown): void {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(msg));\n }\n }\n\n private activeOrderbookMarkets(): string[] {\n const markets: string[] = [];\n this.subs.forEach((sub, id) => {\n if (sub.refCount > 0) markets.push(id);\n });\n return markets;\n }\n\n private activeTradeMarkets(): string[] {\n const markets: string[] = [];\n this.subs.forEach((sub, id) => {\n if (sub.tradeRefs > 0) markets.push(id);\n });\n return markets;\n }\n\n private activeArbMarkets(): string[] {\n return Array.from(this.arbSubs.keys());\n }\n\n private emitDiagnostic(event: DiagnosticEvent): void {\n this.callbacks.onDiagnostics?.(event);\n }\n\n private summarizeTopLevels(\n levels: Array<{ price: number; size: number }>,\n ): Array<{ price: number; size: number }> {\n return levels\n .slice(0, ORDERBOOK_DEBUG_TOP_LEVELS)\n .map((level) => ({ price: level.price, size: level.size }));\n }\n\n private debugOrderbook(event: string, payload: Record<string, unknown>): void {\n if (!this.isOrderbookDebugEnabled()) return;\n\n console.debug(`[AggWebSocket][orderbook] ${event}`, payload);\n }\n\n private isOrderbookDebugEnabled(): boolean {\n return this.enableLogs;\n }\n}\n"],"mappings":"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"}