@poolse/sdk 2.0.0 → 2.0.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/realtime/realtime.ts","../src/resources/attachments.ts","../src/resources/messages.ts","../src/resources/conversations.ts","../src/resources/me.ts","../src/resources/users.ts","../src/rest-client.ts","../src/token-cache.ts","../src/poolse.ts","../src/version.ts"],"names":["Socket"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Hosted poolse API URL. Used as the default for `PoolseConfig.apiUrl`\n * when you don't pass one — appropriate for the vast majority of\n * integrations that target the official poolse cloud. Self-hosted /\n * staging deployments override via the `apiUrl` field.\n */\nexport const POOLSE_API_URL = 'https://api.poolse.dev';\n\nimport type { PoolseUserProfile } from './types.js';\n\n/**\n * SDK configuration passed to `new Poolse(config)`.\n */\nexport interface PoolseConfig {\n /**\n * Base URL of the poolse REST API. Defaults to the hosted endpoint\n * at `https://api.poolse.dev`. Override only for self-hosted /\n * staging deployments. MUST NOT include the `/v1` path — the SDK\n * adds that itself.\n */\n apiUrl?: string;\n\n /**\n * Async hook the SDK calls every time it needs an `Authorization:\n * Bearer <jwt>` header. Most apps refresh the JWT from their own\n * backend here — the SDK never talks to poolse's `POST\n * /v1/users/:user_id/tokens` itself (that endpoint is API-key-authed\n * and lives on the Customer's BACKEND, not the End User's device).\n *\n * Return `null` to deliberately make an unauthenticated request — the\n * server will reject it, but the SDK won't error inside `getToken`.\n */\n getToken: () => Promise<string | null> | string | null;\n\n /**\n * Optional fetch override. Browsers and Node 22+ both ship a global\n * `fetch`, but tests can inject a mock here; bundlers in restricted\n * environments can supply a polyfill.\n */\n fetch?: typeof globalThis.fetch;\n\n /**\n * Retry budget for transient failures (network + 5xx + 429). Defaults\n * to 3 attempts after the initial request. Set to 0 to disable.\n */\n maxRetries?: number;\n\n /**\n * Base for the exponential backoff, in milliseconds. Each retry waits\n * `min(maxBackoffMs, baseBackoffMs * 2^attempt)` plus jitter, OR honours\n * the `Retry-After` header if present. Default 250 ms.\n */\n baseBackoffMs?: number;\n\n /** Hard cap on a single retry delay. Default 30_000 ms. */\n maxBackoffMs?: number;\n\n /**\n * Override the idempotency-key generator. Defaults to\n * `crypto.randomUUID()`. Most apps don't need to override this — the\n * generator is exposed mainly for deterministic tests.\n */\n generateIdempotencyKey?: () => string;\n\n /**\n * Override the WebSocket URL. Defaults to `apiUrl` with `http(s)://`\n * swapped to `ws(s)://`, suitable when the realtime gateway shares\n * its origin with the REST API. Set explicitly for split-host\n * deployments (`https://api.example.com` REST + `wss://realtime.example.com` WS).\n */\n wsUrl?: string;\n\n /**\n * Path the WebSocket is mounted on. Defaults to `/socket` — matches\n * `CaasRealtimeWeb.UserSocket`'s mount point.\n */\n socketPath?: string;\n\n /**\n * Called when the underlying socket encounters a non-fatal error\n * (Phoenix retries internally). Useful for surfacing reconnect\n * banners in the UI without coupling to socket internals.\n */\n onSocketError?: (err: Error) => void;\n\n /**\n * Resolve the tenant's user identifier (`external_id` — same string\n * you pass when minting JWTs and referencing users in\n * `member_external_ids`) to the customer's own user metadata\n * (display name + avatar). Called by `chat.users.get(externalId)`\n * and the `useUser(externalId)` React hook whenever a UI component\n * needs to render a participant.\n *\n * The SDK caches results in-memory and dedupes concurrent calls,\n * so a busy chat with 50 messages from 5 senders fires the\n * resolver 5 times — once per unique sender — not 50.\n *\n * Customers hit their OWN backend / store here, keyed by **their own\n * user id** (no poolse uuid mapping required):\n *\n * userResolver: async (externalId) => {\n * const u = await fetch(`/api/users/${externalId}`).then((r) => r.json());\n * return { displayName: u.full_name, avatarUrl: u.avatar_url };\n * }\n *\n * Sync returns are fine when the data's already in memory:\n *\n * userResolver: (externalId) => directory[externalId] ?? null\n *\n * Return `null` when the user can't be found — components fall back\n * to the external_id as a label and an initials avatar.\n */\n userResolver?: (\n externalId: string,\n ) => Promise<PoolseUserProfile | null> | PoolseUserProfile | null;\n}\n\n/** Internal resolved config — all the defaults filled in. */\nexport interface ResolvedConfig {\n apiUrl: string;\n getToken: PoolseConfig['getToken'];\n fetch: typeof globalThis.fetch;\n maxRetries: number;\n baseBackoffMs: number;\n maxBackoffMs: number;\n generateIdempotencyKey: () => string;\n wsUrl: string | undefined;\n socketPath: string;\n onSocketError: ((err: Error) => void) | undefined;\n userResolver: PoolseConfig['userResolver'];\n}\n\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_BASE_BACKOFF_MS = 250;\nconst DEFAULT_MAX_BACKOFF_MS = 30_000;\n\nexport function resolveConfig(config: PoolseConfig): ResolvedConfig {\n if (typeof config.getToken !== 'function') {\n throw new Error('Poolse: `getToken` is required and must be a function.');\n }\n\n const rawFetch = config.fetch ?? globalThis.fetch;\n if (typeof rawFetch !== 'function') {\n throw new Error(\n 'Poolse: no global `fetch` found. Provide one via `config.fetch` ' +\n '(Node <18 or a sandboxed runtime).',\n );\n }\n // Bind to globalThis so the browser's `fetch` keeps its native `this`\n // (it throws \"Illegal invocation\" when called with any other receiver,\n // and `this.config.fetch(...)` in the RestClient strips the binding).\n // A consumer-supplied `config.fetch` is also bound the same way for\n // consistency — if they want a specific receiver they should bind it\n // themselves before passing it in.\n const fetchFn = rawFetch.bind(globalThis);\n\n return {\n apiUrl: trimTrailingSlash(config.apiUrl ?? POOLSE_API_URL),\n getToken: config.getToken,\n fetch: fetchFn,\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n baseBackoffMs: config.baseBackoffMs ?? DEFAULT_BASE_BACKOFF_MS,\n maxBackoffMs: config.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS,\n generateIdempotencyKey: config.generateIdempotencyKey ?? defaultIdempotencyKey,\n wsUrl: config.wsUrl,\n socketPath: config.socketPath ?? '/socket',\n onSocketError: config.onSocketError,\n userResolver: config.userResolver,\n };\n}\n\nfunction trimTrailingSlash(s: string): string {\n return s.endsWith('/') ? s.slice(0, -1) : s;\n}\n\nfunction defaultIdempotencyKey(): string {\n // crypto.randomUUID() is on globalThis in Node 19+ and browsers (where\n // available, in secure contexts). If a runtime lacks it, the caller\n // must supply `generateIdempotencyKey` in config.\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c && typeof c.randomUUID === 'function') {\n return c.randomUUID();\n }\n throw new Error(\n 'Poolse: globalThis.crypto.randomUUID() is not available; supply ' +\n '`config.generateIdempotencyKey` instead.',\n );\n}\n","// Typed error classes the SDK raises. Callers can `instanceof`-check to\n// decide whether to retry, prompt the user to re-login, etc. — the\n// alternative (parsing error.message strings) is brittle.\n\nimport type { ErrorEnvelope } from './types.js';\n\n/** Base for any error originating in the SDK. */\nexport class PoolseError extends Error {\n public override readonly name: string = 'PoolseError';\n\n constructor(message: string) {\n super(message);\n // Restore prototype chain across the TS down-level transform.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** fetch() rejected or the server returned no response at all. */\nexport class NetworkError extends PoolseError {\n public override readonly name: string = 'NetworkError';\n public override readonly cause: unknown;\n\n constructor(message: string, cause: unknown) {\n super(message);\n this.cause = cause;\n }\n}\n\n/**\n * Server returned a non-2xx status with the canonical error envelope.\n * `code` is poolse's snake_case error code (e.g. `\"invalid_user_token\"`).\n */\nexport class ApiError extends PoolseError {\n public override readonly name: string = 'ApiError';\n public readonly status: number;\n public readonly code: string;\n public readonly docUrl: string;\n public readonly details: Record<string, unknown> | undefined;\n\n constructor(status: number, envelope: ErrorEnvelope['error']) {\n super(`[${status}] ${envelope.code}: ${envelope.message}`);\n this.status = status;\n this.code = envelope.code;\n this.docUrl = envelope.doc_url;\n this.details = envelope.details;\n }\n}\n\n/**\n * 429 specifically. Surfaced as its own subclass so callers can back off\n * politely without parsing the generic ApiError.\n */\nexport class RateLimitedError extends ApiError {\n public override readonly name: string = 'RateLimitedError';\n public readonly retryAfterMs: number;\n\n constructor(envelope: ErrorEnvelope['error'], retryAfterMs: number) {\n super(429, envelope);\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/**\n * Auth failure (401, including expired/revoked tokens). Callers should\n * refresh the JWT (via `getToken`) and retry — the SDK does NOT do this\n * automatically, because the failure could also mean \"the user signed\n * out on another tab\" and silent re-auth would hide that.\n */\nexport class AuthError extends ApiError {\n public override readonly name: string = 'AuthError';\n\n constructor(envelope: ErrorEnvelope['error']) {\n super(401, envelope);\n }\n}\n","// poolse Realtime — thin wrapper over Phoenix.Socket.\n//\n// Responsibilities:\n// * Lazy connection: socket opens on the first `conversation()` / `user()` call.\n// * Auto-reconnect with exponential backoff (default Phoenix behavior is fine).\n// * Auto-rejoin channels on reconnect (Phoenix handles this for joined channels).\n// * Typed listener API: `conv.onMessage((msg) => …)`.\n// * Token refresh: re-pulls `getToken` on every (re)connect so a refreshed\n// JWT lands the next time without manual intervention.\n//\n// Designed to be `instanceof`-stable so React hooks can mount/unmount\n// without tearing down the socket — `Poolse` holds a single instance\n// and consumers get back the same handle for the same conversation id.\n\nimport { Socket } from 'phoenix';\nimport type { Channel } from 'phoenix';\n\nimport type { ResolvedConfig } from '../config.js';\nimport { PoolseError } from '../errors.js';\nimport type { TokenCache } from '../token-cache.js';\nimport type {\n ConversationCreatedEvent,\n MemberReadEvent,\n MentionEvent,\n MessageDeletedEvent,\n MessageNewEvent,\n MessageUpdatedEvent,\n PresenceSnapshot,\n ReactionEvent,\n RealtimeStatus,\n TypingEvent,\n Unsubscribe,\n} from './types.js';\n\ninterface RealtimeOptions {\n /**\n * WebSocket endpoint path (mounted in caas_realtime). Defaults to\n * `'/socket'` — matches the path served by `CaasRealtimeWeb.UserSocket`.\n */\n socketPath?: string;\n /**\n * Override the Phoenix-derived WebSocket URL. Use when the realtime\n * gateway lives on a different host than the REST API (most common\n * in prod: `https://api.example.com` for REST, `wss://realtime.example.com`\n * for WebSocket). When unset, the WS URL is derived from `apiUrl` by\n * swapping http(s) → ws(s).\n */\n wsUrl?: string;\n}\n\nexport class PoolseRealtime {\n private readonly config: ResolvedConfig;\n private readonly tokenCache: TokenCache;\n private readonly socketPath: string;\n private readonly wsUrl: string;\n\n private socket: Socket | null = null;\n private readonly conversations = new Map<string, ConversationChannel>();\n private userChannel: UserChannel | null = null;\n\n private status: RealtimeStatus = 'idle';\n private readonly statusListeners = new Set<(s: RealtimeStatus) => void>();\n\n constructor(config: ResolvedConfig, tokenCache: TokenCache, opts: RealtimeOptions = {}) {\n this.config = config;\n this.tokenCache = tokenCache;\n this.socketPath = opts.socketPath ?? '/socket';\n this.wsUrl = opts.wsUrl ?? deriveWsUrl(config.apiUrl);\n }\n\n /** Current connection status. */\n getStatus(): RealtimeStatus {\n return this.status;\n }\n\n /** Subscribe to connection-status changes. */\n onStatus(listener: (status: RealtimeStatus) => void): Unsubscribe {\n this.statusListeners.add(listener);\n return () => this.statusListeners.delete(listener);\n }\n\n /**\n * Open the socket (idempotent). Synchronous construction so callers\n * can join a channel on the next line; the underlying WebSocket\n * connects on the next tick once the JWT pre-fetch resolves.\n *\n * Phoenix.js invokes the `params` callback SYNCHRONOUSLY on every\n * (re)connect and does NOT await its return value — see\n * `phoenix/priv/static/phoenix.mjs::endPointURL`. So `params` has\n * to read a token that's already in hand. We:\n *\n * 1. Construct the Socket immediately (sets `this.socket` so\n * concurrent `conversation()` / `user()` callers can attach\n * channels — Phoenix buffers joins until the socket opens).\n * 2. Pre-fetch the JWT through `TokenCache`, which fills its\n * internal cache.\n * 3. Call `socket.connect()` so phoenix.js's first handshake reads\n * a primed `peekToken()`.\n *\n * On reconnect, Phoenix calls `params()` again; the cache is still\n * warm (default JWT exp ~1h, refresh window 30s) so `peekToken()`\n * returns the live token. When the token genuinely expires, our\n * REST 401 path invalidates the cache; the next reconnect's\n * `peekToken()` is `null` and the handshake intentionally fails so\n * the cache can re-fill on the next iteration.\n */\n connect(): void {\n if (this.socket) return;\n\n this.setStatus('connecting');\n\n const socket = new Socket(`${this.wsUrl}${this.socketPath}`, {\n params: () => ({ token: this.tokenCache.peekToken() ?? '' }),\n // Phoenix's default reconnect strategy: 10ms, 50ms, 100ms, 150ms,\n // 200ms, 250ms, 500ms, 1s, 2s, 5s — perfectly reasonable for chat.\n });\n\n socket.onOpen(() => this.setStatus('connected'));\n socket.onClose(() => {\n // `onClose` fires for both intentional disconnect and network drop.\n // Phoenix triggers reconnect on its own for the latter; we just\n // surface the transitional state to UIs.\n this.setStatus(this.status === 'closed' ? 'closed' : 'reconnecting');\n });\n socket.onError((err) => {\n // Errors don't tear down the socket — Phoenix retries internally.\n // Surface as `reconnecting` so the UI can show a banner.\n this.setStatus('reconnecting');\n this.config.onSocketError?.(new PoolseError(`socket error: ${String(err)}`));\n });\n\n this.socket = socket;\n\n // Pre-fetch the JWT, then open the socket. Channel joins called\n // between now and socket.connect() are buffered by Phoenix and\n // flushed on open, so callers don't need to await anything.\n void this.tokenCache\n .getToken()\n .catch((err) => {\n this.config.onSocketError?.(\n new PoolseError(`token fetch failed before socket open: ${String(err)}`),\n );\n })\n .finally(() => {\n socket.connect();\n });\n }\n\n /** Close the socket and tear down every joined channel. */\n disconnect(): void {\n this.setStatus('closed');\n this.conversations.forEach((c) => c._destroy());\n this.conversations.clear();\n this.userChannel?._destroy();\n this.userChannel = null;\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n }\n }\n\n /**\n * Subscribe to a conversation. Returns a typed handle with\n * `onMessage`, `onTyping`, etc. Reusing the same `id` returns the\n * same handle — re-subscribing doesn't open a second channel.\n */\n conversation(conversationId: string): ConversationChannel {\n const existing = this.conversations.get(conversationId);\n if (existing) return existing;\n\n this.connect();\n\n if (!this.socket) {\n throw new PoolseError('socket not initialised — call connect() first');\n }\n\n const channel = this.socket.channel(`conversation:${conversationId}`, {});\n const handle = new ConversationChannel(conversationId, channel);\n this.conversations.set(conversationId, handle);\n handle._join();\n return handle;\n }\n\n /**\n * Subscribe to the current user's `user:<id>` channel. Only the user\n * matching the JWT can join — poolse's UserChannel enforces this.\n */\n user(userId: string): UserChannel {\n if (this.userChannel) return this.userChannel;\n\n this.connect();\n\n if (!this.socket) {\n throw new PoolseError('socket not initialised — call connect() first');\n }\n\n const channel = this.socket.channel(`user:${userId}`, {});\n const handle = new UserChannel(userId, channel);\n this.userChannel = handle;\n handle._join();\n return handle;\n }\n\n /** Drop a conversation handle and leave the channel. */\n leave(conversationId: string): void {\n const handle = this.conversations.get(conversationId);\n if (!handle) return;\n handle._destroy();\n this.conversations.delete(conversationId);\n }\n\n private setStatus(status: RealtimeStatus): void {\n if (this.status === status) return;\n this.status = status;\n this.statusListeners.forEach((l) => l(status));\n }\n}\n\n// ── ConversationChannel ────────────────────────────────────────────────\n\nexport class ConversationChannel {\n public readonly conversationId: string;\n private readonly channel: Channel;\n\n // Map from event-name → set of listeners. We bind one Phoenix `.on(...)`\n // per event name (no matter how many JS listeners) and fan out\n // ourselves — much cheaper than re-binding on every subscription.\n private readonly listeners = new Map<string, Set<(payload: unknown) => void>>();\n\n // Phoenix.Presence pushes `presence_state` exactly ONCE right after\n // join, then `presence_diff` for every change. Late subscribers\n // (MemberList mounted after ConversationView has already joined the\n // channel) would otherwise never see the initial snapshot and stay\n // empty until somebody else joins or leaves. We cache the running\n // state here and replay it on subscribe.\n private presenceState: PresenceSnapshot = {};\n private presenceStateSeen = false;\n\n constructor(conversationId: string, channel: Channel) {\n this.conversationId = conversationId;\n this.channel = channel;\n\n // Bind presence handlers eagerly (not via the lazy `subscribe`\n // path) so the cache fills regardless of subscriber timing.\n channel.on('presence_state', (payload: unknown) => {\n this.presenceState = (payload ?? {}) as PresenceSnapshot;\n this.presenceStateSeen = true;\n const listeners = this.listeners.get('presence_state');\n if (listeners) listeners.forEach((l) => l(this.presenceState));\n });\n channel.on('presence_diff', (payload: unknown) => {\n const diff = (payload ?? {}) as { joins?: PresenceSnapshot; leaves?: PresenceSnapshot };\n const next: PresenceSnapshot = { ...this.presenceState };\n if (diff.joins) for (const [k, v] of Object.entries(diff.joins)) next[k] = v;\n if (diff.leaves) for (const k of Object.keys(diff.leaves)) delete next[k];\n this.presenceState = next;\n const listeners = this.listeners.get('presence_diff');\n if (listeners) listeners.forEach((l) => l(payload));\n });\n }\n\n /** New message pushed to the conversation. */\n onMessage(fn: (msg: MessageNewEvent) => void): Unsubscribe {\n return this.subscribe('message:new', fn as (p: unknown) => void);\n }\n\n /** Existing message edited by its sender. */\n onMessageUpdated(fn: (msg: MessageUpdatedEvent) => void): Unsubscribe {\n return this.subscribe('message:updated', fn as (p: unknown) => void);\n }\n\n /** Tombstone for a soft-deleted message. */\n onMessageDeleted(fn: (evt: MessageDeletedEvent) => void): Unsubscribe {\n return this.subscribe('message:deleted', fn as (p: unknown) => void);\n }\n\n onTypingStart(fn: (evt: TypingEvent) => void): Unsubscribe {\n return this.subscribe('typing:start', fn as (p: unknown) => void);\n }\n\n onTypingStop(fn: (evt: TypingEvent) => void): Unsubscribe {\n return this.subscribe('typing:stop', fn as (p: unknown) => void);\n }\n\n onReactionAdded(fn: (evt: ReactionEvent) => void): Unsubscribe {\n return this.subscribe('reaction:added', fn as (p: unknown) => void);\n }\n\n onReactionRemoved(fn: (evt: ReactionEvent) => void): Unsubscribe {\n return this.subscribe('reaction:removed', fn as (p: unknown) => void);\n }\n\n /**\n * A conversation member advanced their read cursor. Used to flip the\n * sender's read-receipt glyph from \"sent\" to \"read\" in real time.\n */\n onMemberRead(fn: (evt: MemberReadEvent) => void): Unsubscribe {\n return this.subscribe('member:read', fn as (p: unknown) => void);\n }\n\n onPresenceState(fn: (state: PresenceSnapshot) => void): Unsubscribe {\n let set = this.listeners.get('presence_state');\n if (!set) {\n set = new Set();\n this.listeners.set('presence_state', set);\n }\n set.add(fn as (p: unknown) => void);\n // Replay the cached presence_state to late subscribers — Phoenix\n // pushes it once on join and never resends, so MemberList mounted\n // after ConversationView would otherwise stay empty.\n if (this.presenceStateSeen) fn(this.presenceState);\n return () => {\n set.delete(fn as (p: unknown) => void);\n };\n }\n\n onPresenceDiff(fn: (diff: PresenceSnapshot) => void): Unsubscribe {\n return this.subscribe('presence_diff', fn as (p: unknown) => void);\n }\n\n /** Current presence snapshot for sync access — usually used in tests. */\n getPresenceState(): PresenceSnapshot {\n return this.presenceState;\n }\n\n /** Send a typing ping to the server. Debounced server-side. */\n sendTyping(): void {\n this.channel.push('typing', {});\n }\n\n /** @internal — called by `PoolseRealtime.conversation/1`. */\n _join(): void {\n this.channel.join();\n }\n\n /** @internal — called when the consumer leaves this conversation. */\n _destroy(): void {\n this.listeners.clear();\n this.channel.leave();\n }\n\n private subscribe(event: string, fn: (payload: unknown) => void): Unsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n this.channel.on(event, (payload: unknown) => {\n const listeners = this.listeners.get(event);\n if (listeners) listeners.forEach((l) => l(payload));\n });\n }\n set.add(fn);\n return () => {\n set.delete(fn);\n };\n }\n}\n\n// ── UserChannel ────────────────────────────────────────────────────────\n\nexport class UserChannel {\n public readonly userId: string;\n private readonly channel: Channel;\n private readonly mentionListeners = new Set<(evt: MentionEvent) => void>();\n private readonly conversationCreatedListeners = new Set<\n (evt: ConversationCreatedEvent) => void\n >();\n private mentionBound = false;\n private conversationCreatedBound = false;\n\n constructor(userId: string, channel: Channel) {\n this.userId = userId;\n this.channel = channel;\n }\n\n onMention(fn: (evt: MentionEvent) => void): Unsubscribe {\n if (!this.mentionBound) {\n this.mentionBound = true;\n this.channel.on('mention:new', (payload: unknown) => {\n this.mentionListeners.forEach((l) => l(payload as MentionEvent));\n });\n }\n this.mentionListeners.add(fn);\n return () => {\n this.mentionListeners.delete(fn);\n };\n }\n\n /**\n * Subscribe to \"you've been added to a conversation\" notifications.\n * Fires once per new membership — either because you created the\n * conversation, or because someone added you to an existing one.\n *\n * Payload is the full {@link Conversation} row so consumers can\n * prepend it to a local list without a refetch.\n */\n onConversationCreated(fn: (conv: ConversationCreatedEvent) => void): Unsubscribe {\n if (!this.conversationCreatedBound) {\n this.conversationCreatedBound = true;\n this.channel.on('conversation:created', (payload: unknown) => {\n this.conversationCreatedListeners.forEach((l) => l(payload as ConversationCreatedEvent));\n });\n }\n this.conversationCreatedListeners.add(fn);\n return () => {\n this.conversationCreatedListeners.delete(fn);\n };\n }\n\n /** @internal */\n _join(): void {\n this.channel.join();\n }\n\n /** @internal */\n _destroy(): void {\n this.mentionListeners.clear();\n this.conversationCreatedListeners.clear();\n this.channel.leave();\n }\n}\n\n// ── helpers ────────────────────────────────────────────────────────────\n\nfunction deriveWsUrl(apiUrl: string): string {\n // http(s):// → ws(s)://. Same host + port. The realtime endpoint\n // typically shares its origin with the REST API (single VPS) but\n // can be overridden via `RealtimeOptions.wsUrl`.\n return apiUrl.replace(/^http/, 'ws');\n}\n","// Attachment uploads use a presigned-URL flow:\n//\n// 1. POST /v1/attachments/upload-url → server returns a presigned\n// PUT URL + the headers the storage backend will require, plus a\n// `:pending` attachment row that the user can reference when\n// sending a message.\n// 2. The client PUTs the bytes directly to the storage backend\n// (Cloudflare R2 / S3). The bytes never touch poolse's API\n// server — this is fast AND keeps large blobs off the app tier.\n// 3. The PUT response Status 2xx flips the attachment row from\n// `:pending` to `:ready` (via a webhook the server subscribes\n// to, OR opportunistically on first download — implementation\n// detail).\n// 4. The client now sends a message referencing the attachment id.\n//\n// This module exposes that flow at two levels:\n// * `requestUpload(attrs)` — low-level, returns the presigned URL.\n// Use when you want full control of the PUT (custom progress,\n// resumable uploads, chunked transfers, RN's FileSystem API).\n// * `upload(input)` — high-level convenience that does step 1 + the\n// PUT in one call, returning the (now-ready) attachment row.\n// Works with browser File/Blob and any BodyInit-compatible value.\n\nimport type { RestClient } from '../rest-client.js';\nimport type {\n Attachment,\n AttachmentDownloadResponse,\n AttachmentUploadRequest,\n AttachmentUploadResponse,\n Uuid,\n} from '../types.js';\n\n/** Input accepted by {@link AttachmentsResource.upload}. */\nexport interface AttachmentUploadInput {\n /**\n * The bytes to upload. Browser: pass a `File` or `Blob`. Node /\n * Workers / Deno: a `Uint8Array`, `ArrayBuffer`, or any\n * `BodyInit`-compatible value the runtime's `fetch` accepts as a\n * PUT body.\n */\n body: BodyInit;\n /**\n * MIME type. MUST match what you pass as `content_type` on the\n * upload-URL request (the storage backend signs it into the URL —\n * a mismatch makes the PUT fail with 403).\n */\n contentType: string;\n /** Total bytes — must match the bytes you actually PUT. */\n byteSize: number;\n /** Surfaced in download UX so saved files keep a sensible name. */\n filename?: string;\n}\n\n/** Options accepted by every attachment method. */\nexport interface AttachmentOptions {\n signal?: AbortSignal;\n /**\n * Progress callback for `upload()`. Called periodically during the\n * PUT phase (NOT during the presigned-URL request — that's a small\n * JSON round-trip). When set, the SDK switches to XHR for the PUT\n * since the standard `fetch` doesn't expose upload progress events.\n *\n * Customers using a custom `config.fetch` (e.g. node-fetch polyfill)\n * lose progress reporting and the callback never fires — XHR is\n * a browser-only API.\n */\n onProgress?: (event: AttachmentProgressEvent) => void;\n}\n\nexport interface AttachmentProgressEvent {\n /** Bytes uploaded so far. */\n loaded: number;\n /** Total bytes — equals `input.byteSize` (passed back for convenience). */\n total: number;\n}\n\n/** Top-level `/v1/attachments` collection. */\nexport class AttachmentsResource {\n /**\n * The PUT to the presigned URL bypasses the SDK's authenticated\n * REST client (presigned URLs encode their own auth and MUST NOT\n * receive an `Authorization` header). It still respects\n * `config.fetch` if the customer provided one — required for tests\n * with a mock fetch, and for runtimes where `globalThis.fetch` is\n * not the right transport.\n */\n constructor(\n private readonly client: RestClient,\n private readonly fetchFn: typeof globalThis.fetch,\n ) {}\n\n /**\n * Step 1 of an upload — request a presigned PUT URL. Use this when\n * you want to drive the PUT yourself (e.g. resumable uploads,\n * React Native FileSystem). For the common case prefer\n * {@link upload}, which does both steps for you.\n */\n requestUpload(\n attrs: AttachmentUploadRequest,\n opts: AttachmentOptions = {},\n ): Promise<AttachmentUploadResponse> {\n return this.client.request<AttachmentUploadResponse>({\n method: 'POST',\n path: '/v1/attachments/upload-url',\n body: attrs,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n\n /**\n * One-call upload: request a presigned URL, PUT the bytes to it,\n * return the attachment row. After this resolves the attachment is\n * ready to be referenced from a message send.\n *\n * ```ts\n * // Browser <input type=\"file\">:\n * const file = inputEl.files![0]!;\n * const att = await chat.attachments.upload({\n * body: file,\n * contentType: file.type,\n * byteSize: file.size,\n * filename: file.name,\n * });\n * await chat.conversations.one(convId).messages.send({\n * body: 'Look at this!',\n * custom_data: { attachment_id: att.id },\n * });\n * ```\n *\n * Note: the PUT uses the runtime's bare `fetch` (NOT the SDK's\n * authenticated REST client) — presigned URLs already encode their\n * own auth and MUST NOT receive an `Authorization` header.\n */\n async upload(input: AttachmentUploadInput, opts: AttachmentOptions = {}): Promise<Attachment> {\n const req: AttachmentUploadRequest = {\n content_type: input.contentType,\n byte_size: input.byteSize,\n ...(input.filename !== undefined ? { original_filename: input.filename } : {}),\n };\n\n const { attachment, upload } = await this.requestUpload(req, opts);\n\n // Progress reporting requires XHR — `fetch` doesn't expose upload\n // events. Drop to XHR only when the caller actually wants progress;\n // otherwise stick with `fetch` (handles streams + Node polyfills\n // that XHR doesn't).\n if (opts.onProgress && typeof XMLHttpRequest !== 'undefined') {\n await xhrPut(upload.url, upload.method.toUpperCase(), upload.headers, input.body, {\n byteSize: input.byteSize,\n onProgress: opts.onProgress,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n return attachment;\n }\n\n const putInit: RequestInit = {\n method: upload.method.toUpperCase(),\n headers: upload.headers,\n body: input.body,\n ...(opts.signal ? { signal: opts.signal } : {}),\n };\n\n const res = await this.fetchFn(upload.url, putInit);\n if (!res.ok) {\n throw new Error(\n `Poolse: presigned upload PUT failed (${res.status}) for attachment ${attachment.id}`,\n );\n }\n return attachment;\n }\n\n /** Returns a handle for further operations on a single attachment. */\n one(id: Uuid): AttachmentHandle {\n return new AttachmentHandle(this.client, id);\n }\n}\n\n/** Wraps an attachment id for download-url + delete. */\nexport class AttachmentHandle {\n constructor(\n private readonly client: RestClient,\n public readonly id: Uuid,\n ) {}\n\n /**\n * Request a presigned GET URL (~1h TTL). Conversation-member-gated\n * server-side. Useful when rendering files in chat: cache the URL\n * client-side until close to expiry, then re-fetch.\n */\n downloadUrl(opts: AttachmentOptions = {}): Promise<AttachmentDownloadResponse> {\n return this.client.request<AttachmentDownloadResponse>({\n method: 'GET',\n path: `/v1/attachments/${this.id}/download-url`,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n\n /**\n * Delete the attachment row + best-effort bucket object delete.\n * Authz: uploader (while still `:pending`) or message-sender / conv\n * owner-admin (once linked).\n */\n delete(opts: AttachmentOptions = {}): Promise<void> {\n return this.client.request<void>({\n method: 'DELETE',\n path: `/v1/attachments/${this.id}`,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n}\n\n/**\n * XHR-based PUT with upload progress events. Used by `upload()` when\n * the caller passes an `onProgress` callback — `fetch` doesn't\n * expose upload progress.\n *\n * Browser-only: tests + Node polyfills don't define XMLHttpRequest,\n * so the caller path that selects XHR vs fetch checks\n * `typeof XMLHttpRequest !== 'undefined'` upstream.\n */\nfunction xhrPut(\n url: string,\n method: string,\n headers: Record<string, string>,\n body: BodyInit,\n opts: {\n byteSize: number;\n onProgress: (e: AttachmentProgressEvent) => void;\n signal?: AbortSignal;\n },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open(method, url);\n for (const [k, v] of Object.entries(headers)) {\n try {\n xhr.setRequestHeader(k, v);\n } catch {\n // Some browsers refuse to set forbidden headers (Content-Length,\n // etc.). The presigned URL still works without them.\n }\n }\n xhr.upload.onprogress = (e) => {\n // `lengthComputable` is true on R2 / S3; fall back to byteSize\n // for older browsers that don't expose `total`.\n const total = e.lengthComputable ? e.total : opts.byteSize;\n opts.onProgress({ loaded: e.loaded, total });\n };\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) resolve();\n else\n reject(new Error(`Poolse: presigned upload PUT failed (${xhr.status} ${xhr.statusText})`));\n };\n xhr.onerror = () => reject(new Error('Poolse: presigned upload PUT failed (network error)'));\n xhr.onabort = () => {\n // Surface as DOMException('AbortError') so callers can detect.\n reject(new DOMException('Upload aborted', 'AbortError'));\n };\n if (opts.signal) {\n if (opts.signal.aborted) {\n xhr.abort();\n return;\n }\n opts.signal.addEventListener('abort', () => xhr.abort(), { once: true });\n }\n // body must be XHR-compatible: Blob, File, FormData, string,\n // ArrayBufferView. Customers using a streaming body via fetch\n // wouldn't pass `onProgress` (we'd be on the fetch path).\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n","import type { RestClient } from '../rest-client.js';\nimport type {\n Message,\n MessageCreateRequest,\n MessageList,\n MessageUpdateRequest,\n ReactionRequest,\n Uuid,\n} from '../types.js';\n\n/** Per-conversation message collection: send, list, mark-read. */\nexport class ConversationMessages {\n constructor(\n private readonly client: RestClient,\n private readonly conversationId: Uuid,\n ) {}\n\n list(opts: { limit?: number; before?: number } = {}, signal?: AbortSignal): Promise<MessageList> {\n return this.client.request<MessageList>({\n method: 'GET',\n path: `/v1/conversations/${this.conversationId}/messages`,\n query: {\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n ...(opts.before !== undefined ? { before: opts.before } : {}),\n },\n ...(signal ? { signal } : {}),\n });\n }\n\n /**\n * Send a message to this conversation.\n *\n * If `attrs.id` is omitted the SDK generates a v4 UUID and uses it\n * as both the wire-level idempotency key AND the literal message.id\n * the server stores. Two side-effects that make a real-time UI\n * trivial:\n *\n * * Resending the same `id` (e.g. a network-retry) returns the\n * ORIGINAL message instead of inserting a duplicate.\n * * The realtime `message:new` broadcast carries this same id,\n * so an optimistic UI can pre-render the row under the final id\n * and dedup by id alone — no client/server id swap needed.\n *\n * Pass an explicit `attrs.id` only when you generated it yourself\n * upstream (e.g. you already render an optimistic row in your hook\n * and want the server to confirm under the same key).\n */\n send(attrs: MessageCreateRequest, signal?: AbortSignal): Promise<Message> {\n const body: MessageCreateRequest =\n attrs.id !== undefined ? attrs : { ...attrs, id: generateClientMessageId() };\n return this.client.request<Message>({\n method: 'POST',\n path: `/v1/conversations/${this.conversationId}/messages`,\n body,\n ...(signal ? { signal } : {}),\n });\n }\n\n markRead(messageId: Uuid, signal?: AbortSignal): Promise<void> {\n return this.client.request<void>({\n method: 'POST',\n path: `/v1/conversations/${this.conversationId}/read`,\n body: { message_id: messageId },\n ...(signal ? { signal } : {}),\n });\n }\n}\n\n/** Per-message operations: edit, delete, react, list replies. */\nexport class MessageHandle {\n constructor(\n private readonly client: RestClient,\n public readonly id: Uuid,\n ) {}\n\n update(attrs: MessageUpdateRequest, signal?: AbortSignal): Promise<Message> {\n return this.client.request<Message>({\n method: 'PATCH',\n path: `/v1/messages/${this.id}`,\n body: attrs,\n ...(signal ? { signal } : {}),\n });\n }\n\n delete(signal?: AbortSignal): Promise<void> {\n return this.client.request<void>({\n method: 'DELETE',\n path: `/v1/messages/${this.id}`,\n ...(signal ? { signal } : {}),\n });\n }\n\n replies(\n opts: { limit?: number; after?: number } = {},\n signal?: AbortSignal,\n ): Promise<MessageList> {\n return this.client.request<MessageList>({\n method: 'GET',\n path: `/v1/messages/${this.id}/replies`,\n query: {\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n ...(opts.after !== undefined ? { after: opts.after } : {}),\n },\n ...(signal ? { signal } : {}),\n });\n }\n\n addReaction(emoji: string, signal?: AbortSignal): Promise<Message> {\n const body: ReactionRequest = { emoji };\n return this.client.request<Message>({\n method: 'POST',\n path: `/v1/messages/${this.id}/reactions`,\n body,\n ...(signal ? { signal } : {}),\n });\n }\n\n removeReaction(emoji: string, signal?: AbortSignal): Promise<Message> {\n return this.client.request<Message>({\n method: 'DELETE',\n path: `/v1/messages/${this.id}/reactions/${encodeURIComponent(emoji)}`,\n ...(signal ? { signal } : {}),\n });\n }\n}\n\n/** Top-level `/v1/messages` namespace — accessed via `chat.messages(id)`. */\nexport class MessagesResource {\n constructor(private readonly client: RestClient) {}\n\n one(id: Uuid): MessageHandle {\n return new MessageHandle(this.client, id);\n }\n}\n\n/**\n * Client-side message id generator. Uses `globalThis.crypto.randomUUID()`\n * when available (browsers in secure contexts, Node 19+, RN 0.74+).\n * In runtimes without it (older RN, sandboxed workers) the caller\n * should generate ids themselves and pass via `attrs.id` — failing\n * loud here is better than silently shipping non-unique ids that\n * would cause server-side dedup collisions across users.\n */\nfunction generateClientMessageId(): Uuid {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c && typeof c.randomUUID === 'function') {\n return c.randomUUID();\n }\n throw new Error(\n 'Poolse: globalThis.crypto.randomUUID() unavailable — pass `id` ' +\n 'explicitly in MessageCreateRequest (your env lacks a built-in UUID generator).',\n );\n}\n","import type { RestClient } from '../rest-client.js';\nimport { ConversationMessages } from './messages.js';\nimport type {\n Conversation,\n ConversationCreateRequest,\n ConversationList,\n ConversationUpdateRequest,\n MemberRole,\n Membership,\n MembershipList,\n Uuid,\n} from '../types.js';\n\n/** Optional knobs accepted by every member-add call. */\nexport interface AddMemberOptions {\n /** Membership role — defaults to `\"member\"` server-side. */\n role?: MemberRole;\n /** AbortSignal for caller-driven cancellation. */\n signal?: AbortSignal;\n}\n\n/** Wraps a single conversation by id — used as the entry point for sub-resources. */\nexport class ConversationHandle {\n /**\n * Message ops scoped to this conversation: `list`, `send`, `markRead`.\n * Lazy: constructed on first access so an idle handle stays cheap.\n */\n public readonly messages: ConversationMessages;\n\n constructor(\n private readonly client: RestClient,\n public readonly id: Uuid,\n ) {\n this.messages = new ConversationMessages(this.client, this.id);\n }\n\n show(signal?: AbortSignal): Promise<Conversation> {\n return this.client.request<Conversation>({\n method: 'GET',\n path: `/v1/conversations/${this.id}`,\n ...(signal ? { signal } : {}),\n });\n }\n\n update(attrs: ConversationUpdateRequest, signal?: AbortSignal): Promise<Conversation> {\n return this.client.request<Conversation>({\n method: 'PATCH',\n path: `/v1/conversations/${this.id}`,\n body: attrs,\n ...(signal ? { signal } : {}),\n });\n }\n\n // ── members ────────────────────────────────────────────────────────────\n\n listMembers(signal?: AbortSignal): Promise<MembershipList> {\n return this.client.request<MembershipList>({\n method: 'GET',\n path: `/v1/conversations/${this.id}/members`,\n ...(signal ? { signal } : {}),\n });\n }\n\n /**\n * Add multiple users to this conversation in one round-trip.\n *\n * `externalIds` are the stable customer-side identifiers you passed\n * to `POST /v1/users` when creating each user — the server resolves\n * them to internal user_ids and creates one membership row per id.\n *\n * Requires `:manage_members` on this conversation (owner or admin).\n *\n * ```ts\n * await chat.conversations.one(convId).addMembers(['alice', 'bob']);\n * ```\n */\n addMembers(externalIds: string[], opts: AddMemberOptions = {}): Promise<MembershipList> {\n return this.client.request<MembershipList>({\n method: 'POST',\n path: `/v1/conversations/${this.id}/members`,\n body: {\n external_ids: externalIds,\n ...(opts.role !== undefined ? { role: opts.role } : {}),\n },\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n\n /**\n * Add a single user. Convenience wrapper around {@link addMembers}\n * that unwraps the returned list to the single membership row.\n *\n * ```ts\n * const m = await chat.conversations.one(convId).addMember('alice');\n * ```\n */\n async addMember(externalId: string, opts: AddMemberOptions = {}): Promise<Membership> {\n const list = await this.addMembers([externalId], opts);\n const row = list.data[0];\n if (!row) {\n // Server should always return one membership per external_id;\n // empty data here means a contract violation, not a missing user\n // (the latter surfaces as a 422 user_not_found error).\n throw new Error('Poolse: addMember succeeded but server returned no membership row.');\n }\n return row;\n }\n\n removeMember(userId: Uuid, signal?: AbortSignal): Promise<void> {\n return this.client.request<void>({\n method: 'DELETE',\n path: `/v1/conversations/${this.id}/members/${userId}`,\n ...(signal ? { signal } : {}),\n });\n }\n}\n\n/** Top-level `/v1/conversations` collection. */\nexport class ConversationsResource {\n constructor(private readonly client: RestClient) {}\n\n list(signal?: AbortSignal): Promise<ConversationList> {\n return this.client.request<ConversationList>({\n method: 'GET',\n path: '/v1/conversations',\n ...(signal ? { signal } : {}),\n });\n }\n\n create(attrs: ConversationCreateRequest, signal?: AbortSignal): Promise<Conversation> {\n return this.client.request<Conversation>({\n method: 'POST',\n path: '/v1/conversations',\n body: attrs,\n ...(signal ? { signal } : {}),\n });\n }\n\n /** Returns a handle for further operations on a single conversation. */\n one(id: Uuid): ConversationHandle {\n return new ConversationHandle(this.client, id);\n }\n}\n","import type { RestClient } from '../rest-client.js';\nimport type { Me } from '../types.js';\n\n/** `/v1/me` — the End-User identity behind the presented JWT. */\nexport class MeResource {\n constructor(private readonly client: RestClient) {}\n\n /** GET /v1/me */\n show(signal?: AbortSignal): Promise<Me> {\n return this.client.request<Me>({\n method: 'GET',\n path: '/v1/me',\n ...(signal ? { signal } : {}),\n });\n }\n}\n","// Customer-supplied user metadata, cached — keyed by the tenant's\n// `external_id` (the same string the customer passes when minting\n// JWTs or referencing users in member lists).\n//\n// poolse has no concept of a \"user profile\" — names and avatars\n// live in the customer's app, not ours. `UsersResource` wraps the\n// `userResolver` the customer passed into `PoolseConfig` with:\n//\n// * an in-memory cache keyed by external_id\n// * concurrent-request dedup (10 bubbles asking for the same user\n// on the same tick fire ONE resolver call)\n// * subscription so React (or any other UI) can re-render when a\n// pending lookup resolves\n//\n// Negative results (resolver returned null, threw, or the customer\n// didn't configure a resolver at all) are cached too so we don't\n// retry on every mount. Customers who want to invalidate the cache\n// can call `chat.users.invalidate(externalId)` after their backend's\n// user data changes (or `invalidateAll()` after a sign-out / tenant\n// swap).\n\nimport type { ResolvedConfig } from '../config.js';\nimport type { PoolseUserProfile } from '../types.js';\n\ntype Listener = () => void;\n\nexport class UsersResource {\n private readonly cache = new Map<string, PoolseUserProfile | null>();\n private readonly pending = new Map<string, Promise<PoolseUserProfile | null>>();\n private readonly listeners = new Map<string, Set<Listener>>();\n\n constructor(private readonly config: ResolvedConfig) {}\n\n /**\n * Get the cached value if present. Returns `undefined` to mean\n * \"not in cache yet\" (different from `null`, which means \"resolver\n * ran and the user wasn't found\").\n */\n peek(externalId: string): PoolseUserProfile | null | undefined {\n return this.cache.get(externalId);\n }\n\n /**\n * Resolve a user, hitting the customer's `userResolver` on cache\n * miss. Concurrent calls for the same external_id share one Promise.\n */\n async get(externalId: string): Promise<PoolseUserProfile | null> {\n if (this.cache.has(externalId)) {\n return this.cache.get(externalId) ?? null;\n }\n const existingPending = this.pending.get(externalId);\n if (existingPending) return existingPending;\n\n const resolver = this.config.userResolver;\n if (!resolver) {\n this.cache.set(externalId, null);\n this.notify(externalId);\n return null;\n }\n\n const promise = Promise.resolve()\n .then(() => resolver(externalId))\n .then(\n (profile) => {\n this.cache.set(externalId, profile ?? null);\n this.pending.delete(externalId);\n this.notify(externalId);\n return profile ?? null;\n },\n (err: unknown) => {\n // Resolver errors are treated as \"user not found\" — log\n // once and cache the null so we don't hammer the failing\n // endpoint on every re-render. Customers can call\n // `invalidate(externalId)` to retry.\n console.error('[poolse] userResolver failed for', externalId, err);\n this.cache.set(externalId, null);\n this.pending.delete(externalId);\n this.notify(externalId);\n return null;\n },\n );\n this.pending.set(externalId, promise);\n return promise;\n }\n\n /**\n * Subscribe to changes for a single external_id. The listener fires\n * when the resolver lands (or when the entry is invalidated).\n * Returns an unsubscribe.\n *\n * `useUser` in @poolse/react uses this with `useSyncExternalStore`.\n */\n subscribe(externalId: string, listener: Listener): () => void {\n let set = this.listeners.get(externalId);\n if (!set) {\n set = new Set();\n this.listeners.set(externalId, set);\n }\n set.add(listener);\n return () => {\n set?.delete(listener);\n };\n }\n\n /** Drop a single cached entry — next `get` re-fetches via the resolver. */\n invalidate(externalId: string): void {\n this.cache.delete(externalId);\n this.pending.delete(externalId);\n this.notify(externalId);\n }\n\n /**\n * Drop the entire cache. Use after a sign-out, tenant swap, or any\n * other event that invalidates every cached profile (e.g., the\n * customer just renamed every user in bulk).\n */\n invalidateAll(): void {\n this.cache.clear();\n this.pending.clear();\n for (const externalId of this.listeners.keys()) {\n this.notify(externalId);\n }\n }\n\n private notify(externalId: string): void {\n const set = this.listeners.get(externalId);\n if (!set) return;\n for (const l of set) l();\n }\n}\n","// Low-level fetch wrapper.\n//\n// Responsibilities:\n// * Apply the Bearer JWT from `config.getToken()`.\n// * Auto-generate an `Idempotency-Key` for non-GET requests so poolse\n// can dedupe retries safely.\n// * Retry on transient failures: network errors, 5xx, 429.\n// - Backoff = max(Retry-After header, exponential with jitter).\n// - 401/4xx-other are NOT retried (they won't change on repeat).\n// * Translate non-2xx into typed `ApiError` subclasses.\n\nimport type { ResolvedConfig } from './config.js';\nimport { ApiError, AuthError, NetworkError, RateLimitedError } from './errors.js';\nimport type { TokenCache } from './token-cache.js';\nimport type { ErrorEnvelope } from './types.js';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n\nexport interface RequestOptions {\n method: HttpMethod;\n path: string;\n /** JSON-serialisable body for non-GETs. Omit for GET/DELETE. */\n body?: unknown;\n /** Query string params; values are stringified, nullish entries dropped. */\n query?: Record<string, string | number | boolean | null | undefined>;\n /**\n * Idempotency-Key override. Defaults to a fresh UUID for non-GETs.\n * Pass `null` to deliberately omit the header (e.g. when the caller's\n * own retry logic supplies a deterministic one).\n */\n idempotencyKey?: string | null;\n /**\n * Per-request override for total retry budget. Defaults to\n * `config.maxRetries`.\n */\n maxRetries?: number;\n /** AbortSignal for caller-driven cancellation. */\n signal?: AbortSignal;\n}\n\nconst NON_BODY_METHODS: ReadonlySet<HttpMethod> = new Set(['GET', 'DELETE']);\nconst IDEMPOTENT_METHODS: ReadonlySet<HttpMethod> = new Set(['GET']);\n\nexport class RestClient {\n private readonly config: ResolvedConfig;\n private readonly tokenCache: TokenCache;\n\n constructor(config: ResolvedConfig, tokenCache: TokenCache) {\n this.config = config;\n this.tokenCache = tokenCache;\n }\n\n async request<T>(opts: RequestOptions): Promise<T> {\n const url = this.buildUrl(opts.path, opts.query);\n const maxRetries = opts.maxRetries ?? this.config.maxRetries;\n const idempotencyKey = this.resolveIdempotencyKey(opts);\n\n let attempt = 0;\n let triedAuthRefresh = false;\n\n // The retry loop runs up to `maxRetries + 1` total attempts. Each\n // failed attempt either returns (giving up) or waits per the backoff.\n for (;;) {\n const body = opts.body === undefined ? undefined : JSON.stringify(opts.body);\n const headers = await this.buildHeaders(opts.method, idempotencyKey, body !== undefined);\n\n let response: Response;\n try {\n const init: RequestInit = { method: opts.method, headers };\n if (body !== undefined) init.body = body;\n if (opts.signal) init.signal = opts.signal;\n response = await this.config.fetch(url, init);\n } catch (err) {\n // AbortError is caller intent (component unmount, conv switch,\n // StrictMode double-effect). Re-throw AS-IS so callers can\n // distinguish it from a real network failure. Wrapping it as\n // NetworkError previously caused hooks like useMembers to fall\n // into their \"failed to load\" branch whenever the aborted fetch\n // resolved after a newly-mounted fetcher already cleared state.\n if (err instanceof DOMException && err.name === 'AbortError') {\n throw err;\n }\n if (attempt < maxRetries && isRetryableNetworkError(err)) {\n await sleep(this.backoffDelay(attempt));\n attempt += 1;\n continue;\n }\n throw new NetworkError('Network request failed', err);\n }\n\n if (response.status >= 200 && response.status < 300) {\n return (await parseJsonOrNull(response)) as T;\n }\n\n // 401: a cached token can race a clock-skew expiry or a server\n // restart. Invalidate the token cache and retry ONCE — if the\n // refreshed token also gets 401, the credentials are genuinely\n // bad and we surface it. Doesn't count against the per-request\n // retry budget (auth refresh isn't a \"transient\" failure in the\n // same sense as 5xx/network).\n if (response.status === 401) {\n if (!triedAuthRefresh) {\n this.tokenCache.invalidate();\n triedAuthRefresh = true;\n continue;\n }\n throw new AuthError(await parseEnvelope(response));\n }\n\n // 429: retry after the larger of (Retry-After, exponential backoff).\n if (response.status === 429) {\n const envelope = await parseEnvelope(response);\n const retryAfterMs = retryAfterHeaderMs(response);\n if (attempt < maxRetries) {\n await sleep(Math.max(retryAfterMs ?? 0, this.backoffDelay(attempt)));\n attempt += 1;\n continue;\n }\n throw new RateLimitedError(envelope, retryAfterMs ?? 0);\n }\n\n // 5xx: retry if we have budget and the method is safe to retry.\n // Non-idempotent methods (POST/PATCH/PUT/DELETE) are STILL retried\n // here because the Idempotency-Key header makes duplicates safe.\n if (response.status >= 500 && attempt < maxRetries) {\n await sleep(this.backoffDelay(attempt));\n attempt += 1;\n continue;\n }\n\n throw new ApiError(response.status, await parseEnvelope(response));\n }\n }\n\n // ── helpers ────────────────────────────────────────────────────────────\n\n private buildUrl(path: string, query?: RequestOptions['query']): string {\n const base = `${this.config.apiUrl}${path.startsWith('/') ? path : `/${path}`}`;\n if (!query) return base;\n\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null) {\n params.append(k, String(v));\n }\n }\n const qs = params.toString();\n return qs ? `${base}?${qs}` : base;\n }\n\n private async buildHeaders(\n method: HttpMethod,\n idempotencyKey: string | null,\n hasBody: boolean,\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n\n if (hasBody) headers['Content-Type'] = 'application/json';\n\n const token = await this.config.getToken();\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n if (!IDEMPOTENT_METHODS.has(method) && idempotencyKey) {\n headers['Idempotency-Key'] = idempotencyKey;\n }\n\n return headers;\n }\n\n private resolveIdempotencyKey(opts: RequestOptions): string | null {\n if (opts.idempotencyKey === null) return null;\n if (opts.idempotencyKey) return opts.idempotencyKey;\n if (IDEMPOTENT_METHODS.has(opts.method)) return null;\n return this.config.generateIdempotencyKey();\n }\n\n private backoffDelay(attempt: number): number {\n const exp = this.config.baseBackoffMs * 2 ** attempt;\n const capped = Math.min(this.config.maxBackoffMs, exp);\n // Full jitter: pick uniformly in [0, capped]. Avoids retry-storm\n // synchronization when many clients fail at once.\n return Math.floor(Math.random() * capped);\n }\n}\n\nfunction _unusedNonBodyMethods(): unknown {\n return NON_BODY_METHODS;\n}\n\nasync function parseEnvelope(response: Response): Promise<ErrorEnvelope['error']> {\n try {\n const json = (await response.json()) as ErrorEnvelope;\n if (json?.error?.code) return json.error;\n } catch {\n // fall through to a synthetic envelope below\n }\n return {\n code: 'unknown_error',\n message: `HTTP ${response.status}`,\n doc_url: '',\n };\n}\n\nasync function parseJsonOrNull(response: Response): Promise<unknown> {\n if (response.status === 204) return null;\n const text = await response.text();\n if (!text) return null;\n return JSON.parse(text);\n}\n\nfunction retryAfterHeaderMs(response: Response): number | null {\n const raw = response.headers.get('retry-after');\n if (!raw) return null;\n const seconds = Number.parseInt(raw, 10);\n return Number.isFinite(seconds) ? seconds * 1000 : null;\n}\n\nfunction isRetryableNetworkError(err: unknown): boolean {\n // Abort is caller intent — never retry.\n if (err instanceof DOMException && err.name === 'AbortError') return false;\n // Everything else (TypeError from fetch failure, etc.) is fair game.\n return true;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// Caches the JWT returned by the consumer's `getToken` callback so the\n// SDK doesn't call back on every REST request and every WebSocket\n// connect. Without this, mounting a single conversation view fires\n// ~4-5 `getToken` calls per render — and every parent re-render that\n// (accidentally) hands the provider a new config object multiplies\n// that out, turning a passive UI into a token-fetch storm.\n//\n// The cache:\n// * Decodes the `exp` claim (no signature verification — that's the\n// server's job) and returns the cached token until `exp - 30s`.\n// * Coalesces concurrent calls: if a refresh is in flight, every\n// caller awaits the same promise — one network round-trip even\n// when 4 hooks mount simultaneously.\n// * Can be `invalidate()`-d from the outside (e.g. by the REST client\n// after a 401) so the next call always re-fetches.\n// * Treats opaque (non-JWT) tokens as cacheable for `FALLBACK_TTL_MS`\n// — long enough to absorb a mount burst, short enough that opaque\n// rotations still land within a few seconds.\n// * NEVER caches `null` (an unauthenticated request is a choice the\n// consumer makes per call, not a state to memoise).\n\nimport type { PoolseConfig } from './config.js';\n\ntype Fetcher = PoolseConfig['getToken'];\n\ninterface GetTokenOptions {\n /** Bypass the cache and force a fresh call to the consumer's `getToken`. */\n forceRefresh?: boolean;\n}\n\nconst REFRESH_BUFFER_MS = 30_000;\nconst FALLBACK_TTL_MS = 60_000;\n\nexport class TokenCache {\n private token: string | null = null;\n private expMs: number | null = null;\n private inFlight: Promise<string | null> | null = null;\n\n constructor(private readonly fetcher: Fetcher) {}\n\n /**\n * Synchronously return the cached token without triggering a fetch.\n * Returns `null` if the cache is empty OR if the cached token is\n * within the refresh window (treating near-expiry tokens as stale\n * keeps the realtime layer from handshaking with an about-to-expire\n * JWT when a refresh is already due).\n *\n * Exists for callers like Phoenix.js's `params` callback that the\n * library invokes synchronously and does NOT await — see\n * `phoenix/priv/static/phoenix.mjs::endPointURL()`.\n */\n peekToken(): string | null {\n if (this.token === null || this.expMs === null) return this.token;\n return Date.now() < this.expMs - REFRESH_BUFFER_MS ? this.token : null;\n }\n\n async getToken(opts: GetTokenOptions = {}): Promise<string | null> {\n if (opts.forceRefresh) this.invalidate();\n\n const now = Date.now();\n if (this.token && this.expMs !== null && now < this.expMs - REFRESH_BUFFER_MS) {\n return this.token;\n }\n\n if (this.inFlight) return this.inFlight;\n\n this.inFlight = this.fetchAndStore().finally(() => {\n this.inFlight = null;\n });\n return this.inFlight;\n }\n\n invalidate(): void {\n this.token = null;\n this.expMs = null;\n // Don't clear `inFlight` — let the existing fetch resolve normally;\n // its result just won't be cached (the freshness check above will\n // miss it). The next call after `invalidate()` will be served by\n // that same in-flight promise if it's still pending.\n }\n\n private async fetchAndStore(): Promise<string | null> {\n const token = await this.fetcher();\n if (!token) {\n this.token = null;\n this.expMs = null;\n return null;\n }\n\n const expSec = parseJwtExp(token);\n if (expSec !== null) {\n const expMs = expSec * 1000;\n // Already expired by the time it reached us — cache for a short\n // fallback so the burst doesn't hammer, but don't trust the exp.\n // The next REST 401 will invalidate and we'll re-fetch.\n this.expMs = expMs <= Date.now() ? Date.now() + FALLBACK_TTL_MS : expMs;\n } else {\n this.expMs = Date.now() + FALLBACK_TTL_MS;\n }\n this.token = token;\n return token;\n }\n}\n\n// JWT payload base64url-decode → JSON parse → pluck `exp`. Returns\n// null if the token isn't a JWT, the payload is unreadable, or `exp`\n// is missing/non-numeric. Never throws — bad tokens just go uncached.\nfunction parseJwtExp(token: string): number | null {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n\n try {\n const json = decodeBase64Url(parts[1] as string);\n const payload = JSON.parse(json) as { exp?: unknown };\n return typeof payload.exp === 'number' && Number.isFinite(payload.exp) ? payload.exp : null;\n } catch {\n return null;\n }\n}\n\nfunction decodeBase64Url(s: string): string {\n // JWT uses base64url (RFC 7515 §2): `-` and `_` instead of `+` and\n // `/`, no padding. Translate back to standard base64 and re-pad.\n const b64 = s.replace(/-/g, '+').replace(/_/g, '/');\n const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4);\n if (typeof atob === 'function') return atob(padded);\n // Node fallback (older runtimes without global atob). The SDK's\n // minimum target is Node 18 where atob is global, but keep this for\n // safety / SSR environments that polyfill differently.\n const g = globalThis as {\n Buffer?: { from(s: string, e: string): { toString(e: string): string } };\n };\n if (g.Buffer) return g.Buffer.from(padded, 'base64').toString('binary');\n throw new Error('No base64 decoder available');\n}\n","// Public entry-point for the SDK. One instance per End User session.\n// Re-create when the user signs out or rotates tenants.\n\nimport type { PoolseConfig, ResolvedConfig } from './config.js';\nimport { resolveConfig } from './config.js';\nimport { PoolseRealtime } from './realtime/realtime.js';\nimport { AttachmentsResource } from './resources/attachments.js';\nimport { ConversationsResource } from './resources/conversations.js';\nimport { MeResource } from './resources/me.js';\nimport { MessagesResource } from './resources/messages.js';\nimport { UsersResource } from './resources/users.js';\nimport { RestClient } from './rest-client.js';\nimport { TokenCache } from './token-cache.js';\n\nexport class Poolse {\n /** `/v1/me` — current End User. */\n public readonly me: MeResource;\n /** `/v1/conversations` collection + per-conversation handle factory. */\n public readonly conversations: ConversationsResource;\n /** `/v1/messages/:id/*` — accessed via `chat.messages.one(id)`. */\n public readonly messages: MessagesResource;\n /** `/v1/attachments/*` — presigned-URL uploads/downloads. */\n public readonly attachments: AttachmentsResource;\n\n /**\n * Customer-supplied user metadata, cached + dedup'd.\n * `chat.users.get(userId)` returns `{ displayName, avatarUrl }`\n * via the optional `config.userResolver`. UI components\n * (`MessageBubble`, `MemberList`, `TypingIndicator`) pick this up\n * automatically via the `useUser` hook in `@poolse/react`.\n *\n * If no resolver is configured, `get` always returns `null` and\n * UI falls back to the userId slice + initials avatar.\n */\n public readonly users: UsersResource;\n\n /**\n * Low-level REST client. Exposed for advanced use cases (custom endpoints,\n * raw retry/headers control). Most callers should use the resources above.\n */\n public readonly rest: RestClient;\n\n /**\n * WebSocket / Phoenix Channels client. Lazily connects on the first\n * `poolse.realtime.conversation(id)` / `poolse.realtime.user(id)`\n * call — passing `config.apiUrl` (with `http(s)://` swapped to\n * `ws(s)://`) for the socket URL by default, overridable via\n * `config.wsUrl`.\n */\n public readonly realtime: PoolseRealtime;\n\n private readonly resolved: ResolvedConfig;\n private readonly tokenCache: TokenCache;\n\n constructor(config: PoolseConfig) {\n this.resolved = resolveConfig(config);\n\n // Wrap the consumer's `getToken` in a cache so the SDK doesn't\n // call back on every REST request / WebSocket connect. Both the\n // REST client and the realtime layer share this one instance so a\n // freshly-minted token from one path serves all subsequent calls.\n this.tokenCache = new TokenCache(this.resolved.getToken);\n const cachedConfig: ResolvedConfig = {\n ...this.resolved,\n getToken: () => this.tokenCache.getToken(),\n };\n\n this.rest = new RestClient(cachedConfig, this.tokenCache);\n this.me = new MeResource(this.rest);\n this.conversations = new ConversationsResource(this.rest);\n this.messages = new MessagesResource(this.rest);\n this.attachments = new AttachmentsResource(this.rest, cachedConfig.fetch);\n this.users = new UsersResource(cachedConfig);\n\n this.realtime = new PoolseRealtime(cachedConfig, this.tokenCache, {\n ...(this.resolved.wsUrl !== undefined ? { wsUrl: this.resolved.wsUrl } : {}),\n socketPath: this.resolved.socketPath,\n });\n }\n\n /**\n * Tear down the SDK: close the WebSocket, drop all channels.\n * No-op for REST — fetch() doesn't keep persistent state.\n * Call this when the user signs out or the SDK instance is\n * being replaced.\n */\n destroy(): void {\n this.realtime.disconnect();\n }\n}\n","// Single source of truth for the SDK version at runtime. Kept in sync\n// with package.json by the release process.\nexport const version = '2.0.0';\n"]}
1
+ {"version":3,"sources":["../src/uuid.ts","../src/config.ts","../src/errors.ts","../src/realtime/realtime.ts","../src/resources/attachments.ts","../src/resources/messages.ts","../src/resources/conversations.ts","../src/resources/me.ts","../src/resources/users.ts","../src/rest-client.ts","../src/token-cache.ts","../src/poolse.ts","../src/version.ts"],"names":["Socket"],"mappings":";;;;;AAmBO,SAAS,QAAA,GAAmB;AACjC,EAAA,MAAM,IACJ,UAAA,CAMA,MAAA;AAEF,EAAA,IAAI,CAAA,EAAG,UAAA,EAAY,OAAO,CAAA,CAAE,UAAA,EAAW;AAEvC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,IAAI,GAAG,eAAA,EAAiB;AACtB,IAAA,CAAA,CAAE,gBAAgB,KAAK,CAAA;AAAA,EACzB,CAAA,MAAO;AACL,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,MAAA,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,KAAW,GAAG,CAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,KAAA,CAAM,CAAC,CAAA,GAAK,KAAA,CAAM,CAAC,IAAK,EAAA,GAAQ,EAAA;AAChC,EAAA,KAAA,CAAM,CAAC,CAAA,GAAK,KAAA,CAAM,CAAC,IAAK,EAAA,GAAQ,GAAA;AAEhC,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAG,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,EAClD;AACA,EAAA,OACE,IAAI,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,GACvB,GAAA,GACA,GAAA,CAAI,KAAA,CAAM,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA,GACvB,MACA,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,IAAA,CAAK,EAAE,IACvB,GAAA,GACA,GAAA,CAAI,MAAM,CAAA,EAAG,EAAE,EAAE,IAAA,CAAK,EAAE,IACxB,GAAA,GACA,GAAA,CAAI,MAAM,EAAE,CAAA,CAAE,KAAK,EAAE,CAAA;AAEzB;;;ACnDO,IAAM,cAAA,GAAiB;AA8H9B,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,uBAAA,GAA0B,GAAA;AAChC,IAAM,sBAAA,GAAyB,GAAA;AAExB,SAAS,cAAc,MAAA,EAAsC;AAClE,EAAA,IAAI,OAAO,MAAA,CAAO,QAAA,KAAa,UAAA,EAAY;AACzC,IAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAAA,EAC1E;AAEA,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,KAAA,IAAS,UAAA,CAAW,KAAA;AAC5C,EAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AAOA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,UAAU,CAAA;AAExC,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,iBAAA,CAAkB,MAAA,CAAO,MAAA,IAAU,cAAc,CAAA;AAAA,IACzD,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,KAAA,EAAO,OAAA;AAAA,IACP,UAAA,EAAY,OAAO,UAAA,IAAc,mBAAA;AAAA,IACjC,aAAA,EAAe,OAAO,aAAA,IAAiB,uBAAA;AAAA,IACvC,YAAA,EAAc,OAAO,YAAA,IAAgB,sBAAA;AAAA,IACrC,sBAAA,EAAwB,OAAO,sBAAA,IAA0B,qBAAA;AAAA,IACzD,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,UAAA,EAAY,OAAO,UAAA,IAAc,SAAA;AAAA,IACjC,eAAe,MAAA,CAAO,aAAA;AAAA,IACtB,cAAc,MAAA,CAAO;AAAA,GACvB;AACF;AAEA,SAAS,kBAAkB,CAAA,EAAmB;AAC5C,EAAA,OAAO,CAAA,CAAE,SAAS,GAAG,CAAA,GAAI,EAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,CAAA;AAC5C;AAQA,SAAS,qBAAA,GAAgC;AACvC,EAAA,OAAO,QAAA,EAAS;AAClB;;;AChLO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAM;AAAA,EACZ,IAAA,GAAe,aAAA;AAAA,EAExC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAGO,IAAM,YAAA,GAAN,cAA2B,WAAA,CAAY;AAAA,EACnB,IAAA,GAAe,cAAA;AAAA,EACf,KAAA;AAAA,EAEzB,WAAA,CAAY,SAAiB,KAAA,EAAgB;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AACF;AAMO,IAAM,QAAA,GAAN,cAAuB,WAAA,CAAY;AAAA,EACf,IAAA,GAAe,UAAA;AAAA,EACxB,MAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EAEhB,WAAA,CAAY,QAAgB,QAAA,EAAkC;AAC5D,IAAA,KAAA,CAAM,CAAA,CAAA,EAAI,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,IAAI,CAAA,EAAA,EAAK,QAAA,CAAS,OAAO,CAAA,CAAE,CAAA;AACzD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAO,QAAA,CAAS,IAAA;AACrB,IAAA,IAAA,CAAK,SAAS,QAAA,CAAS,OAAA;AACvB,IAAA,IAAA,CAAK,UAAU,QAAA,CAAS,OAAA;AAAA,EAC1B;AACF;AAMO,IAAM,gBAAA,GAAN,cAA+B,QAAA,CAAS;AAAA,EACpB,IAAA,GAAe,kBAAA;AAAA,EACxB,YAAA;AAAA,EAEhB,WAAA,CAAY,UAAkC,YAAA,EAAsB;AAClE,IAAA,KAAA,CAAM,KAAK,QAAQ,CAAA;AACnB,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,EACtB;AACF;AAQO,IAAM,SAAA,GAAN,cAAwB,QAAA,CAAS;AAAA,EACb,IAAA,GAAe,WAAA;AAAA,EAExC,YAAY,QAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,KAAK,QAAQ,CAAA;AAAA,EACrB;AACF;;;ACxBO,IAAM,iBAAN,MAAqB;AAAA,EACT,MAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EAET,MAAA,GAAwB,IAAA;AAAA,EACf,aAAA,uBAAoB,GAAA,EAAiC;AAAA,EAC9D,WAAA,GAAkC,IAAA;AAAA,EAElC,MAAA,GAAyB,MAAA;AAAA,EAChB,eAAA,uBAAsB,GAAA,EAAiC;AAAA,EAExE,WAAA,CAAY,MAAA,EAAwB,UAAA,EAAwB,IAAA,GAAwB,EAAC,EAAG;AACtF,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,SAAA;AACrC,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,WAAA,CAAY,OAAO,MAAM,CAAA;AAAA,EACtD;AAAA;AAAA,EAGA,SAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGA,SAAS,QAAA,EAAyD;AAChE,IAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,QAAQ,CAAA;AACjC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA,CAAgB,MAAA,CAAO,QAAQ,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,OAAA,GAAgB;AACd,IAAA,IAAI,KAAK,MAAA,EAAQ;AAEjB,IAAA,IAAA,CAAK,UAAU,YAAY,CAAA;AAE3B,IAAA,MAAM,MAAA,GAAS,IAAIA,cAAA,CAAO,CAAA,EAAG,KAAK,KAAK,CAAA,EAAG,IAAA,CAAK,UAAU,CAAA,CAAA,EAAI;AAAA,MAC3D,MAAA,EAAQ,OAAO,EAAE,KAAA,EAAO,KAAK,UAAA,CAAW,SAAA,MAAe,EAAA,EAAG;AAAA;AAAA;AAAA,KAG3D,CAAA;AAED,IAAA,MAAA,CAAO,MAAA,CAAO,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,CAAC,CAAA;AAC/C,IAAA,MAAA,CAAO,QAAQ,MAAM;AAInB,MAAA,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,MAAA,KAAW,QAAA,GAAW,WAAW,cAAc,CAAA;AAAA,IACrE,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAGtB,MAAA,IAAA,CAAK,UAAU,cAAc,CAAA;AAC7B,MAAA,IAAA,CAAK,MAAA,CAAO,gBAAgB,IAAI,WAAA,CAAY,iBAAiB,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE,CAAC,CAAA;AAAA,IAC7E,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAKd,IAAA,KAAK,KAAK,UAAA,CACP,QAAA,EAAS,CACT,KAAA,CAAM,CAAC,GAAA,KAAQ;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,aAAA;AAAA,QACV,IAAI,WAAA,CAAY,CAAA,uCAAA,EAA0C,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE;AAAA,OACzE;AAAA,IACF,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,MAAA,CAAO,OAAA,EAAQ;AAAA,IACjB,CAAC,CAAA;AAAA,EACL;AAAA;AAAA,EAGA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,UAAU,QAAQ,CAAA;AACvB,IAAA,IAAA,CAAK,cAAc,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,CAAA;AAC9C,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,aAAa,QAAA,EAAS;AAC3B,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAA,CAAK,OAAO,UAAA,EAAW;AACvB,MAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,IAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,cAAA,EAA6C;AACxD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAc,CAAA;AACtD,IAAA,IAAI,UAAU,OAAO,QAAA;AAErB,IAAA,IAAA,CAAK,OAAA,EAAQ;AAEb,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,MAAA,MAAM,IAAI,YAAY,oDAA+C,CAAA;AAAA,IACvE;AAEA,IAAA,MAAM,OAAA,GAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,gBAAgB,cAAc,CAAA,CAAA,EAAI,EAAE,CAAA;AACxE,IAAA,MAAM,MAAA,GAAS,IAAI,mBAAA,CAAoB,cAAA,EAAgB,OAAO,CAAA;AAC9D,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAA,EAAgB,MAAM,CAAA;AAC7C,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,MAAA,EAA6B;AAChC,IAAA,IAAI,IAAA,CAAK,WAAA,EAAa,OAAO,IAAA,CAAK,WAAA;AAElC,IAAA,IAAA,CAAK,OAAA,EAAQ;AAEb,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,MAAA,MAAM,IAAI,YAAY,oDAA+C,CAAA;AAAA,IACvE;AAEA,IAAA,MAAM,OAAA,GAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,MAAM,CAAA,CAAA,EAAI,EAAE,CAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAI,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAA;AAC9C,IAAA,IAAA,CAAK,WAAA,GAAc,MAAA;AACnB,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,cAAA,EAA8B;AAClC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAc,CAAA;AACpD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAA,CAAO,QAAA,EAAS;AAChB,IAAA,IAAA,CAAK,aAAA,CAAc,OAAO,cAAc,CAAA;AAAA,EAC1C;AAAA,EAEQ,UAAU,MAAA,EAA8B;AAC9C,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC5B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,gBAAgB,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,EAC/C;AACF;AAIO,IAAM,sBAAN,MAA0B;AAAA,EACf,cAAA;AAAA,EACC,OAAA;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,uBAAgB,GAAA,EAA6C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQtE,gBAAkC,EAAC;AAAA,EACnC,iBAAA,GAAoB,KAAA;AAAA,EAE5B,WAAA,CAAY,gBAAwB,OAAA,EAAkB;AACpD,IAAA,IAAA,CAAK,cAAA,GAAiB,cAAA;AACtB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAIf,IAAA,OAAA,CAAQ,EAAA,CAAG,gBAAA,EAAkB,CAAC,OAAA,KAAqB;AACjD,MAAA,IAAA,CAAK,aAAA,GAAiB,WAAW,EAAC;AAClC,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AACzB,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,gBAAgB,CAAA;AACrD,MAAA,IAAI,SAAA,YAAqB,OAAA,CAAQ,CAAC,MAAM,CAAA,CAAE,IAAA,CAAK,aAAa,CAAC,CAAA;AAAA,IAC/D,CAAC,CAAA;AACD,IAAA,OAAA,CAAQ,EAAA,CAAG,eAAA,EAAiB,CAAC,OAAA,KAAqB;AAChD,MAAA,MAAM,IAAA,GAAQ,WAAW,EAAC;AAC1B,MAAA,MAAM,IAAA,GAAyB,EAAE,GAAG,IAAA,CAAK,aAAA,EAAc;AACvD,MAAA,IAAI,IAAA,CAAK,KAAA,EAAO,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAC3E,MAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,EAAG,OAAO,IAAA,CAAK,CAAC,CAAA;AACxE,MAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,eAAe,CAAA;AACpD,MAAA,IAAI,WAAW,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,IACpD,CAAC,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,UAAU,EAAA,EAAiD;AACzD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,aAAA,EAAe,EAA0B,CAAA;AAAA,EACjE;AAAA;AAAA,EAGA,iBAAiB,EAAA,EAAqD;AACpE,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,iBAAA,EAAmB,EAA0B,CAAA;AAAA,EACrE;AAAA;AAAA,EAGA,iBAAiB,EAAA,EAAqD;AACpE,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,iBAAA,EAAmB,EAA0B,CAAA;AAAA,EACrE;AAAA,EAEA,cAAc,EAAA,EAA6C;AACzD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,cAAA,EAAgB,EAA0B,CAAA;AAAA,EAClE;AAAA,EAEA,aAAa,EAAA,EAA6C;AACxD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,aAAA,EAAe,EAA0B,CAAA;AAAA,EACjE;AAAA,EAEA,gBAAgB,EAAA,EAA+C;AAC7D,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,gBAAA,EAAkB,EAA0B,CAAA;AAAA,EACpE;AAAA,EAEA,kBAAkB,EAAA,EAA+C;AAC/D,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,kBAAA,EAAoB,EAA0B,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,EAAA,EAAiD;AAC5D,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,aAAA,EAAe,EAA0B,CAAA;AAAA,EACjE;AAAA,EAEA,gBAAgB,EAAA,EAAoD;AAClE,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,gBAAgB,CAAA;AAC7C,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,GAAA,uBAAU,GAAA,EAAI;AACd,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,gBAAA,EAAkB,GAAG,CAAA;AAAA,IAC1C;AACA,IAAA,GAAA,CAAI,IAAI,EAA0B,CAAA;AAIlC,IAAA,IAAI,IAAA,CAAK,iBAAA,EAAmB,EAAA,CAAG,IAAA,CAAK,aAAa,CAAA;AACjD,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,CAAI,OAAO,EAA0B,CAAA;AAAA,IACvC,CAAA;AAAA,EACF;AAAA,EAEA,eAAe,EAAA,EAAmD;AAChE,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,eAAA,EAAiB,EAA0B,CAAA;AAAA,EACnE;AAAA;AAAA,EAGA,gBAAA,GAAqC;AACnC,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EACd;AAAA;AAAA,EAGA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,QAAA,EAAU,EAAE,CAAA;AAAA,EAChC;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAQ,IAAA,EAAK;AAAA,EACpB;AAAA;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AAAA,EAEQ,SAAA,CAAU,OAAe,EAAA,EAA6C;AAC5E,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AAClC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,GAAA,uBAAU,GAAA,EAAI;AACd,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAC7B,MAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,KAAA,EAAO,CAAC,OAAA,KAAqB;AAC3C,QAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AAC1C,QAAA,IAAI,WAAW,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,MACpD,CAAC,CAAA;AAAA,IACH;AACA,IAAA,GAAA,CAAI,IAAI,EAAE,CAAA;AACV,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,CAAI,OAAO,EAAE,CAAA;AAAA,IACf,CAAA;AAAA,EACF;AACF;AAIO,IAAM,cAAN,MAAkB;AAAA,EACP,MAAA;AAAA,EACC,OAAA;AAAA,EACA,gBAAA,uBAAuB,GAAA,EAAiC;AAAA,EACxD,4BAAA,uBAAmC,GAAA,EAElD;AAAA,EACM,YAAA,GAAe,KAAA;AAAA,EACf,wBAAA,GAA2B,KAAA;AAAA,EAEnC,WAAA,CAAY,QAAgB,OAAA,EAAkB;AAC5C,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,UAAU,EAAA,EAA8C;AACtD,IAAA,IAAI,CAAC,KAAK,YAAA,EAAc;AACtB,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,MAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,aAAA,EAAe,CAAC,OAAA,KAAqB;AACnD,QAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,OAAuB,CAAC,CAAA;AAAA,MACjE,CAAC,CAAA;AAAA,IACH;AACA,IAAA,IAAA,CAAK,gBAAA,CAAiB,IAAI,EAAE,CAAA;AAC5B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,EAAE,CAAA;AAAA,IACjC,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,sBAAsB,EAAA,EAA2D;AAC/E,IAAA,IAAI,CAAC,KAAK,wBAAA,EAA0B;AAClC,MAAA,IAAA,CAAK,wBAAA,GAA2B,IAAA;AAChC,MAAA,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAG,sBAAA,EAAwB,CAAC,OAAA,KAAqB;AAC5D,QAAA,IAAA,CAAK,6BAA6B,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,OAAmC,CAAC,CAAA;AAAA,MACzF,CAAC,CAAA;AAAA,IACH;AACA,IAAA,IAAA,CAAK,4BAAA,CAA6B,IAAI,EAAE,CAAA;AACxC,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,4BAAA,CAA6B,OAAO,EAAE,CAAA;AAAA,IAC7C,CAAA;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAQ,IAAA,EAAK;AAAA,EACpB;AAAA;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,iBAAiB,KAAA,EAAM;AAC5B,IAAA,IAAA,CAAK,6BAA6B,KAAA,EAAM;AACxC,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF;AAIA,SAAS,YAAY,MAAA,EAAwB;AAI3C,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA;AACrC;;;AChWO,IAAM,sBAAN,MAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS/B,WAAA,CACmB,QACA,OAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAChB;AAAA,EAFgB,MAAA;AAAA,EACA,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASnB,aAAA,CACE,KAAA,EACA,IAAA,GAA0B,EAAC,EACQ;AACnC,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAkC;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,4BAAA;AAAA,MACN,IAAA,EAAM,KAAA;AAAA,MACN,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW;AAAC,KAC9C,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,MAAM,MAAA,CAAO,KAAA,EAA8B,IAAA,GAA0B,EAAC,EAAwB;AAC5F,IAAA,MAAM,GAAA,GAA+B;AAAA,MACnC,cAAc,KAAA,CAAM,WAAA;AAAA,MACpB,WAAW,KAAA,CAAM,QAAA;AAAA,MACjB,GAAI,MAAM,QAAA,KAAa,MAAA,GAAY,EAAE,iBAAA,EAAmB,KAAA,CAAM,QAAA,EAAS,GAAI;AAAC,KAC9E;AAEA,IAAA,MAAM,EAAE,YAAY,MAAA,EAAO,GAAI,MAAM,IAAA,CAAK,aAAA,CAAc,KAAK,IAAI,CAAA;AAMjE,IAAA,IAAI,IAAA,CAAK,UAAA,IAAc,OAAO,cAAA,KAAmB,WAAA,EAAa;AAC5D,MAAA,MAAM,MAAA,CAAO,MAAA,CAAO,GAAA,EAAK,MAAA,CAAO,MAAA,CAAO,aAAY,EAAG,MAAA,CAAO,OAAA,EAAS,KAAA,CAAM,IAAA,EAAM;AAAA,QAChF,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW;AAAC,OAC9C,CAAA;AACD,MAAA,OAAO,UAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,WAAA,EAAY;AAAA,MAClC,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW;AAAC,KAC/C;AAEA,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,KAAK,OAAO,CAAA;AAClD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,qCAAA,EAAwC,GAAA,CAAI,MAAM,CAAA,iBAAA,EAAoB,WAAW,EAAE,CAAA;AAAA,OACrF;AAAA,IACF;AACA,IAAA,OAAO,UAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,EAAA,EAA4B;AAC9B,IAAA,OAAO,IAAI,gBAAA,CAAiB,IAAA,CAAK,MAAA,EAAQ,EAAE,CAAA;AAAA,EAC7C;AACF;AAGO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,WAAA,CACmB,QACD,EAAA,EAChB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACD,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAAA,EACf;AAAA,EAFgB,MAAA;AAAA,EACD,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlB,WAAA,CAAY,IAAA,GAA0B,EAAC,EAAwC;AAC7E,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAoC;AAAA,MACrD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,gBAAA,EAAmB,IAAA,CAAK,EAAE,CAAA,aAAA,CAAA;AAAA,MAChC,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW;AAAC,KAC9C,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAA,CAAO,IAAA,GAA0B,EAAC,EAAkB;AAClD,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAc;AAAA,MAC/B,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA,EAAM,CAAA,gBAAA,EAAmB,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,MAChC,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW;AAAC,KAC9C,CAAA;AAAA,EACH;AACF;AAWA,SAAS,MAAA,CACP,GAAA,EACA,MAAA,EACA,OAAA,EACA,MACA,IAAA,EAKe;AACf,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,GAAA,GAAM,IAAI,cAAA,EAAe;AAC/B,IAAA,GAAA,CAAI,IAAA,CAAK,QAAQ,GAAG,CAAA;AACpB,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAC5C,MAAA,IAAI;AACF,QAAA,GAAA,CAAI,gBAAA,CAAiB,GAAG,CAAC,CAAA;AAAA,MAC3B,CAAA,CAAA,MAAQ;AAAA,MAGR;AAAA,IACF;AACA,IAAA,GAAA,CAAI,MAAA,CAAO,UAAA,GAAa,CAAC,CAAA,KAAM;AAG7B,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,gBAAA,GAAmB,CAAA,CAAE,QAAQ,IAAA,CAAK,QAAA;AAClD,MAAA,IAAA,CAAK,WAAW,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,OAAO,CAAA;AAAA,IAC7C,CAAA;AACA,IAAA,GAAA,CAAI,SAAS,MAAM;AACjB,MAAA,IAAI,IAAI,MAAA,IAAU,GAAA,IAAO,GAAA,CAAI,MAAA,GAAS,KAAK,OAAA,EAAQ;AAAA;AAEjD,QAAA,MAAA,CAAO,IAAI,MAAM,CAAA,qCAAA,EAAwC,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,GAAA,CAAI,UAAU,CAAA,CAAA,CAAG,CAAC,CAAA;AAAA,IAC7F,CAAA;AACA,IAAA,GAAA,CAAI,UAAU,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,qDAAqD,CAAC,CAAA;AAC3F,IAAA,GAAA,CAAI,UAAU,MAAM;AAElB,MAAA,MAAA,CAAO,IAAI,YAAA,CAAa,gBAAA,EAAkB,YAAY,CAAC,CAAA;AAAA,IACzD,CAAA;AACA,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AACvB,QAAA,GAAA,CAAI,KAAA,EAAM;AACV,QAAA;AAAA,MACF;AACA,MAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,OAAA,EAAS,MAAM,GAAA,CAAI,OAAM,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,IACzE;AAIA,IAAA,GAAA,CAAI,KAAK,IAA8B,CAAA;AAAA,EACzC,CAAC,CAAA;AACH;;;AClQO,IAAM,uBAAN,MAA2B;AAAA,EAChC,WAAA,CACmB,QACA,cAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AAAA,EAChB;AAAA,EAFgB,MAAA;AAAA,EACA,cAAA;AAAA,EAGnB,IAAA,CAAK,IAAA,GAA4C,EAAC,EAAG,MAAA,EAA4C;AAC/F,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAqB;AAAA,MACtC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,cAAc,CAAA,SAAA,CAAA;AAAA,MAC9C,KAAA,EAAO;AAAA,QACL,GAAI,KAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,GAAI,EAAC;AAAA,QACxD,GAAI,KAAK,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO,GAAI;AAAC,OAC7D;AAAA,MACA,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,IAAA,CAAK,OAA6B,MAAA,EAAwC;AACxE,IAAA,MAAM,IAAA,GACJ,KAAA,CAAM,EAAA,KAAO,MAAA,GAAY,KAAA,GAAQ,EAAE,GAAG,KAAA,EAAO,EAAA,EAAI,uBAAA,EAAwB,EAAE;AAC7E,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAiB;AAAA,MAClC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,cAAc,CAAA,SAAA,CAAA;AAAA,MAC9C,IAAA;AAAA,MACA,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,QAAA,CAAS,WAAiB,MAAA,EAAqC;AAC7D,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAc;AAAA,MAC/B,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,cAAc,CAAA,KAAA,CAAA;AAAA,MAC9C,IAAA,EAAM,EAAE,UAAA,EAAY,SAAA,EAAU;AAAA,MAC9B,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AACF;AAGO,IAAM,gBAAN,MAAoB;AAAA,EACzB,WAAA,CACmB,QACD,EAAA,EAChB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACD,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAAA,EACf;AAAA,EAFgB,MAAA;AAAA,EACD,EAAA;AAAA,EAGlB,MAAA,CAAO,OAA6B,MAAA,EAAwC;AAC1E,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAiB;AAAA,MAClC,MAAA,EAAQ,OAAA;AAAA,MACR,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,MAC7B,IAAA,EAAM,KAAA;AAAA,MACN,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,MAAA,EAAqC;AAC1C,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAc;AAAA,MAC/B,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,MAC7B,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,OAAA,CACE,IAAA,GAA2C,EAAC,EAC5C,MAAA,EACsB;AACtB,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAqB;AAAA,MACtC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAA,CAAK,EAAE,CAAA,QAAA,CAAA;AAAA,MAC7B,KAAA,EAAO;AAAA,QACL,GAAI,KAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,GAAI,EAAC;AAAA,QACxD,GAAI,KAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,GAAI;AAAC,OAC1D;AAAA,MACA,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,WAAA,CAAY,OAAe,MAAA,EAAwC;AACjE,IAAA,MAAM,IAAA,GAAwB,EAAE,KAAA,EAAM;AACtC,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAiB;AAAA,MAClC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAA,CAAK,EAAE,CAAA,UAAA,CAAA;AAAA,MAC7B,IAAA;AAAA,MACA,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,cAAA,CAAe,OAAe,MAAA,EAAwC;AACpE,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAiB;AAAA,MAClC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,aAAA,EAAgB,IAAA,CAAK,EAAE,CAAA,WAAA,EAAc,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA,MACpE,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AACF;AAGO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,MAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAqB;AAAA,EAArB,MAAA;AAAA,EAE7B,IAAI,EAAA,EAAyB;AAC3B,IAAA,OAAO,IAAI,aAAA,CAAc,IAAA,CAAK,MAAA,EAAQ,EAAE,CAAA;AAAA,EAC1C;AACF;AASA,SAAS,uBAAA,GAAgC;AACvC,EAAA,OAAO,QAAA,EAAS;AAClB;;;AC3HO,IAAM,qBAAN,MAAyB;AAAA,EAO9B,WAAA,CACmB,QACD,EAAA,EAChB;AAFiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACD,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAEhB,IAAA,IAAA,CAAK,WAAW,IAAI,oBAAA,CAAqB,IAAA,CAAK,MAAA,EAAQ,KAAK,EAAE,CAAA;AAAA,EAC/D;AAAA,EAJmB,MAAA;AAAA,EACD,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAJF,QAAA;AAAA,EAShB,KAAK,MAAA,EAA6C;AAChD,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAsB;AAAA,MACvC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,MAClC,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,MAAA,CAAO,OAAkC,MAAA,EAA6C;AACpF,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAsB;AAAA,MACvC,MAAA,EAAQ,OAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,MAClC,IAAA,EAAM,KAAA;AAAA,MACN,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA;AAAA,EAIA,YAAY,MAAA,EAA+C;AACzD,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAwB;AAAA,MACzC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,EAAE,CAAA,QAAA,CAAA;AAAA,MAClC,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,UAAA,CAAW,WAAA,EAAuB,IAAA,GAAyB,EAAC,EAA4B;AACtF,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAwB;AAAA,MACzC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,EAAE,CAAA,QAAA,CAAA;AAAA,MAClC,IAAA,EAAM;AAAA,QACJ,YAAA,EAAc,WAAA;AAAA,QACd,GAAI,KAAK,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK,GAAI;AAAC,OACvD;AAAA,MACA,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW;AAAC,KAC9C,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAAA,CAAU,UAAA,EAAoB,IAAA,GAAyB,EAAC,EAAwB;AACpF,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,WAAW,CAAC,UAAU,GAAG,IAAI,CAAA;AACrD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AACvB,IAAA,IAAI,CAAC,GAAA,EAAK;AAIR,MAAA,MAAM,IAAI,MAAM,oEAAoE,CAAA;AAAA,IACtF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,YAAA,CAAa,QAAc,MAAA,EAAqC;AAC9D,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAc;AAAA,MAC/B,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA,EAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,EAAE,YAAY,MAAM,CAAA,CAAA;AAAA,MACpD,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AACF;AAGO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,MAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAqB;AAAA,EAArB,MAAA;AAAA,EAE7B,KAAK,MAAA,EAAiD;AACpD,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAA0B;AAAA,MAC3C,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,mBAAA;AAAA,MACN,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA,EAEA,MAAA,CAAO,OAAkC,MAAA,EAA6C;AACpF,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAsB;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,mBAAA;AAAA,MACN,IAAA,EAAM,KAAA;AAAA,MACN,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,IAAI,EAAA,EAA8B;AAChC,IAAA,OAAO,IAAI,kBAAA,CAAmB,IAAA,CAAK,MAAA,EAAQ,EAAE,CAAA;AAAA,EAC/C;AACF;;;AC1IO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAA6B,MAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAqB;AAAA,EAArB,MAAA;AAAA;AAAA,EAG7B,KAAK,MAAA,EAAmC;AACtC,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,CAAY;AAAA,MAC7B,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,QAAA;AAAA,MACN,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC5B,CAAA;AAAA,EACH;AACF;;;ACWO,IAAM,gBAAN,MAAoB;AAAA,EAKzB,YAA6B,MAAA,EAAwB;AAAxB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAyB;AAAA,EAAzB,MAAA;AAAA,EAJZ,KAAA,uBAAY,GAAA,EAAsC;AAAA,EAClD,OAAA,uBAAc,GAAA,EAA+C;AAAA,EAC7D,SAAA,uBAAgB,GAAA,EAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS5D,KAAK,UAAA,EAA0D;AAC7D,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAU,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,UAAA,EAAuD;AAC/D,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAU,CAAA,EAAG;AAC9B,MAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAU,CAAA,IAAK,IAAA;AAAA,IACvC;AACA,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AACnD,IAAA,IAAI,iBAAiB,OAAO,eAAA;AAE5B,IAAA,MAAM,QAAA,GAAW,KAAK,MAAA,CAAO,YAAA;AAC7B,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAA,EAAY,IAAI,CAAA;AAC/B,MAAA,IAAA,CAAK,OAAO,UAAU,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,EAAQ,CAC7B,KAAK,MAAM,QAAA,CAAS,UAAU,CAAC,CAAA,CAC/B,IAAA;AAAA,MACC,CAAC,OAAA,KAAY;AACX,QAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAA,EAAY,OAAA,IAAW,IAAI,CAAA;AAC1C,QAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,UAAU,CAAA;AAC9B,QAAA,IAAA,CAAK,OAAO,UAAU,CAAA;AACtB,QAAA,OAAO,OAAA,IAAW,IAAA;AAAA,MACpB,CAAA;AAAA,MACA,CAAC,GAAA,KAAiB;AAKhB,QAAA,OAAA,CAAQ,KAAA,CAAM,kCAAA,EAAoC,UAAA,EAAY,GAAG,CAAA;AACjE,QAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAA,EAAY,IAAI,CAAA;AAC/B,QAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,UAAU,CAAA;AAC9B,QAAA,IAAA,CAAK,OAAO,UAAU,CAAA;AACtB,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,KACF;AACF,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,UAAA,EAAY,OAAO,CAAA;AACpC,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAA,CAAU,YAAoB,QAAA,EAAgC;AAC5D,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,UAAU,CAAA;AACvC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,GAAA,uBAAU,GAAA,EAAI;AACd,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,UAAA,EAAY,GAAG,CAAA;AAAA,IACpC;AACA,IAAA,GAAA,CAAI,IAAI,QAAQ,CAAA;AAChB,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,EAAK,OAAO,QAAQ,CAAA;AAAA,IACtB,CAAA;AAAA,EACF;AAAA;AAAA,EAGA,WAAW,UAAA,EAA0B;AACnC,IAAA,IAAA,CAAK,KAAA,CAAM,OAAO,UAAU,CAAA;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,UAAU,CAAA;AAC9B,IAAA,IAAA,CAAK,OAAO,UAAU,CAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,KAAA,MAAW,UAAA,IAAc,IAAA,CAAK,SAAA,CAAU,IAAA,EAAK,EAAG;AAC9C,MAAA,IAAA,CAAK,OAAO,UAAU,CAAA;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,OAAO,UAAA,EAA0B;AACvC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,UAAU,CAAA;AACzC,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,CAAA,EAAE;AAAA,EACzB;AACF;;;ACxFA,IAAM,kBAAA,mBAA8C,IAAI,GAAA,CAAI,CAAC,KAAK,CAAC,CAAA;AAE5D,IAAM,aAAN,MAAiB;AAAA,EACL,MAAA;AAAA,EACA,UAAA;AAAA,EAEjB,WAAA,CAAY,QAAwB,UAAA,EAAwB;AAC1D,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAAA,EACpB;AAAA,EAEA,MAAM,QAAW,IAAA,EAAkC;AACjD,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,KAAK,KAAK,CAAA;AAC/C,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,MAAA,CAAO,UAAA;AAClD,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,qBAAA,CAAsB,IAAI,CAAA;AAEtD,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,gBAAA,GAAmB,KAAA;AAIvB,IAAA,WAAS;AACP,MAAA,MAAM,IAAA,GAAO,KAAK,IAAA,KAAS,MAAA,GAAY,SAAY,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AAC3E,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,KAAK,MAAA,EAAQ,cAAA,EAAgB,SAAS,MAAS,CAAA;AAEvF,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAoB,EAAE,MAAA,EAAQ,IAAA,CAAK,QAAQ,OAAA,EAAQ;AACzD,QAAA,IAAI,IAAA,KAAS,KAAA,CAAA,EAAW,IAAA,CAAK,IAAA,GAAO,IAAA;AACpC,QAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,MAAA;AACpC,QAAA,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,MAC9C,SAAS,GAAA,EAAK;AAOZ,QAAA,IAAI,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,YAAA,EAAc;AAC5D,UAAA,MAAM,GAAA;AAAA,QACR;AACA,QAAA,IAAI,OAAA,GAAU,UAAA,IAAc,uBAAA,CAAwB,GAAG,CAAA,EAAG;AACxD,UAAA,MAAM,KAAA,CAAM,IAAA,CAAK,YAAA,CAAa,OAAO,CAAC,CAAA;AACtC,UAAA,OAAA,IAAW,CAAA;AACX,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAI,YAAA,CAAa,wBAAA,EAA0B,GAAG,CAAA;AAAA,MACtD;AAEA,MAAA,IAAI,QAAA,CAAS,MAAA,IAAU,GAAA,IAAO,QAAA,CAAS,SAAS,GAAA,EAAK;AACnD,QAAA,OAAQ,MAAM,gBAAgB,QAAQ,CAAA;AAAA,MACxC;AAQA,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,UAAA,IAAA,CAAK,WAAW,UAAA,EAAW;AAC3B,UAAA,gBAAA,GAAmB,IAAA;AACnB,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAI,SAAA,CAAU,MAAM,aAAA,CAAc,QAAQ,CAAC,CAAA;AAAA,MACnD;AAGA,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,MAAM,QAAA,GAAW,MAAM,aAAA,CAAc,QAAQ,CAAA;AAC7C,QAAA,MAAM,YAAA,GAAe,mBAAmB,QAAQ,CAAA;AAChD,QAAA,IAAI,UAAU,UAAA,EAAY;AACxB,UAAA,MAAM,KAAA,CAAM,KAAK,GAAA,CAAI,YAAA,IAAgB,GAAG,IAAA,CAAK,YAAA,CAAa,OAAO,CAAC,CAAC,CAAA;AACnE,UAAA,OAAA,IAAW,CAAA;AACX,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAI,gBAAA,CAAiB,QAAA,EAAU,YAAA,IAAgB,CAAC,CAAA;AAAA,MACxD;AAKA,MAAA,IAAI,QAAA,CAAS,MAAA,IAAU,GAAA,IAAO,OAAA,GAAU,UAAA,EAAY;AAClD,QAAA,MAAM,KAAA,CAAM,IAAA,CAAK,YAAA,CAAa,OAAO,CAAC,CAAA;AACtC,QAAA,OAAA,IAAW,CAAA;AACX,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,IAAI,QAAA,CAAS,QAAA,CAAS,QAAQ,MAAM,aAAA,CAAc,QAAQ,CAAC,CAAA;AAAA,IACnE;AAAA,EACF;AAAA;AAAA,EAIQ,QAAA,CAAS,MAAc,KAAA,EAAyC;AACtE,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,CAAA;AAC7E,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,EAAM;AACjC,QAAA,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MAC5B;AAAA,IACF;AACA,IAAA,MAAM,EAAA,GAAK,OAAO,QAAA,EAAS;AAC3B,IAAA,OAAO,EAAA,GAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,IAAA;AAAA,EAChC;AAAA,EAEA,MAAc,YAAA,CACZ,MAAA,EACA,cAAA,EACA,OAAA,EACiC;AACjC,IAAA,MAAM,OAAA,GAAkC,EAAE,MAAA,EAAQ,kBAAA,EAAmB;AAErE,IAAA,IAAI,OAAA,EAAS,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAEvC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,MAAA,CAAO,QAAA,EAAS;AACzC,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,eAAe,CAAA,GAAI,UAAU,KAAK,CAAA,CAAA;AAErD,IAAA,IAAI,CAAC,kBAAA,CAAmB,GAAA,CAAI,MAAM,KAAK,cAAA,EAAgB;AACrD,MAAA,OAAA,CAAQ,iBAAiB,CAAA,GAAI,cAAA;AAAA,IAC/B;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEQ,sBAAsB,IAAA,EAAqC;AACjE,IAAA,IAAI,IAAA,CAAK,cAAA,KAAmB,IAAA,EAAM,OAAO,IAAA;AACzC,IAAA,IAAI,IAAA,CAAK,cAAA,EAAgB,OAAO,IAAA,CAAK,cAAA;AACrC,IAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,IAAA,CAAK,MAAM,GAAG,OAAO,IAAA;AAChD,IAAA,OAAO,IAAA,CAAK,OAAO,sBAAA,EAAuB;AAAA,EAC5C;AAAA,EAEQ,aAAa,OAAA,EAAyB;AAC5C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,aAAA,GAAgB,CAAA,IAAK,OAAA;AAC7C,IAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,cAAc,GAAG,CAAA;AAGrD,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,MAAM,CAAA;AAAA,EAC1C;AACF,CAAA;AAMA,eAAe,cAAc,QAAA,EAAqD;AAChF,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,IAAI,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA;AAAA,EACrC,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,eAAA;AAAA,IACN,OAAA,EAAS,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,IAChC,OAAA,EAAS;AAAA,GACX;AACF;AAEA,eAAe,gBAAgB,QAAA,EAAsC;AACnE,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,GAAA,EAAK,OAAO,IAAA;AACpC,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AACxB;AAEA,SAAS,mBAAmB,QAAA,EAAmC;AAC7D,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAC9C,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,QAAA,CAAS,GAAA,EAAK,EAAE,CAAA;AACvC,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,GAAI,UAAU,GAAA,GAAO,IAAA;AACrD;AAEA,SAAS,wBAAwB,GAAA,EAAuB;AAEtD,EAAA,IAAI,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,cAAc,OAAO,KAAA;AAErE,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;;;ACpMA,IAAM,iBAAA,GAAoB,GAAA;AAC1B,IAAM,eAAA,GAAkB,GAAA;AAEjB,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAA6B,OAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAAmB;AAAA,EAAnB,OAAA;AAAA,EAJrB,KAAA,GAAuB,IAAA;AAAA,EACvB,KAAA,GAAuB,IAAA;AAAA,EACvB,QAAA,GAA0C,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAelD,SAAA,GAA2B;AACzB,IAAA,IAAI,KAAK,KAAA,KAAU,IAAA,IAAQ,KAAK,KAAA,KAAU,IAAA,SAAa,IAAA,CAAK,KAAA;AAC5D,IAAA,OAAO,KAAK,GAAA,EAAI,GAAI,KAAK,KAAA,GAAQ,iBAAA,GAAoB,KAAK,KAAA,GAAQ,IAAA;AAAA,EACpE;AAAA,EAEA,MAAM,QAAA,CAAS,IAAA,GAAwB,EAAC,EAA2B;AACjE,IAAA,IAAI,IAAA,CAAK,YAAA,EAAc,IAAA,CAAK,UAAA,EAAW;AAEvC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,IAAA,CAAK,SAAS,IAAA,CAAK,KAAA,KAAU,QAAQ,GAAA,GAAM,IAAA,CAAK,QAAQ,iBAAA,EAAmB;AAC7E,MAAA,OAAO,IAAA,CAAK,KAAA;AAAA,IACd;AAEA,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,OAAO,IAAA,CAAK,QAAA;AAE/B,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,aAAA,EAAc,CAAE,QAAQ,MAAM;AACjD,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,IAClB,CAAC,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,EAKf;AAAA,EAEA,MAAc,aAAA,GAAwC;AACpD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,OAAA,EAAQ;AACjC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAA,GAAS,YAAY,KAAK,CAAA;AAChC,IAAA,IAAI,WAAW,IAAA,EAAM;AACnB,MAAA,MAAM,QAAQ,MAAA,GAAS,GAAA;AAIvB,MAAA,IAAA,CAAK,KAAA,GAAQ,SAAS,IAAA,CAAK,GAAA,KAAQ,IAAA,CAAK,GAAA,KAAQ,eAAA,GAAkB,KAAA;AAAA,IACpE,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,GAAA,EAAI,GAAI,eAAA;AAAA,IAC5B;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA;AAKA,SAAS,YAAY,KAAA,EAA8B;AACjD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAE/B,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAW,CAAA;AAC/C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,OAAO,OAAO,OAAA,CAAQ,GAAA,KAAQ,QAAA,IAAY,MAAA,CAAO,SAAS,OAAA,CAAQ,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA,GAAM,IAAA;AAAA,EACzF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,CAAA,EAAmB;AAG1C,EAAA,MAAM,GAAA,GAAM,EAAE,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AAClD,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,MAAA,CAAA,CAAQ,IAAK,GAAA,CAAI,MAAA,GAAS,KAAM,CAAC,CAAA;AAC1D,EAAA,IAAI,OAAO,IAAA,KAAS,UAAA,EAAY,OAAO,KAAK,MAAM,CAAA;AAIlD,EAAA,MAAM,CAAA,GAAI,UAAA;AAGV,EAAA,IAAI,CAAA,CAAE,MAAA,EAAQ,OAAO,CAAA,CAAE,MAAA,CAAO,KAAK,MAAA,EAAQ,QAAQ,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAA;AACtE,EAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAC/C;;;ACxHO,IAAM,SAAN,MAAa;AAAA;AAAA,EAEF,EAAA;AAAA;AAAA,EAEA,aAAA;AAAA;AAAA,EAEA,QAAA;AAAA;AAAA,EAEA,WAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAA;AAAA,EAEC,QAAA;AAAA,EACA,UAAA;AAAA,EAEjB,YAAY,MAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,QAAA,GAAW,cAAc,MAAM,CAAA;AAMpC,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,UAAA,CAAW,IAAA,CAAK,SAAS,QAAQ,CAAA;AACvD,IAAA,MAAM,YAAA,GAA+B;AAAA,MACnC,GAAG,IAAA,CAAK,QAAA;AAAA,MACR,QAAA,EAAU,MAAM,IAAA,CAAK,UAAA,CAAW,QAAA;AAAS,KAC3C;AAEA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,UAAA,CAAW,YAAA,EAAc,KAAK,UAAU,CAAA;AACxD,IAAA,IAAA,CAAK,EAAA,GAAK,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA;AAClC,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,qBAAA,CAAsB,IAAA,CAAK,IAAI,CAAA;AACxD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAC9C,IAAA,IAAA,CAAK,cAAc,IAAI,mBAAA,CAAoB,IAAA,CAAK,IAAA,EAAM,aAAa,KAAK,CAAA;AACxE,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,aAAA,CAAc,YAAY,CAAA;AAE3C,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,cAAA,CAAe,YAAA,EAAc,KAAK,UAAA,EAAY;AAAA,MAChE,GAAI,IAAA,CAAK,QAAA,CAAS,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,KAAA,EAAM,GAAI,EAAC;AAAA,MAC1E,UAAA,EAAY,KAAK,QAAA,CAAS;AAAA,KAC3B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,SAAS,UAAA,EAAW;AAAA,EAC3B;AACF;;;ACvFO,IAAM,OAAA,GAAU","file":"index.cjs","sourcesContent":["// Cross-runtime UUID v4 generator. Used internally for idempotency\n// keys, client-side message ids, and upload queue local ids — all\n// places that need a unique-per-call opaque string but NOT cryptographic\n// strength (the server enforces real auth and dedup; collisions here\n// only matter for in-process bookkeeping).\n//\n// Resolution order:\n// 1. `globalThis.crypto.randomUUID()` if present (browsers in secure\n// contexts, Node ≥ 19, Bun, Deno, Hermes ≥ 0.74 — modern path).\n// 2. `globalThis.crypto.getRandomValues()` + RFC 4122 v4 framing\n// (covers RN apps that ship `react-native-get-random-values`).\n// 3. `Math.random()` byte fill + RFC 4122 v4 framing (last resort —\n// enough entropy for in-process keys, never used as a security\n// primitive).\n//\n// This function is also exported as `safeUuid` so RN consumers can\n// reuse it for their own `generateIdempotencyKey` config if they\n// want, but the default already uses it — no setup required.\n\nexport function safeUuid(): string {\n const c = (\n globalThis as {\n crypto?: {\n randomUUID?: () => string;\n getRandomValues?: (a: Uint8Array) => Uint8Array;\n };\n }\n ).crypto;\n\n if (c?.randomUUID) return c.randomUUID();\n\n const bytes = new Uint8Array(16);\n if (c?.getRandomValues) {\n c.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n\n const hex: string[] = [];\n for (let i = 0; i < 16; i++) {\n hex.push(bytes[i]!.toString(16).padStart(2, '0'));\n }\n return (\n hex.slice(0, 4).join('') +\n '-' +\n hex.slice(4, 6).join('') +\n '-' +\n hex.slice(6, 8).join('') +\n '-' +\n hex.slice(8, 10).join('') +\n '-' +\n hex.slice(10).join('')\n );\n}\n","/**\n * Hosted poolse API URL. Used as the default for `PoolseConfig.apiUrl`\n * when you don't pass one — appropriate for the vast majority of\n * integrations that target the official poolse cloud. Self-hosted /\n * staging deployments override via the `apiUrl` field.\n */\nexport const POOLSE_API_URL = 'https://api.poolse.dev';\n\nimport type { PoolseUserProfile } from './types.js';\n\n/**\n * SDK configuration passed to `new Poolse(config)`.\n */\nexport interface PoolseConfig {\n /**\n * Base URL of the poolse REST API. Defaults to the hosted endpoint\n * at `https://api.poolse.dev`. Override only for self-hosted /\n * staging deployments. MUST NOT include the `/v1` path — the SDK\n * adds that itself.\n */\n apiUrl?: string;\n\n /**\n * Async hook the SDK calls every time it needs an `Authorization:\n * Bearer <jwt>` header. Most apps refresh the JWT from their own\n * backend here — the SDK never talks to poolse's `POST\n * /v1/users/:user_id/tokens` itself (that endpoint is API-key-authed\n * and lives on the Customer's BACKEND, not the End User's device).\n *\n * Return `null` to deliberately make an unauthenticated request — the\n * server will reject it, but the SDK won't error inside `getToken`.\n */\n getToken: () => Promise<string | null> | string | null;\n\n /**\n * Optional fetch override. Browsers and Node 22+ both ship a global\n * `fetch`, but tests can inject a mock here; bundlers in restricted\n * environments can supply a polyfill.\n */\n fetch?: typeof globalThis.fetch;\n\n /**\n * Retry budget for transient failures (network + 5xx + 429). Defaults\n * to 3 attempts after the initial request. Set to 0 to disable.\n */\n maxRetries?: number;\n\n /**\n * Base for the exponential backoff, in milliseconds. Each retry waits\n * `min(maxBackoffMs, baseBackoffMs * 2^attempt)` plus jitter, OR honours\n * the `Retry-After` header if present. Default 250 ms.\n */\n baseBackoffMs?: number;\n\n /** Hard cap on a single retry delay. Default 30_000 ms. */\n maxBackoffMs?: number;\n\n /**\n * Override the idempotency-key generator. Defaults to\n * `crypto.randomUUID()`. Most apps don't need to override this — the\n * generator is exposed mainly for deterministic tests.\n */\n generateIdempotencyKey?: () => string;\n\n /**\n * Override the WebSocket URL. Defaults to `apiUrl` with `http(s)://`\n * swapped to `ws(s)://`, suitable when the realtime gateway shares\n * its origin with the REST API. Set explicitly for split-host\n * deployments (`https://api.example.com` REST + `wss://realtime.example.com` WS).\n */\n wsUrl?: string;\n\n /**\n * Path the WebSocket is mounted on. Defaults to `/socket` — matches\n * `CaasRealtimeWeb.UserSocket`'s mount point.\n */\n socketPath?: string;\n\n /**\n * Called when the underlying socket encounters a non-fatal error\n * (Phoenix retries internally). Useful for surfacing reconnect\n * banners in the UI without coupling to socket internals.\n */\n onSocketError?: (err: Error) => void;\n\n /**\n * Resolve the tenant's user identifier (`external_id` — same string\n * you pass when minting JWTs and referencing users in\n * `member_external_ids`) to the customer's own user metadata\n * (display name + avatar). Called by `chat.users.get(externalId)`\n * and the `useUser(externalId)` React hook whenever a UI component\n * needs to render a participant.\n *\n * The SDK caches results in-memory and dedupes concurrent calls,\n * so a busy chat with 50 messages from 5 senders fires the\n * resolver 5 times — once per unique sender — not 50.\n *\n * Customers hit their OWN backend / store here, keyed by **their own\n * user id** (no poolse uuid mapping required):\n *\n * userResolver: async (externalId) => {\n * const u = await fetch(`/api/users/${externalId}`).then((r) => r.json());\n * return { displayName: u.full_name, avatarUrl: u.avatar_url };\n * }\n *\n * Sync returns are fine when the data's already in memory:\n *\n * userResolver: (externalId) => directory[externalId] ?? null\n *\n * Return `null` when the user can't be found — components fall back\n * to the external_id as a label and an initials avatar.\n */\n userResolver?: (\n externalId: string,\n ) => Promise<PoolseUserProfile | null> | PoolseUserProfile | null;\n}\n\n/** Internal resolved config — all the defaults filled in. */\nexport interface ResolvedConfig {\n apiUrl: string;\n getToken: PoolseConfig['getToken'];\n fetch: typeof globalThis.fetch;\n maxRetries: number;\n baseBackoffMs: number;\n maxBackoffMs: number;\n generateIdempotencyKey: () => string;\n wsUrl: string | undefined;\n socketPath: string;\n onSocketError: ((err: Error) => void) | undefined;\n userResolver: PoolseConfig['userResolver'];\n}\n\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_BASE_BACKOFF_MS = 250;\nconst DEFAULT_MAX_BACKOFF_MS = 30_000;\n\nexport function resolveConfig(config: PoolseConfig): ResolvedConfig {\n if (typeof config.getToken !== 'function') {\n throw new Error('Poolse: `getToken` is required and must be a function.');\n }\n\n const rawFetch = config.fetch ?? globalThis.fetch;\n if (typeof rawFetch !== 'function') {\n throw new Error(\n 'Poolse: no global `fetch` found. Provide one via `config.fetch` ' +\n '(Node <18 or a sandboxed runtime).',\n );\n }\n // Bind to globalThis so the browser's `fetch` keeps its native `this`\n // (it throws \"Illegal invocation\" when called with any other receiver,\n // and `this.config.fetch(...)` in the RestClient strips the binding).\n // A consumer-supplied `config.fetch` is also bound the same way for\n // consistency — if they want a specific receiver they should bind it\n // themselves before passing it in.\n const fetchFn = rawFetch.bind(globalThis);\n\n return {\n apiUrl: trimTrailingSlash(config.apiUrl ?? POOLSE_API_URL),\n getToken: config.getToken,\n fetch: fetchFn,\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n baseBackoffMs: config.baseBackoffMs ?? DEFAULT_BASE_BACKOFF_MS,\n maxBackoffMs: config.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS,\n generateIdempotencyKey: config.generateIdempotencyKey ?? defaultIdempotencyKey,\n wsUrl: config.wsUrl,\n socketPath: config.socketPath ?? '/socket',\n onSocketError: config.onSocketError,\n userResolver: config.userResolver,\n };\n}\n\nfunction trimTrailingSlash(s: string): string {\n return s.endsWith('/') ? s.slice(0, -1) : s;\n}\n\n// Delegates to `safeUuid` so the default works in every supported\n// runtime — browsers, Node, Bun, Deno, React Native (with or without\n// a crypto polyfill). Consumers can still override via\n// `config.generateIdempotencyKey` when they need a different source.\nimport { safeUuid } from './uuid.js';\n\nfunction defaultIdempotencyKey(): string {\n return safeUuid();\n}\n","// Typed error classes the SDK raises. Callers can `instanceof`-check to\n// decide whether to retry, prompt the user to re-login, etc. — the\n// alternative (parsing error.message strings) is brittle.\n\nimport type { ErrorEnvelope } from './types.js';\n\n/** Base for any error originating in the SDK. */\nexport class PoolseError extends Error {\n public override readonly name: string = 'PoolseError';\n\n constructor(message: string) {\n super(message);\n // Restore prototype chain across the TS down-level transform.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** fetch() rejected or the server returned no response at all. */\nexport class NetworkError extends PoolseError {\n public override readonly name: string = 'NetworkError';\n public override readonly cause: unknown;\n\n constructor(message: string, cause: unknown) {\n super(message);\n this.cause = cause;\n }\n}\n\n/**\n * Server returned a non-2xx status with the canonical error envelope.\n * `code` is poolse's snake_case error code (e.g. `\"invalid_user_token\"`).\n */\nexport class ApiError extends PoolseError {\n public override readonly name: string = 'ApiError';\n public readonly status: number;\n public readonly code: string;\n public readonly docUrl: string;\n public readonly details: Record<string, unknown> | undefined;\n\n constructor(status: number, envelope: ErrorEnvelope['error']) {\n super(`[${status}] ${envelope.code}: ${envelope.message}`);\n this.status = status;\n this.code = envelope.code;\n this.docUrl = envelope.doc_url;\n this.details = envelope.details;\n }\n}\n\n/**\n * 429 specifically. Surfaced as its own subclass so callers can back off\n * politely without parsing the generic ApiError.\n */\nexport class RateLimitedError extends ApiError {\n public override readonly name: string = 'RateLimitedError';\n public readonly retryAfterMs: number;\n\n constructor(envelope: ErrorEnvelope['error'], retryAfterMs: number) {\n super(429, envelope);\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/**\n * Auth failure (401, including expired/revoked tokens). Callers should\n * refresh the JWT (via `getToken`) and retry — the SDK does NOT do this\n * automatically, because the failure could also mean \"the user signed\n * out on another tab\" and silent re-auth would hide that.\n */\nexport class AuthError extends ApiError {\n public override readonly name: string = 'AuthError';\n\n constructor(envelope: ErrorEnvelope['error']) {\n super(401, envelope);\n }\n}\n","// poolse Realtime — thin wrapper over Phoenix.Socket.\n//\n// Responsibilities:\n// * Lazy connection: socket opens on the first `conversation()` / `user()` call.\n// * Auto-reconnect with exponential backoff (default Phoenix behavior is fine).\n// * Auto-rejoin channels on reconnect (Phoenix handles this for joined channels).\n// * Typed listener API: `conv.onMessage((msg) => …)`.\n// * Token refresh: re-pulls `getToken` on every (re)connect so a refreshed\n// JWT lands the next time without manual intervention.\n//\n// Designed to be `instanceof`-stable so React hooks can mount/unmount\n// without tearing down the socket — `Poolse` holds a single instance\n// and consumers get back the same handle for the same conversation id.\n\nimport { Socket } from 'phoenix';\nimport type { Channel } from 'phoenix';\n\nimport type { ResolvedConfig } from '../config.js';\nimport { PoolseError } from '../errors.js';\nimport type { TokenCache } from '../token-cache.js';\nimport type {\n ConversationCreatedEvent,\n MemberReadEvent,\n MentionEvent,\n MessageDeletedEvent,\n MessageNewEvent,\n MessageUpdatedEvent,\n PresenceSnapshot,\n ReactionEvent,\n RealtimeStatus,\n TypingEvent,\n Unsubscribe,\n} from './types.js';\n\ninterface RealtimeOptions {\n /**\n * WebSocket endpoint path (mounted in caas_realtime). Defaults to\n * `'/socket'` — matches the path served by `CaasRealtimeWeb.UserSocket`.\n */\n socketPath?: string;\n /**\n * Override the Phoenix-derived WebSocket URL. Use when the realtime\n * gateway lives on a different host than the REST API (most common\n * in prod: `https://api.example.com` for REST, `wss://realtime.example.com`\n * for WebSocket). When unset, the WS URL is derived from `apiUrl` by\n * swapping http(s) → ws(s).\n */\n wsUrl?: string;\n}\n\nexport class PoolseRealtime {\n private readonly config: ResolvedConfig;\n private readonly tokenCache: TokenCache;\n private readonly socketPath: string;\n private readonly wsUrl: string;\n\n private socket: Socket | null = null;\n private readonly conversations = new Map<string, ConversationChannel>();\n private userChannel: UserChannel | null = null;\n\n private status: RealtimeStatus = 'idle';\n private readonly statusListeners = new Set<(s: RealtimeStatus) => void>();\n\n constructor(config: ResolvedConfig, tokenCache: TokenCache, opts: RealtimeOptions = {}) {\n this.config = config;\n this.tokenCache = tokenCache;\n this.socketPath = opts.socketPath ?? '/socket';\n this.wsUrl = opts.wsUrl ?? deriveWsUrl(config.apiUrl);\n }\n\n /** Current connection status. */\n getStatus(): RealtimeStatus {\n return this.status;\n }\n\n /** Subscribe to connection-status changes. */\n onStatus(listener: (status: RealtimeStatus) => void): Unsubscribe {\n this.statusListeners.add(listener);\n return () => this.statusListeners.delete(listener);\n }\n\n /**\n * Open the socket (idempotent). Synchronous construction so callers\n * can join a channel on the next line; the underlying WebSocket\n * connects on the next tick once the JWT pre-fetch resolves.\n *\n * Phoenix.js invokes the `params` callback SYNCHRONOUSLY on every\n * (re)connect and does NOT await its return value — see\n * `phoenix/priv/static/phoenix.mjs::endPointURL`. So `params` has\n * to read a token that's already in hand. We:\n *\n * 1. Construct the Socket immediately (sets `this.socket` so\n * concurrent `conversation()` / `user()` callers can attach\n * channels — Phoenix buffers joins until the socket opens).\n * 2. Pre-fetch the JWT through `TokenCache`, which fills its\n * internal cache.\n * 3. Call `socket.connect()` so phoenix.js's first handshake reads\n * a primed `peekToken()`.\n *\n * On reconnect, Phoenix calls `params()` again; the cache is still\n * warm (default JWT exp ~1h, refresh window 30s) so `peekToken()`\n * returns the live token. When the token genuinely expires, our\n * REST 401 path invalidates the cache; the next reconnect's\n * `peekToken()` is `null` and the handshake intentionally fails so\n * the cache can re-fill on the next iteration.\n */\n connect(): void {\n if (this.socket) return;\n\n this.setStatus('connecting');\n\n const socket = new Socket(`${this.wsUrl}${this.socketPath}`, {\n params: () => ({ token: this.tokenCache.peekToken() ?? '' }),\n // Phoenix's default reconnect strategy: 10ms, 50ms, 100ms, 150ms,\n // 200ms, 250ms, 500ms, 1s, 2s, 5s — perfectly reasonable for chat.\n });\n\n socket.onOpen(() => this.setStatus('connected'));\n socket.onClose(() => {\n // `onClose` fires for both intentional disconnect and network drop.\n // Phoenix triggers reconnect on its own for the latter; we just\n // surface the transitional state to UIs.\n this.setStatus(this.status === 'closed' ? 'closed' : 'reconnecting');\n });\n socket.onError((err) => {\n // Errors don't tear down the socket — Phoenix retries internally.\n // Surface as `reconnecting` so the UI can show a banner.\n this.setStatus('reconnecting');\n this.config.onSocketError?.(new PoolseError(`socket error: ${String(err)}`));\n });\n\n this.socket = socket;\n\n // Pre-fetch the JWT, then open the socket. Channel joins called\n // between now and socket.connect() are buffered by Phoenix and\n // flushed on open, so callers don't need to await anything.\n void this.tokenCache\n .getToken()\n .catch((err) => {\n this.config.onSocketError?.(\n new PoolseError(`token fetch failed before socket open: ${String(err)}`),\n );\n })\n .finally(() => {\n socket.connect();\n });\n }\n\n /** Close the socket and tear down every joined channel. */\n disconnect(): void {\n this.setStatus('closed');\n this.conversations.forEach((c) => c._destroy());\n this.conversations.clear();\n this.userChannel?._destroy();\n this.userChannel = null;\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n }\n }\n\n /**\n * Subscribe to a conversation. Returns a typed handle with\n * `onMessage`, `onTyping`, etc. Reusing the same `id` returns the\n * same handle — re-subscribing doesn't open a second channel.\n */\n conversation(conversationId: string): ConversationChannel {\n const existing = this.conversations.get(conversationId);\n if (existing) return existing;\n\n this.connect();\n\n if (!this.socket) {\n throw new PoolseError('socket not initialised — call connect() first');\n }\n\n const channel = this.socket.channel(`conversation:${conversationId}`, {});\n const handle = new ConversationChannel(conversationId, channel);\n this.conversations.set(conversationId, handle);\n handle._join();\n return handle;\n }\n\n /**\n * Subscribe to the current user's `user:<id>` channel. Only the user\n * matching the JWT can join — poolse's UserChannel enforces this.\n */\n user(userId: string): UserChannel {\n if (this.userChannel) return this.userChannel;\n\n this.connect();\n\n if (!this.socket) {\n throw new PoolseError('socket not initialised — call connect() first');\n }\n\n const channel = this.socket.channel(`user:${userId}`, {});\n const handle = new UserChannel(userId, channel);\n this.userChannel = handle;\n handle._join();\n return handle;\n }\n\n /** Drop a conversation handle and leave the channel. */\n leave(conversationId: string): void {\n const handle = this.conversations.get(conversationId);\n if (!handle) return;\n handle._destroy();\n this.conversations.delete(conversationId);\n }\n\n private setStatus(status: RealtimeStatus): void {\n if (this.status === status) return;\n this.status = status;\n this.statusListeners.forEach((l) => l(status));\n }\n}\n\n// ── ConversationChannel ────────────────────────────────────────────────\n\nexport class ConversationChannel {\n public readonly conversationId: string;\n private readonly channel: Channel;\n\n // Map from event-name → set of listeners. We bind one Phoenix `.on(...)`\n // per event name (no matter how many JS listeners) and fan out\n // ourselves — much cheaper than re-binding on every subscription.\n private readonly listeners = new Map<string, Set<(payload: unknown) => void>>();\n\n // Phoenix.Presence pushes `presence_state` exactly ONCE right after\n // join, then `presence_diff` for every change. Late subscribers\n // (MemberList mounted after ConversationView has already joined the\n // channel) would otherwise never see the initial snapshot and stay\n // empty until somebody else joins or leaves. We cache the running\n // state here and replay it on subscribe.\n private presenceState: PresenceSnapshot = {};\n private presenceStateSeen = false;\n\n constructor(conversationId: string, channel: Channel) {\n this.conversationId = conversationId;\n this.channel = channel;\n\n // Bind presence handlers eagerly (not via the lazy `subscribe`\n // path) so the cache fills regardless of subscriber timing.\n channel.on('presence_state', (payload: unknown) => {\n this.presenceState = (payload ?? {}) as PresenceSnapshot;\n this.presenceStateSeen = true;\n const listeners = this.listeners.get('presence_state');\n if (listeners) listeners.forEach((l) => l(this.presenceState));\n });\n channel.on('presence_diff', (payload: unknown) => {\n const diff = (payload ?? {}) as { joins?: PresenceSnapshot; leaves?: PresenceSnapshot };\n const next: PresenceSnapshot = { ...this.presenceState };\n if (diff.joins) for (const [k, v] of Object.entries(diff.joins)) next[k] = v;\n if (diff.leaves) for (const k of Object.keys(diff.leaves)) delete next[k];\n this.presenceState = next;\n const listeners = this.listeners.get('presence_diff');\n if (listeners) listeners.forEach((l) => l(payload));\n });\n }\n\n /** New message pushed to the conversation. */\n onMessage(fn: (msg: MessageNewEvent) => void): Unsubscribe {\n return this.subscribe('message:new', fn as (p: unknown) => void);\n }\n\n /** Existing message edited by its sender. */\n onMessageUpdated(fn: (msg: MessageUpdatedEvent) => void): Unsubscribe {\n return this.subscribe('message:updated', fn as (p: unknown) => void);\n }\n\n /** Tombstone for a soft-deleted message. */\n onMessageDeleted(fn: (evt: MessageDeletedEvent) => void): Unsubscribe {\n return this.subscribe('message:deleted', fn as (p: unknown) => void);\n }\n\n onTypingStart(fn: (evt: TypingEvent) => void): Unsubscribe {\n return this.subscribe('typing:start', fn as (p: unknown) => void);\n }\n\n onTypingStop(fn: (evt: TypingEvent) => void): Unsubscribe {\n return this.subscribe('typing:stop', fn as (p: unknown) => void);\n }\n\n onReactionAdded(fn: (evt: ReactionEvent) => void): Unsubscribe {\n return this.subscribe('reaction:added', fn as (p: unknown) => void);\n }\n\n onReactionRemoved(fn: (evt: ReactionEvent) => void): Unsubscribe {\n return this.subscribe('reaction:removed', fn as (p: unknown) => void);\n }\n\n /**\n * A conversation member advanced their read cursor. Used to flip the\n * sender's read-receipt glyph from \"sent\" to \"read\" in real time.\n */\n onMemberRead(fn: (evt: MemberReadEvent) => void): Unsubscribe {\n return this.subscribe('member:read', fn as (p: unknown) => void);\n }\n\n onPresenceState(fn: (state: PresenceSnapshot) => void): Unsubscribe {\n let set = this.listeners.get('presence_state');\n if (!set) {\n set = new Set();\n this.listeners.set('presence_state', set);\n }\n set.add(fn as (p: unknown) => void);\n // Replay the cached presence_state to late subscribers — Phoenix\n // pushes it once on join and never resends, so MemberList mounted\n // after ConversationView would otherwise stay empty.\n if (this.presenceStateSeen) fn(this.presenceState);\n return () => {\n set.delete(fn as (p: unknown) => void);\n };\n }\n\n onPresenceDiff(fn: (diff: PresenceSnapshot) => void): Unsubscribe {\n return this.subscribe('presence_diff', fn as (p: unknown) => void);\n }\n\n /** Current presence snapshot for sync access — usually used in tests. */\n getPresenceState(): PresenceSnapshot {\n return this.presenceState;\n }\n\n /** Send a typing ping to the server. Debounced server-side. */\n sendTyping(): void {\n this.channel.push('typing', {});\n }\n\n /** @internal — called by `PoolseRealtime.conversation/1`. */\n _join(): void {\n this.channel.join();\n }\n\n /** @internal — called when the consumer leaves this conversation. */\n _destroy(): void {\n this.listeners.clear();\n this.channel.leave();\n }\n\n private subscribe(event: string, fn: (payload: unknown) => void): Unsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n this.channel.on(event, (payload: unknown) => {\n const listeners = this.listeners.get(event);\n if (listeners) listeners.forEach((l) => l(payload));\n });\n }\n set.add(fn);\n return () => {\n set.delete(fn);\n };\n }\n}\n\n// ── UserChannel ────────────────────────────────────────────────────────\n\nexport class UserChannel {\n public readonly userId: string;\n private readonly channel: Channel;\n private readonly mentionListeners = new Set<(evt: MentionEvent) => void>();\n private readonly conversationCreatedListeners = new Set<\n (evt: ConversationCreatedEvent) => void\n >();\n private mentionBound = false;\n private conversationCreatedBound = false;\n\n constructor(userId: string, channel: Channel) {\n this.userId = userId;\n this.channel = channel;\n }\n\n onMention(fn: (evt: MentionEvent) => void): Unsubscribe {\n if (!this.mentionBound) {\n this.mentionBound = true;\n this.channel.on('mention:new', (payload: unknown) => {\n this.mentionListeners.forEach((l) => l(payload as MentionEvent));\n });\n }\n this.mentionListeners.add(fn);\n return () => {\n this.mentionListeners.delete(fn);\n };\n }\n\n /**\n * Subscribe to \"you've been added to a conversation\" notifications.\n * Fires once per new membership — either because you created the\n * conversation, or because someone added you to an existing one.\n *\n * Payload is the full {@link Conversation} row so consumers can\n * prepend it to a local list without a refetch.\n */\n onConversationCreated(fn: (conv: ConversationCreatedEvent) => void): Unsubscribe {\n if (!this.conversationCreatedBound) {\n this.conversationCreatedBound = true;\n this.channel.on('conversation:created', (payload: unknown) => {\n this.conversationCreatedListeners.forEach((l) => l(payload as ConversationCreatedEvent));\n });\n }\n this.conversationCreatedListeners.add(fn);\n return () => {\n this.conversationCreatedListeners.delete(fn);\n };\n }\n\n /** @internal */\n _join(): void {\n this.channel.join();\n }\n\n /** @internal */\n _destroy(): void {\n this.mentionListeners.clear();\n this.conversationCreatedListeners.clear();\n this.channel.leave();\n }\n}\n\n// ── helpers ────────────────────────────────────────────────────────────\n\nfunction deriveWsUrl(apiUrl: string): string {\n // http(s):// → ws(s)://. Same host + port. The realtime endpoint\n // typically shares its origin with the REST API (single VPS) but\n // can be overridden via `RealtimeOptions.wsUrl`.\n return apiUrl.replace(/^http/, 'ws');\n}\n","// Attachment uploads use a presigned-URL flow:\n//\n// 1. POST /v1/attachments/upload-url → server returns a presigned\n// PUT URL + the headers the storage backend will require, plus a\n// `:pending` attachment row that the user can reference when\n// sending a message.\n// 2. The client PUTs the bytes directly to the storage backend\n// (Cloudflare R2 / S3). The bytes never touch poolse's API\n// server — this is fast AND keeps large blobs off the app tier.\n// 3. The PUT response Status 2xx flips the attachment row from\n// `:pending` to `:ready` (via a webhook the server subscribes\n// to, OR opportunistically on first download — implementation\n// detail).\n// 4. The client now sends a message referencing the attachment id.\n//\n// This module exposes that flow at two levels:\n// * `requestUpload(attrs)` — low-level, returns the presigned URL.\n// Use when you want full control of the PUT (custom progress,\n// resumable uploads, chunked transfers, RN's FileSystem API).\n// * `upload(input)` — high-level convenience that does step 1 + the\n// PUT in one call, returning the (now-ready) attachment row.\n// Works with browser File/Blob and any BodyInit-compatible value.\n\nimport type { RestClient } from '../rest-client.js';\nimport type {\n Attachment,\n AttachmentDownloadResponse,\n AttachmentUploadRequest,\n AttachmentUploadResponse,\n Uuid,\n} from '../types.js';\n\n/** Input accepted by {@link AttachmentsResource.upload}. */\nexport interface AttachmentUploadInput {\n /**\n * The bytes to upload. Browser: pass a `File` or `Blob`. Node /\n * Workers / Deno: a `Uint8Array`, `ArrayBuffer`, or any\n * `BodyInit`-compatible value the runtime's `fetch` accepts as a\n * PUT body.\n */\n body: BodyInit;\n /**\n * MIME type. MUST match what you pass as `content_type` on the\n * upload-URL request (the storage backend signs it into the URL —\n * a mismatch makes the PUT fail with 403).\n */\n contentType: string;\n /** Total bytes — must match the bytes you actually PUT. */\n byteSize: number;\n /** Surfaced in download UX so saved files keep a sensible name. */\n filename?: string;\n}\n\n/** Options accepted by every attachment method. */\nexport interface AttachmentOptions {\n signal?: AbortSignal;\n /**\n * Progress callback for `upload()`. Called periodically during the\n * PUT phase (NOT during the presigned-URL request — that's a small\n * JSON round-trip). When set, the SDK switches to XHR for the PUT\n * since the standard `fetch` doesn't expose upload progress events.\n *\n * Customers using a custom `config.fetch` (e.g. node-fetch polyfill)\n * lose progress reporting and the callback never fires — XHR is\n * a browser-only API.\n */\n onProgress?: (event: AttachmentProgressEvent) => void;\n}\n\nexport interface AttachmentProgressEvent {\n /** Bytes uploaded so far. */\n loaded: number;\n /** Total bytes — equals `input.byteSize` (passed back for convenience). */\n total: number;\n}\n\n/** Top-level `/v1/attachments` collection. */\nexport class AttachmentsResource {\n /**\n * The PUT to the presigned URL bypasses the SDK's authenticated\n * REST client (presigned URLs encode their own auth and MUST NOT\n * receive an `Authorization` header). It still respects\n * `config.fetch` if the customer provided one — required for tests\n * with a mock fetch, and for runtimes where `globalThis.fetch` is\n * not the right transport.\n */\n constructor(\n private readonly client: RestClient,\n private readonly fetchFn: typeof globalThis.fetch,\n ) {}\n\n /**\n * Step 1 of an upload — request a presigned PUT URL. Use this when\n * you want to drive the PUT yourself (e.g. resumable uploads,\n * React Native FileSystem). For the common case prefer\n * {@link upload}, which does both steps for you.\n */\n requestUpload(\n attrs: AttachmentUploadRequest,\n opts: AttachmentOptions = {},\n ): Promise<AttachmentUploadResponse> {\n return this.client.request<AttachmentUploadResponse>({\n method: 'POST',\n path: '/v1/attachments/upload-url',\n body: attrs,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n\n /**\n * One-call upload: request a presigned URL, PUT the bytes to it,\n * return the attachment row. After this resolves the attachment is\n * ready to be referenced from a message send.\n *\n * ```ts\n * // Browser <input type=\"file\">:\n * const file = inputEl.files![0]!;\n * const att = await chat.attachments.upload({\n * body: file,\n * contentType: file.type,\n * byteSize: file.size,\n * filename: file.name,\n * });\n * await chat.conversations.one(convId).messages.send({\n * body: 'Look at this!',\n * custom_data: { attachment_id: att.id },\n * });\n * ```\n *\n * Note: the PUT uses the runtime's bare `fetch` (NOT the SDK's\n * authenticated REST client) — presigned URLs already encode their\n * own auth and MUST NOT receive an `Authorization` header.\n */\n async upload(input: AttachmentUploadInput, opts: AttachmentOptions = {}): Promise<Attachment> {\n const req: AttachmentUploadRequest = {\n content_type: input.contentType,\n byte_size: input.byteSize,\n ...(input.filename !== undefined ? { original_filename: input.filename } : {}),\n };\n\n const { attachment, upload } = await this.requestUpload(req, opts);\n\n // Progress reporting requires XHR — `fetch` doesn't expose upload\n // events. Drop to XHR only when the caller actually wants progress;\n // otherwise stick with `fetch` (handles streams + Node polyfills\n // that XHR doesn't).\n if (opts.onProgress && typeof XMLHttpRequest !== 'undefined') {\n await xhrPut(upload.url, upload.method.toUpperCase(), upload.headers, input.body, {\n byteSize: input.byteSize,\n onProgress: opts.onProgress,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n return attachment;\n }\n\n const putInit: RequestInit = {\n method: upload.method.toUpperCase(),\n headers: upload.headers,\n body: input.body,\n ...(opts.signal ? { signal: opts.signal } : {}),\n };\n\n const res = await this.fetchFn(upload.url, putInit);\n if (!res.ok) {\n throw new Error(\n `Poolse: presigned upload PUT failed (${res.status}) for attachment ${attachment.id}`,\n );\n }\n return attachment;\n }\n\n /** Returns a handle for further operations on a single attachment. */\n one(id: Uuid): AttachmentHandle {\n return new AttachmentHandle(this.client, id);\n }\n}\n\n/** Wraps an attachment id for download-url + delete. */\nexport class AttachmentHandle {\n constructor(\n private readonly client: RestClient,\n public readonly id: Uuid,\n ) {}\n\n /**\n * Request a presigned GET URL (~1h TTL). Conversation-member-gated\n * server-side. Useful when rendering files in chat: cache the URL\n * client-side until close to expiry, then re-fetch.\n */\n downloadUrl(opts: AttachmentOptions = {}): Promise<AttachmentDownloadResponse> {\n return this.client.request<AttachmentDownloadResponse>({\n method: 'GET',\n path: `/v1/attachments/${this.id}/download-url`,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n\n /**\n * Delete the attachment row + best-effort bucket object delete.\n * Authz: uploader (while still `:pending`) or message-sender / conv\n * owner-admin (once linked).\n */\n delete(opts: AttachmentOptions = {}): Promise<void> {\n return this.client.request<void>({\n method: 'DELETE',\n path: `/v1/attachments/${this.id}`,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n}\n\n/**\n * XHR-based PUT with upload progress events. Used by `upload()` when\n * the caller passes an `onProgress` callback — `fetch` doesn't\n * expose upload progress.\n *\n * Browser-only: tests + Node polyfills don't define XMLHttpRequest,\n * so the caller path that selects XHR vs fetch checks\n * `typeof XMLHttpRequest !== 'undefined'` upstream.\n */\nfunction xhrPut(\n url: string,\n method: string,\n headers: Record<string, string>,\n body: BodyInit,\n opts: {\n byteSize: number;\n onProgress: (e: AttachmentProgressEvent) => void;\n signal?: AbortSignal;\n },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open(method, url);\n for (const [k, v] of Object.entries(headers)) {\n try {\n xhr.setRequestHeader(k, v);\n } catch {\n // Some browsers refuse to set forbidden headers (Content-Length,\n // etc.). The presigned URL still works without them.\n }\n }\n xhr.upload.onprogress = (e) => {\n // `lengthComputable` is true on R2 / S3; fall back to byteSize\n // for older browsers that don't expose `total`.\n const total = e.lengthComputable ? e.total : opts.byteSize;\n opts.onProgress({ loaded: e.loaded, total });\n };\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) resolve();\n else\n reject(new Error(`Poolse: presigned upload PUT failed (${xhr.status} ${xhr.statusText})`));\n };\n xhr.onerror = () => reject(new Error('Poolse: presigned upload PUT failed (network error)'));\n xhr.onabort = () => {\n // Surface as DOMException('AbortError') so callers can detect.\n reject(new DOMException('Upload aborted', 'AbortError'));\n };\n if (opts.signal) {\n if (opts.signal.aborted) {\n xhr.abort();\n return;\n }\n opts.signal.addEventListener('abort', () => xhr.abort(), { once: true });\n }\n // body must be XHR-compatible: Blob, File, FormData, string,\n // ArrayBufferView. Customers using a streaming body via fetch\n // wouldn't pass `onProgress` (we'd be on the fetch path).\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n","import type { RestClient } from '../rest-client.js';\nimport type {\n Message,\n MessageCreateRequest,\n MessageList,\n MessageUpdateRequest,\n ReactionRequest,\n Uuid,\n} from '../types.js';\nimport { safeUuid } from '../uuid.js';\n\n/** Per-conversation message collection: send, list, mark-read. */\nexport class ConversationMessages {\n constructor(\n private readonly client: RestClient,\n private readonly conversationId: Uuid,\n ) {}\n\n list(opts: { limit?: number; before?: number } = {}, signal?: AbortSignal): Promise<MessageList> {\n return this.client.request<MessageList>({\n method: 'GET',\n path: `/v1/conversations/${this.conversationId}/messages`,\n query: {\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n ...(opts.before !== undefined ? { before: opts.before } : {}),\n },\n ...(signal ? { signal } : {}),\n });\n }\n\n /**\n * Send a message to this conversation.\n *\n * If `attrs.id` is omitted the SDK generates a v4 UUID and uses it\n * as both the wire-level idempotency key AND the literal message.id\n * the server stores. Two side-effects that make a real-time UI\n * trivial:\n *\n * * Resending the same `id` (e.g. a network-retry) returns the\n * ORIGINAL message instead of inserting a duplicate.\n * * The realtime `message:new` broadcast carries this same id,\n * so an optimistic UI can pre-render the row under the final id\n * and dedup by id alone — no client/server id swap needed.\n *\n * Pass an explicit `attrs.id` only when you generated it yourself\n * upstream (e.g. you already render an optimistic row in your hook\n * and want the server to confirm under the same key).\n */\n send(attrs: MessageCreateRequest, signal?: AbortSignal): Promise<Message> {\n const body: MessageCreateRequest =\n attrs.id !== undefined ? attrs : { ...attrs, id: generateClientMessageId() };\n return this.client.request<Message>({\n method: 'POST',\n path: `/v1/conversations/${this.conversationId}/messages`,\n body,\n ...(signal ? { signal } : {}),\n });\n }\n\n markRead(messageId: Uuid, signal?: AbortSignal): Promise<void> {\n return this.client.request<void>({\n method: 'POST',\n path: `/v1/conversations/${this.conversationId}/read`,\n body: { message_id: messageId },\n ...(signal ? { signal } : {}),\n });\n }\n}\n\n/** Per-message operations: edit, delete, react, list replies. */\nexport class MessageHandle {\n constructor(\n private readonly client: RestClient,\n public readonly id: Uuid,\n ) {}\n\n update(attrs: MessageUpdateRequest, signal?: AbortSignal): Promise<Message> {\n return this.client.request<Message>({\n method: 'PATCH',\n path: `/v1/messages/${this.id}`,\n body: attrs,\n ...(signal ? { signal } : {}),\n });\n }\n\n delete(signal?: AbortSignal): Promise<void> {\n return this.client.request<void>({\n method: 'DELETE',\n path: `/v1/messages/${this.id}`,\n ...(signal ? { signal } : {}),\n });\n }\n\n replies(\n opts: { limit?: number; after?: number } = {},\n signal?: AbortSignal,\n ): Promise<MessageList> {\n return this.client.request<MessageList>({\n method: 'GET',\n path: `/v1/messages/${this.id}/replies`,\n query: {\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n ...(opts.after !== undefined ? { after: opts.after } : {}),\n },\n ...(signal ? { signal } : {}),\n });\n }\n\n addReaction(emoji: string, signal?: AbortSignal): Promise<Message> {\n const body: ReactionRequest = { emoji };\n return this.client.request<Message>({\n method: 'POST',\n path: `/v1/messages/${this.id}/reactions`,\n body,\n ...(signal ? { signal } : {}),\n });\n }\n\n removeReaction(emoji: string, signal?: AbortSignal): Promise<Message> {\n return this.client.request<Message>({\n method: 'DELETE',\n path: `/v1/messages/${this.id}/reactions/${encodeURIComponent(emoji)}`,\n ...(signal ? { signal } : {}),\n });\n }\n}\n\n/** Top-level `/v1/messages` namespace — accessed via `chat.messages(id)`. */\nexport class MessagesResource {\n constructor(private readonly client: RestClient) {}\n\n one(id: Uuid): MessageHandle {\n return new MessageHandle(this.client, id);\n }\n}\n\n/**\n * Client-side message id generator. Delegates to the SDK's `safeUuid`\n * which works in every supported runtime (browsers, Node ≥ 19, RN /\n * Hermes — with or without a crypto polyfill). Server enforces real\n * auth + dedup; in-process collisions are effectively impossible at\n * any practical message volume.\n */\nfunction generateClientMessageId(): Uuid {\n return safeUuid();\n}\n","import type { RestClient } from '../rest-client.js';\nimport { ConversationMessages } from './messages.js';\nimport type {\n Conversation,\n ConversationCreateRequest,\n ConversationList,\n ConversationUpdateRequest,\n MemberRole,\n Membership,\n MembershipList,\n Uuid,\n} from '../types.js';\n\n/** Optional knobs accepted by every member-add call. */\nexport interface AddMemberOptions {\n /** Membership role — defaults to `\"member\"` server-side. */\n role?: MemberRole;\n /** AbortSignal for caller-driven cancellation. */\n signal?: AbortSignal;\n}\n\n/** Wraps a single conversation by id — used as the entry point for sub-resources. */\nexport class ConversationHandle {\n /**\n * Message ops scoped to this conversation: `list`, `send`, `markRead`.\n * Lazy: constructed on first access so an idle handle stays cheap.\n */\n public readonly messages: ConversationMessages;\n\n constructor(\n private readonly client: RestClient,\n public readonly id: Uuid,\n ) {\n this.messages = new ConversationMessages(this.client, this.id);\n }\n\n show(signal?: AbortSignal): Promise<Conversation> {\n return this.client.request<Conversation>({\n method: 'GET',\n path: `/v1/conversations/${this.id}`,\n ...(signal ? { signal } : {}),\n });\n }\n\n update(attrs: ConversationUpdateRequest, signal?: AbortSignal): Promise<Conversation> {\n return this.client.request<Conversation>({\n method: 'PATCH',\n path: `/v1/conversations/${this.id}`,\n body: attrs,\n ...(signal ? { signal } : {}),\n });\n }\n\n // ── members ────────────────────────────────────────────────────────────\n\n listMembers(signal?: AbortSignal): Promise<MembershipList> {\n return this.client.request<MembershipList>({\n method: 'GET',\n path: `/v1/conversations/${this.id}/members`,\n ...(signal ? { signal } : {}),\n });\n }\n\n /**\n * Add multiple users to this conversation in one round-trip.\n *\n * `externalIds` are the stable customer-side identifiers you passed\n * to `POST /v1/users` when creating each user — the server resolves\n * them to internal user_ids and creates one membership row per id.\n *\n * Requires `:manage_members` on this conversation (owner or admin).\n *\n * ```ts\n * await chat.conversations.one(convId).addMembers(['alice', 'bob']);\n * ```\n */\n addMembers(externalIds: string[], opts: AddMemberOptions = {}): Promise<MembershipList> {\n return this.client.request<MembershipList>({\n method: 'POST',\n path: `/v1/conversations/${this.id}/members`,\n body: {\n external_ids: externalIds,\n ...(opts.role !== undefined ? { role: opts.role } : {}),\n },\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n }\n\n /**\n * Add a single user. Convenience wrapper around {@link addMembers}\n * that unwraps the returned list to the single membership row.\n *\n * ```ts\n * const m = await chat.conversations.one(convId).addMember('alice');\n * ```\n */\n async addMember(externalId: string, opts: AddMemberOptions = {}): Promise<Membership> {\n const list = await this.addMembers([externalId], opts);\n const row = list.data[0];\n if (!row) {\n // Server should always return one membership per external_id;\n // empty data here means a contract violation, not a missing user\n // (the latter surfaces as a 422 user_not_found error).\n throw new Error('Poolse: addMember succeeded but server returned no membership row.');\n }\n return row;\n }\n\n removeMember(userId: Uuid, signal?: AbortSignal): Promise<void> {\n return this.client.request<void>({\n method: 'DELETE',\n path: `/v1/conversations/${this.id}/members/${userId}`,\n ...(signal ? { signal } : {}),\n });\n }\n}\n\n/** Top-level `/v1/conversations` collection. */\nexport class ConversationsResource {\n constructor(private readonly client: RestClient) {}\n\n list(signal?: AbortSignal): Promise<ConversationList> {\n return this.client.request<ConversationList>({\n method: 'GET',\n path: '/v1/conversations',\n ...(signal ? { signal } : {}),\n });\n }\n\n create(attrs: ConversationCreateRequest, signal?: AbortSignal): Promise<Conversation> {\n return this.client.request<Conversation>({\n method: 'POST',\n path: '/v1/conversations',\n body: attrs,\n ...(signal ? { signal } : {}),\n });\n }\n\n /** Returns a handle for further operations on a single conversation. */\n one(id: Uuid): ConversationHandle {\n return new ConversationHandle(this.client, id);\n }\n}\n","import type { RestClient } from '../rest-client.js';\nimport type { Me } from '../types.js';\n\n/** `/v1/me` — the End-User identity behind the presented JWT. */\nexport class MeResource {\n constructor(private readonly client: RestClient) {}\n\n /** GET /v1/me */\n show(signal?: AbortSignal): Promise<Me> {\n return this.client.request<Me>({\n method: 'GET',\n path: '/v1/me',\n ...(signal ? { signal } : {}),\n });\n }\n}\n","// Customer-supplied user metadata, cached — keyed by the tenant's\n// `external_id` (the same string the customer passes when minting\n// JWTs or referencing users in member lists).\n//\n// poolse has no concept of a \"user profile\" — names and avatars\n// live in the customer's app, not ours. `UsersResource` wraps the\n// `userResolver` the customer passed into `PoolseConfig` with:\n//\n// * an in-memory cache keyed by external_id\n// * concurrent-request dedup (10 bubbles asking for the same user\n// on the same tick fire ONE resolver call)\n// * subscription so React (or any other UI) can re-render when a\n// pending lookup resolves\n//\n// Negative results (resolver returned null, threw, or the customer\n// didn't configure a resolver at all) are cached too so we don't\n// retry on every mount. Customers who want to invalidate the cache\n// can call `chat.users.invalidate(externalId)` after their backend's\n// user data changes (or `invalidateAll()` after a sign-out / tenant\n// swap).\n\nimport type { ResolvedConfig } from '../config.js';\nimport type { PoolseUserProfile } from '../types.js';\n\ntype Listener = () => void;\n\nexport class UsersResource {\n private readonly cache = new Map<string, PoolseUserProfile | null>();\n private readonly pending = new Map<string, Promise<PoolseUserProfile | null>>();\n private readonly listeners = new Map<string, Set<Listener>>();\n\n constructor(private readonly config: ResolvedConfig) {}\n\n /**\n * Get the cached value if present. Returns `undefined` to mean\n * \"not in cache yet\" (different from `null`, which means \"resolver\n * ran and the user wasn't found\").\n */\n peek(externalId: string): PoolseUserProfile | null | undefined {\n return this.cache.get(externalId);\n }\n\n /**\n * Resolve a user, hitting the customer's `userResolver` on cache\n * miss. Concurrent calls for the same external_id share one Promise.\n */\n async get(externalId: string): Promise<PoolseUserProfile | null> {\n if (this.cache.has(externalId)) {\n return this.cache.get(externalId) ?? null;\n }\n const existingPending = this.pending.get(externalId);\n if (existingPending) return existingPending;\n\n const resolver = this.config.userResolver;\n if (!resolver) {\n this.cache.set(externalId, null);\n this.notify(externalId);\n return null;\n }\n\n const promise = Promise.resolve()\n .then(() => resolver(externalId))\n .then(\n (profile) => {\n this.cache.set(externalId, profile ?? null);\n this.pending.delete(externalId);\n this.notify(externalId);\n return profile ?? null;\n },\n (err: unknown) => {\n // Resolver errors are treated as \"user not found\" — log\n // once and cache the null so we don't hammer the failing\n // endpoint on every re-render. Customers can call\n // `invalidate(externalId)` to retry.\n console.error('[poolse] userResolver failed for', externalId, err);\n this.cache.set(externalId, null);\n this.pending.delete(externalId);\n this.notify(externalId);\n return null;\n },\n );\n this.pending.set(externalId, promise);\n return promise;\n }\n\n /**\n * Subscribe to changes for a single external_id. The listener fires\n * when the resolver lands (or when the entry is invalidated).\n * Returns an unsubscribe.\n *\n * `useUser` in @poolse/react uses this with `useSyncExternalStore`.\n */\n subscribe(externalId: string, listener: Listener): () => void {\n let set = this.listeners.get(externalId);\n if (!set) {\n set = new Set();\n this.listeners.set(externalId, set);\n }\n set.add(listener);\n return () => {\n set?.delete(listener);\n };\n }\n\n /** Drop a single cached entry — next `get` re-fetches via the resolver. */\n invalidate(externalId: string): void {\n this.cache.delete(externalId);\n this.pending.delete(externalId);\n this.notify(externalId);\n }\n\n /**\n * Drop the entire cache. Use after a sign-out, tenant swap, or any\n * other event that invalidates every cached profile (e.g., the\n * customer just renamed every user in bulk).\n */\n invalidateAll(): void {\n this.cache.clear();\n this.pending.clear();\n for (const externalId of this.listeners.keys()) {\n this.notify(externalId);\n }\n }\n\n private notify(externalId: string): void {\n const set = this.listeners.get(externalId);\n if (!set) return;\n for (const l of set) l();\n }\n}\n","// Low-level fetch wrapper.\n//\n// Responsibilities:\n// * Apply the Bearer JWT from `config.getToken()`.\n// * Auto-generate an `Idempotency-Key` for non-GET requests so poolse\n// can dedupe retries safely.\n// * Retry on transient failures: network errors, 5xx, 429.\n// - Backoff = max(Retry-After header, exponential with jitter).\n// - 401/4xx-other are NOT retried (they won't change on repeat).\n// * Translate non-2xx into typed `ApiError` subclasses.\n\nimport type { ResolvedConfig } from './config.js';\nimport { ApiError, AuthError, NetworkError, RateLimitedError } from './errors.js';\nimport type { TokenCache } from './token-cache.js';\nimport type { ErrorEnvelope } from './types.js';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n\nexport interface RequestOptions {\n method: HttpMethod;\n path: string;\n /** JSON-serialisable body for non-GETs. Omit for GET/DELETE. */\n body?: unknown;\n /** Query string params; values are stringified, nullish entries dropped. */\n query?: Record<string, string | number | boolean | null | undefined>;\n /**\n * Idempotency-Key override. Defaults to a fresh UUID for non-GETs.\n * Pass `null` to deliberately omit the header (e.g. when the caller's\n * own retry logic supplies a deterministic one).\n */\n idempotencyKey?: string | null;\n /**\n * Per-request override for total retry budget. Defaults to\n * `config.maxRetries`.\n */\n maxRetries?: number;\n /** AbortSignal for caller-driven cancellation. */\n signal?: AbortSignal;\n}\n\nconst NON_BODY_METHODS: ReadonlySet<HttpMethod> = new Set(['GET', 'DELETE']);\nconst IDEMPOTENT_METHODS: ReadonlySet<HttpMethod> = new Set(['GET']);\n\nexport class RestClient {\n private readonly config: ResolvedConfig;\n private readonly tokenCache: TokenCache;\n\n constructor(config: ResolvedConfig, tokenCache: TokenCache) {\n this.config = config;\n this.tokenCache = tokenCache;\n }\n\n async request<T>(opts: RequestOptions): Promise<T> {\n const url = this.buildUrl(opts.path, opts.query);\n const maxRetries = opts.maxRetries ?? this.config.maxRetries;\n const idempotencyKey = this.resolveIdempotencyKey(opts);\n\n let attempt = 0;\n let triedAuthRefresh = false;\n\n // The retry loop runs up to `maxRetries + 1` total attempts. Each\n // failed attempt either returns (giving up) or waits per the backoff.\n for (;;) {\n const body = opts.body === undefined ? undefined : JSON.stringify(opts.body);\n const headers = await this.buildHeaders(opts.method, idempotencyKey, body !== undefined);\n\n let response: Response;\n try {\n const init: RequestInit = { method: opts.method, headers };\n if (body !== undefined) init.body = body;\n if (opts.signal) init.signal = opts.signal;\n response = await this.config.fetch(url, init);\n } catch (err) {\n // AbortError is caller intent (component unmount, conv switch,\n // StrictMode double-effect). Re-throw AS-IS so callers can\n // distinguish it from a real network failure. Wrapping it as\n // NetworkError previously caused hooks like useMembers to fall\n // into their \"failed to load\" branch whenever the aborted fetch\n // resolved after a newly-mounted fetcher already cleared state.\n if (err instanceof DOMException && err.name === 'AbortError') {\n throw err;\n }\n if (attempt < maxRetries && isRetryableNetworkError(err)) {\n await sleep(this.backoffDelay(attempt));\n attempt += 1;\n continue;\n }\n throw new NetworkError('Network request failed', err);\n }\n\n if (response.status >= 200 && response.status < 300) {\n return (await parseJsonOrNull(response)) as T;\n }\n\n // 401: a cached token can race a clock-skew expiry or a server\n // restart. Invalidate the token cache and retry ONCE — if the\n // refreshed token also gets 401, the credentials are genuinely\n // bad and we surface it. Doesn't count against the per-request\n // retry budget (auth refresh isn't a \"transient\" failure in the\n // same sense as 5xx/network).\n if (response.status === 401) {\n if (!triedAuthRefresh) {\n this.tokenCache.invalidate();\n triedAuthRefresh = true;\n continue;\n }\n throw new AuthError(await parseEnvelope(response));\n }\n\n // 429: retry after the larger of (Retry-After, exponential backoff).\n if (response.status === 429) {\n const envelope = await parseEnvelope(response);\n const retryAfterMs = retryAfterHeaderMs(response);\n if (attempt < maxRetries) {\n await sleep(Math.max(retryAfterMs ?? 0, this.backoffDelay(attempt)));\n attempt += 1;\n continue;\n }\n throw new RateLimitedError(envelope, retryAfterMs ?? 0);\n }\n\n // 5xx: retry if we have budget and the method is safe to retry.\n // Non-idempotent methods (POST/PATCH/PUT/DELETE) are STILL retried\n // here because the Idempotency-Key header makes duplicates safe.\n if (response.status >= 500 && attempt < maxRetries) {\n await sleep(this.backoffDelay(attempt));\n attempt += 1;\n continue;\n }\n\n throw new ApiError(response.status, await parseEnvelope(response));\n }\n }\n\n // ── helpers ────────────────────────────────────────────────────────────\n\n private buildUrl(path: string, query?: RequestOptions['query']): string {\n const base = `${this.config.apiUrl}${path.startsWith('/') ? path : `/${path}`}`;\n if (!query) return base;\n\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null) {\n params.append(k, String(v));\n }\n }\n const qs = params.toString();\n return qs ? `${base}?${qs}` : base;\n }\n\n private async buildHeaders(\n method: HttpMethod,\n idempotencyKey: string | null,\n hasBody: boolean,\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n\n if (hasBody) headers['Content-Type'] = 'application/json';\n\n const token = await this.config.getToken();\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n if (!IDEMPOTENT_METHODS.has(method) && idempotencyKey) {\n headers['Idempotency-Key'] = idempotencyKey;\n }\n\n return headers;\n }\n\n private resolveIdempotencyKey(opts: RequestOptions): string | null {\n if (opts.idempotencyKey === null) return null;\n if (opts.idempotencyKey) return opts.idempotencyKey;\n if (IDEMPOTENT_METHODS.has(opts.method)) return null;\n return this.config.generateIdempotencyKey();\n }\n\n private backoffDelay(attempt: number): number {\n const exp = this.config.baseBackoffMs * 2 ** attempt;\n const capped = Math.min(this.config.maxBackoffMs, exp);\n // Full jitter: pick uniformly in [0, capped]. Avoids retry-storm\n // synchronization when many clients fail at once.\n return Math.floor(Math.random() * capped);\n }\n}\n\nfunction _unusedNonBodyMethods(): unknown {\n return NON_BODY_METHODS;\n}\n\nasync function parseEnvelope(response: Response): Promise<ErrorEnvelope['error']> {\n try {\n const json = (await response.json()) as ErrorEnvelope;\n if (json?.error?.code) return json.error;\n } catch {\n // fall through to a synthetic envelope below\n }\n return {\n code: 'unknown_error',\n message: `HTTP ${response.status}`,\n doc_url: '',\n };\n}\n\nasync function parseJsonOrNull(response: Response): Promise<unknown> {\n if (response.status === 204) return null;\n const text = await response.text();\n if (!text) return null;\n return JSON.parse(text);\n}\n\nfunction retryAfterHeaderMs(response: Response): number | null {\n const raw = response.headers.get('retry-after');\n if (!raw) return null;\n const seconds = Number.parseInt(raw, 10);\n return Number.isFinite(seconds) ? seconds * 1000 : null;\n}\n\nfunction isRetryableNetworkError(err: unknown): boolean {\n // Abort is caller intent — never retry.\n if (err instanceof DOMException && err.name === 'AbortError') return false;\n // Everything else (TypeError from fetch failure, etc.) is fair game.\n return true;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// Caches the JWT returned by the consumer's `getToken` callback so the\n// SDK doesn't call back on every REST request and every WebSocket\n// connect. Without this, mounting a single conversation view fires\n// ~4-5 `getToken` calls per render — and every parent re-render that\n// (accidentally) hands the provider a new config object multiplies\n// that out, turning a passive UI into a token-fetch storm.\n//\n// The cache:\n// * Decodes the `exp` claim (no signature verification — that's the\n// server's job) and returns the cached token until `exp - 30s`.\n// * Coalesces concurrent calls: if a refresh is in flight, every\n// caller awaits the same promise — one network round-trip even\n// when 4 hooks mount simultaneously.\n// * Can be `invalidate()`-d from the outside (e.g. by the REST client\n// after a 401) so the next call always re-fetches.\n// * Treats opaque (non-JWT) tokens as cacheable for `FALLBACK_TTL_MS`\n// — long enough to absorb a mount burst, short enough that opaque\n// rotations still land within a few seconds.\n// * NEVER caches `null` (an unauthenticated request is a choice the\n// consumer makes per call, not a state to memoise).\n\nimport type { PoolseConfig } from './config.js';\n\ntype Fetcher = PoolseConfig['getToken'];\n\ninterface GetTokenOptions {\n /** Bypass the cache and force a fresh call to the consumer's `getToken`. */\n forceRefresh?: boolean;\n}\n\nconst REFRESH_BUFFER_MS = 30_000;\nconst FALLBACK_TTL_MS = 60_000;\n\nexport class TokenCache {\n private token: string | null = null;\n private expMs: number | null = null;\n private inFlight: Promise<string | null> | null = null;\n\n constructor(private readonly fetcher: Fetcher) {}\n\n /**\n * Synchronously return the cached token without triggering a fetch.\n * Returns `null` if the cache is empty OR if the cached token is\n * within the refresh window (treating near-expiry tokens as stale\n * keeps the realtime layer from handshaking with an about-to-expire\n * JWT when a refresh is already due).\n *\n * Exists for callers like Phoenix.js's `params` callback that the\n * library invokes synchronously and does NOT await — see\n * `phoenix/priv/static/phoenix.mjs::endPointURL()`.\n */\n peekToken(): string | null {\n if (this.token === null || this.expMs === null) return this.token;\n return Date.now() < this.expMs - REFRESH_BUFFER_MS ? this.token : null;\n }\n\n async getToken(opts: GetTokenOptions = {}): Promise<string | null> {\n if (opts.forceRefresh) this.invalidate();\n\n const now = Date.now();\n if (this.token && this.expMs !== null && now < this.expMs - REFRESH_BUFFER_MS) {\n return this.token;\n }\n\n if (this.inFlight) return this.inFlight;\n\n this.inFlight = this.fetchAndStore().finally(() => {\n this.inFlight = null;\n });\n return this.inFlight;\n }\n\n invalidate(): void {\n this.token = null;\n this.expMs = null;\n // Don't clear `inFlight` — let the existing fetch resolve normally;\n // its result just won't be cached (the freshness check above will\n // miss it). The next call after `invalidate()` will be served by\n // that same in-flight promise if it's still pending.\n }\n\n private async fetchAndStore(): Promise<string | null> {\n const token = await this.fetcher();\n if (!token) {\n this.token = null;\n this.expMs = null;\n return null;\n }\n\n const expSec = parseJwtExp(token);\n if (expSec !== null) {\n const expMs = expSec * 1000;\n // Already expired by the time it reached us — cache for a short\n // fallback so the burst doesn't hammer, but don't trust the exp.\n // The next REST 401 will invalidate and we'll re-fetch.\n this.expMs = expMs <= Date.now() ? Date.now() + FALLBACK_TTL_MS : expMs;\n } else {\n this.expMs = Date.now() + FALLBACK_TTL_MS;\n }\n this.token = token;\n return token;\n }\n}\n\n// JWT payload base64url-decode → JSON parse → pluck `exp`. Returns\n// null if the token isn't a JWT, the payload is unreadable, or `exp`\n// is missing/non-numeric. Never throws — bad tokens just go uncached.\nfunction parseJwtExp(token: string): number | null {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n\n try {\n const json = decodeBase64Url(parts[1] as string);\n const payload = JSON.parse(json) as { exp?: unknown };\n return typeof payload.exp === 'number' && Number.isFinite(payload.exp) ? payload.exp : null;\n } catch {\n return null;\n }\n}\n\nfunction decodeBase64Url(s: string): string {\n // JWT uses base64url (RFC 7515 §2): `-` and `_` instead of `+` and\n // `/`, no padding. Translate back to standard base64 and re-pad.\n const b64 = s.replace(/-/g, '+').replace(/_/g, '/');\n const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4);\n if (typeof atob === 'function') return atob(padded);\n // Node fallback (older runtimes without global atob). The SDK's\n // minimum target is Node 18 where atob is global, but keep this for\n // safety / SSR environments that polyfill differently.\n const g = globalThis as {\n Buffer?: { from(s: string, e: string): { toString(e: string): string } };\n };\n if (g.Buffer) return g.Buffer.from(padded, 'base64').toString('binary');\n throw new Error('No base64 decoder available');\n}\n","// Public entry-point for the SDK. One instance per End User session.\n// Re-create when the user signs out or rotates tenants.\n\nimport type { PoolseConfig, ResolvedConfig } from './config.js';\nimport { resolveConfig } from './config.js';\nimport { PoolseRealtime } from './realtime/realtime.js';\nimport { AttachmentsResource } from './resources/attachments.js';\nimport { ConversationsResource } from './resources/conversations.js';\nimport { MeResource } from './resources/me.js';\nimport { MessagesResource } from './resources/messages.js';\nimport { UsersResource } from './resources/users.js';\nimport { RestClient } from './rest-client.js';\nimport { TokenCache } from './token-cache.js';\n\nexport class Poolse {\n /** `/v1/me` — current End User. */\n public readonly me: MeResource;\n /** `/v1/conversations` collection + per-conversation handle factory. */\n public readonly conversations: ConversationsResource;\n /** `/v1/messages/:id/*` — accessed via `chat.messages.one(id)`. */\n public readonly messages: MessagesResource;\n /** `/v1/attachments/*` — presigned-URL uploads/downloads. */\n public readonly attachments: AttachmentsResource;\n\n /**\n * Customer-supplied user metadata, cached + dedup'd.\n * `chat.users.get(userId)` returns `{ displayName, avatarUrl }`\n * via the optional `config.userResolver`. UI components\n * (`MessageBubble`, `MemberList`, `TypingIndicator`) pick this up\n * automatically via the `useUser` hook in `@poolse/react`.\n *\n * If no resolver is configured, `get` always returns `null` and\n * UI falls back to the userId slice + initials avatar.\n */\n public readonly users: UsersResource;\n\n /**\n * Low-level REST client. Exposed for advanced use cases (custom endpoints,\n * raw retry/headers control). Most callers should use the resources above.\n */\n public readonly rest: RestClient;\n\n /**\n * WebSocket / Phoenix Channels client. Lazily connects on the first\n * `poolse.realtime.conversation(id)` / `poolse.realtime.user(id)`\n * call — passing `config.apiUrl` (with `http(s)://` swapped to\n * `ws(s)://`) for the socket URL by default, overridable via\n * `config.wsUrl`.\n */\n public readonly realtime: PoolseRealtime;\n\n private readonly resolved: ResolvedConfig;\n private readonly tokenCache: TokenCache;\n\n constructor(config: PoolseConfig) {\n this.resolved = resolveConfig(config);\n\n // Wrap the consumer's `getToken` in a cache so the SDK doesn't\n // call back on every REST request / WebSocket connect. Both the\n // REST client and the realtime layer share this one instance so a\n // freshly-minted token from one path serves all subsequent calls.\n this.tokenCache = new TokenCache(this.resolved.getToken);\n const cachedConfig: ResolvedConfig = {\n ...this.resolved,\n getToken: () => this.tokenCache.getToken(),\n };\n\n this.rest = new RestClient(cachedConfig, this.tokenCache);\n this.me = new MeResource(this.rest);\n this.conversations = new ConversationsResource(this.rest);\n this.messages = new MessagesResource(this.rest);\n this.attachments = new AttachmentsResource(this.rest, cachedConfig.fetch);\n this.users = new UsersResource(cachedConfig);\n\n this.realtime = new PoolseRealtime(cachedConfig, this.tokenCache, {\n ...(this.resolved.wsUrl !== undefined ? { wsUrl: this.resolved.wsUrl } : {}),\n socketPath: this.resolved.socketPath,\n });\n }\n\n /**\n * Tear down the SDK: close the WebSocket, drop all channels.\n * No-op for REST — fetch() doesn't keep persistent state.\n * Call this when the user signs out or the SDK instance is\n * being replaced.\n */\n destroy(): void {\n this.realtime.disconnect();\n }\n}\n","// Single source of truth for the SDK version at runtime. Kept in sync\n// with package.json by the release process.\nexport const version = '2.0.1';\n"]}
package/dist/index.d.cts CHANGED
@@ -1016,6 +1016,8 @@ declare class AuthError extends ApiError {
1016
1016
  constructor(envelope: ErrorEnvelope['error']);
1017
1017
  }
1018
1018
 
1019
- declare const version = "2.0.0";
1019
+ declare const version = "2.0.1";
1020
1020
 
1021
- export { type AddMemberOptions, ApiError, type Attachment, type AttachmentDownloadResponse, AttachmentHandle, type AttachmentOptions, type AttachmentProgressEvent, type AttachmentStatus, type AttachmentUploadInput, type AttachmentUploadRequest, type AttachmentUploadResponse, AttachmentsResource, AuthError, type Conversation, ConversationChannel, type ConversationCreateRequest, type ConversationCreatedEvent, ConversationHandle, type ConversationList, ConversationMessages, type ConversationType, type ConversationUpdateRequest, ConversationsResource, type ErrorEnvelope, type IsoDateTime, type Me, MeResource, type MemberReadEvent, type MemberRole, type Membership, type MembershipCreateRequest, type MembershipList, type MentionEvent, type Message, type MessageCreateRequest, type MessageDeletedEvent, MessageHandle, type MessageList, type MessageNewEvent, type MessageType, type MessageUpdateRequest, type MessageUpdatedEvent, MessagesResource, NetworkError, POOLSE_API_URL, Poolse, type PoolseConfig, PoolseError, PoolseRealtime, type PoolseUserProfile, type PresenceSnapshot, type QuotedMessagePreview, RateLimitedError, type ReactionEvent, type ReactionRequest, type ReadRequest, type RealtimeStatus, type TypingEvent, type Unsubscribe, UserChannel, UsersResource, type Uuid, version };
1021
+ declare function safeUuid(): string;
1022
+
1023
+ export { type AddMemberOptions, ApiError, type Attachment, type AttachmentDownloadResponse, AttachmentHandle, type AttachmentOptions, type AttachmentProgressEvent, type AttachmentStatus, type AttachmentUploadInput, type AttachmentUploadRequest, type AttachmentUploadResponse, AttachmentsResource, AuthError, type Conversation, ConversationChannel, type ConversationCreateRequest, type ConversationCreatedEvent, ConversationHandle, type ConversationList, ConversationMessages, type ConversationType, type ConversationUpdateRequest, ConversationsResource, type ErrorEnvelope, type IsoDateTime, type Me, MeResource, type MemberReadEvent, type MemberRole, type Membership, type MembershipCreateRequest, type MembershipList, type MentionEvent, type Message, type MessageCreateRequest, type MessageDeletedEvent, MessageHandle, type MessageList, type MessageNewEvent, type MessageType, type MessageUpdateRequest, type MessageUpdatedEvent, MessagesResource, NetworkError, POOLSE_API_URL, Poolse, type PoolseConfig, PoolseError, PoolseRealtime, type PoolseUserProfile, type PresenceSnapshot, type QuotedMessagePreview, RateLimitedError, type ReactionEvent, type ReactionRequest, type ReadRequest, type RealtimeStatus, type TypingEvent, type Unsubscribe, UserChannel, UsersResource, type Uuid, safeUuid, version };
package/dist/index.d.ts CHANGED
@@ -1016,6 +1016,8 @@ declare class AuthError extends ApiError {
1016
1016
  constructor(envelope: ErrorEnvelope['error']);
1017
1017
  }
1018
1018
 
1019
- declare const version = "2.0.0";
1019
+ declare const version = "2.0.1";
1020
1020
 
1021
- export { type AddMemberOptions, ApiError, type Attachment, type AttachmentDownloadResponse, AttachmentHandle, type AttachmentOptions, type AttachmentProgressEvent, type AttachmentStatus, type AttachmentUploadInput, type AttachmentUploadRequest, type AttachmentUploadResponse, AttachmentsResource, AuthError, type Conversation, ConversationChannel, type ConversationCreateRequest, type ConversationCreatedEvent, ConversationHandle, type ConversationList, ConversationMessages, type ConversationType, type ConversationUpdateRequest, ConversationsResource, type ErrorEnvelope, type IsoDateTime, type Me, MeResource, type MemberReadEvent, type MemberRole, type Membership, type MembershipCreateRequest, type MembershipList, type MentionEvent, type Message, type MessageCreateRequest, type MessageDeletedEvent, MessageHandle, type MessageList, type MessageNewEvent, type MessageType, type MessageUpdateRequest, type MessageUpdatedEvent, MessagesResource, NetworkError, POOLSE_API_URL, Poolse, type PoolseConfig, PoolseError, PoolseRealtime, type PoolseUserProfile, type PresenceSnapshot, type QuotedMessagePreview, RateLimitedError, type ReactionEvent, type ReactionRequest, type ReadRequest, type RealtimeStatus, type TypingEvent, type Unsubscribe, UserChannel, UsersResource, type Uuid, version };
1021
+ declare function safeUuid(): string;
1022
+
1023
+ export { type AddMemberOptions, ApiError, type Attachment, type AttachmentDownloadResponse, AttachmentHandle, type AttachmentOptions, type AttachmentProgressEvent, type AttachmentStatus, type AttachmentUploadInput, type AttachmentUploadRequest, type AttachmentUploadResponse, AttachmentsResource, AuthError, type Conversation, ConversationChannel, type ConversationCreateRequest, type ConversationCreatedEvent, ConversationHandle, type ConversationList, ConversationMessages, type ConversationType, type ConversationUpdateRequest, ConversationsResource, type ErrorEnvelope, type IsoDateTime, type Me, MeResource, type MemberReadEvent, type MemberRole, type Membership, type MembershipCreateRequest, type MembershipList, type MentionEvent, type Message, type MessageCreateRequest, type MessageDeletedEvent, MessageHandle, type MessageList, type MessageNewEvent, type MessageType, type MessageUpdateRequest, type MessageUpdatedEvent, MessagesResource, NetworkError, POOLSE_API_URL, Poolse, type PoolseConfig, PoolseError, PoolseRealtime, type PoolseUserProfile, type PresenceSnapshot, type QuotedMessagePreview, RateLimitedError, type ReactionEvent, type ReactionRequest, type ReadRequest, type RealtimeStatus, type TypingEvent, type Unsubscribe, UserChannel, UsersResource, type Uuid, safeUuid, version };