import { a as RealtimePayload, D as PalbeAuth, G as PalbeFlags, K as PalbeRealtime, B as PalbeAnalytics, E as PalbeCalls, H as PalbeMessaging, a2 as PalbePerf, d as PalbeRuntime } from './analytics-facade-B1s6ueXl.js'; interface CallOptions { headers?: Record; signal?: AbortSignal; } /** What a room needs from the socket. `PalbeRealtime` provides it; a test * supplies its own, so the typed layer can be measured without a connection. */ interface RoomTransport { /** Subscribe to one event on one topic. Returns the undo. */ subscribe(topic: string, event: string, handler: (payload: RealtimePayload) => void): () => void; /** Push one client frame. */ send(topic: string, event: string, payload: RealtimePayload): void; } /** * A room, as the generator emits one. An app never writes this by hand. * * `send` and `event` are TYPE CARRIERS — their values are never read. They exist * so `room.send('say', {...})` checks the payload against the right shape * without the app ever naming that shape. */ interface RoomDescriptor { /** The channel pattern the backend declared: `ai:{sessionId}`. */ pattern: string; /** The `{param}` names, in pattern order. * * Typed as a literal tuple (the generator emits `as const`) so `join` can * demand EXACTLY these keys. Without that, `params` is `Record` and a typo'd key type-checks — it then builds a topic with an * unfilled `{param}`, which matches no room on the server and fails as * SILENCE. Measured: the runtime guard caught it, the compiler did not. */ params: P; /** The declared event names — what the handle subscribes to. Without the list * it would have to guess, and a room's events are what it must not guess. */ events: readonly string[]; /** The declared message names. `send` is a TYPE carrier with no runtime keys, * so this is the half a JavaScript caller can be checked against. */ messages: readonly string[]; send: S; event: E; } /** A live room. Hold it for as long as the view is on screen. */ interface RoomHandle { /** The topic this handle is attached to. An app never has to build it. */ readonly topic: string; /** Start receiving. Returns a token for `off`. */ on(handler: (event: E) => void): RoomToken; /** Stop one callback. */ off(token: RoomToken): void; /** Send one declared message. The event name comes from the descriptor. */ send(name: K, payload: S[K]): void; /** Drop every callback this handle registered. */ leave(): void; } /** Opaque handle to one registration. Callback + token, deliberately: a room * routinely has several interested parties (a transcript, a badge, a logger), * and an async iterator has exactly one consumer. */ type RoomToken = { readonly __room: unique symbol; } | symbol; /** * Attach to a room. * * const room = pb.join(AiSessionIdRoom, { sessionId }) * const token = room.on((e) => { * switch (e.event) { * case 'token': transcript.push(e.payload.text); break * case 'done': finish(e.payload.reason); break * } * }) * room.send('say', { text: 'hello' }) * room.off(token) * * `switch` is exhaustive: when the backend adds an event, the compiler points at * every place that has to handle it. */ declare function joinRoom(descriptor: RoomDescriptor, params: Record, transport: RoomTransport): RoomHandle; interface UploadProgress { /** Bytes sent so far. */ sent: number; /** * Total bytes. Always > 0 when delivered — progress events whose length is * not computable are skipped entirely. */ total: number; } interface UploadOptions { file: Blob; filename?: string; contentType?: string; /** * The request body sent beside the file. Folded into the single `body` part * storage reads and handed to the route's schema — pass a pre-encoded JSON * string as `body` to own the envelope yourself. */ fields?: Record; onProgress?: (progress: UploadProgress) => void; signal?: AbortSignal; headers?: Record; /** Client-side pre-send validation (iOS parity). */ constraints?: { maxSize?: number; allowedTypes?: string[]; }; } /** * The Palbe surface. Codegen augments this interface with typed endpoint * namespaces: declare module '@palbase/web' { interface PB { rooms: ... } } */ interface PB { call(name: string, input?: unknown, options?: CallOptions): Promise; upload(name: string, options: UploadOptions): Promise; readonly auth: PalbeAuth; readonly flags: PalbeFlags; readonly realtime: PalbeRealtime; /** * Join a room the backend declared with `@Room`. * * const room = pb.join(AiSessionIdRoom, { sessionId }) * const token = room.on((e) => { … }) * room.send('say', { text: 'hello' }) * * The descriptor is GENERATED: the pattern, the event names and the message * names all come from the backend's declaration, so the app writes no channel * string and no payload type of its own. */ join(descriptor: RoomDescriptor, params: Record): RoomHandle; readonly analytics: PalbeAnalytics; readonly calls: PalbeCalls; readonly messaging: PalbeMessaging; /** The PalPerf surface: custom traces (`startTrace`) + the buffered flush of * network/app-start/custom items. `pb.perf.record(...)` is also how the * runtime feeds the cold-start measurement in. */ readonly perf: PalbePerf; /** Mark (or unmark) this client's traffic as test — flips the facade's flag * so every subsequent perf flush carries `X-Palbase-Test-Device: 1` (the * SAME header the iOS SDK sends; the server reads it → `is_test_traffic`). */ setTestDevice(on: boolean): void; } declare const pb: PB; /** * A `PB` client permanently bound to ONE runtime — typed namespaces, `call`, * `upload` and `auth` all resolve `rt`, NEVER the global slot. This is the * per-request isolation primitive for server adapters (palbe/next pbServer): * two bound clients serving concurrent requests cannot leak each other's * sessions, and global `__configure` swaps don't touch them. */ declare function createBoundClient(rt: PalbeRuntime): PB; export { type CallOptions as C, type PB as P, type RoomDescriptor as R, type UploadOptions as U, type RoomHandle as a, type RoomToken as b, createBoundClient as c, type RoomTransport as d, type UploadProgress as e, joinRoom as j, pb as p };