@ragable/sdk 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +112 -1
- package/dist/index.d.ts +112 -1
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/request-client.ts","../src/agent-stream.ts","../src/agent-chat-ui.ts","../src/sse.ts","../src/transport.ts","../src/browser-postgrest.ts","../src/auth-storage.ts","../src/auth.ts","../src/partial-json.ts","../src/stream-parts.ts","../src/ai.ts","../src/browser.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Native `fetch` must not be called as a detached reference (`const f = fetch; f(url)`),\r\n * or the browser throws **Illegal invocation**. Use this for defaults and for `options.fetch`.\r\n */\r\nexport function bindFetch(custom?: typeof fetch): typeof fetch {\r\n return (input, init) => {\r\n const f = custom ?? globalThis.fetch;\r\n return f.call(globalThis, input as RequestInfo, init);\r\n };\r\n}\r\n\r\n/** Hosted Ragable HTTP API base (`…/api`) — used by all SDK clients (not configurable). */\r\nexport const DEFAULT_RAGABLE_API_BASE =\r\n \"https://ragable-341305259977.asia-southeast1.run.app/api\";\r\n\r\nexport interface RagableClientOptions {\r\n apiKey: string;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n}\r\n\r\nexport type RequestOptions = Omit<RequestInit, \"body\"> & {\r\n body?: unknown;\r\n};\r\n\r\nexport abstract class RagableSdkError extends Error {\r\n abstract readonly __type: string;\r\n constructor(message: string) {\r\n super(message);\r\n this.name = this.constructor.name;\r\n // Native `Error.message` is non-enumerable — `{...err}`, `JSON.stringify({...err})`, and some\r\n // loggers show `{}`. Redefine so spreads and plain serialization keep `message`.\r\n Object.defineProperty(this, \"message\", {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value: message,\r\n });\r\n }\r\n\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n __type: this.__type,\r\n };\r\n }\r\n}\r\n\r\nexport class RagableError extends RagableSdkError {\r\n readonly __type = \"RagableError\" as const;\r\n readonly status: number;\r\n readonly body: unknown;\r\n readonly code: string | undefined;\r\n readonly details: string | undefined;\r\n\r\n constructor(message: string, status: number, body: unknown) {\r\n super(message);\r\n this.status = status;\r\n this.body = body;\r\n this.code =\r\n body && typeof body === \"object\"\r\n ? typeof (body as Record<string, unknown>).code === \"string\"\r\n ? ((body as Record<string, unknown>).code as string)\r\n : typeof (body as Record<string, unknown>).code === \"number\"\r\n ? String((body as Record<string, unknown>).code)\r\n : undefined\r\n : undefined;\r\n this.details =\r\n body && typeof body === \"object\"\r\n ? typeof (body as Record<string, unknown>).details === \"string\"\r\n ? ((body as Record<string, unknown>).details as string)\r\n : undefined\r\n : undefined;\r\n }\r\n\r\n override toJSON(): Record<string, unknown> {\r\n return {\r\n ...super.toJSON(),\r\n status: this.status,\r\n body: this.body,\r\n code: this.code,\r\n details: this.details,\r\n };\r\n }\r\n\r\n /** Stable string for logs — avoids `{}` when coercing or stringifying. */\r\n override toString(): string {\r\n const bits = [`${this.name}: ${this.message}`];\r\n if (this.status) bits.push(`status=${this.status}`);\r\n if (this.code) bits.push(`code=${this.code}`);\r\n return bits.join(\" · \");\r\n }\r\n}\r\n\r\n/** Safe one-line log for any thrown value (catch blocks, TanStack Query). */\r\nexport function formatSdkError(err: unknown): string {\r\n if (err instanceof RagableError) {\r\n return `${err.message} (HTTP ${err.status}${err.code ? `, ${err.code}` : \"\"})`;\r\n }\r\n if (err instanceof RagableSdkError) {\r\n return err.message;\r\n }\r\n if (err instanceof Error) {\r\n return err.message || err.name;\r\n }\r\n if (typeof err === \"string\") return err;\r\n if (err && typeof err === \"object\") {\r\n try {\r\n const s = JSON.stringify(err);\r\n if (s !== \"{}\") return s;\r\n return \"Unknown error (empty object — avoid `{...error}` spread; use error.message or formatSdkError)\";\r\n } catch {\r\n /* fall through */\r\n }\r\n }\r\n return String(err);\r\n}\r\n\r\n/**\r\n * Human-readable line for a PostgREST `{ data, error }` error (or any thrown value).\r\n * Use in UI instead of `JSON.stringify(error)` or template strings on unknown errors.\r\n */\r\nexport function formatPostgrestError(error: unknown): string {\r\n return formatSdkError(error);\r\n}\r\n\r\nexport class RagableNetworkError extends RagableSdkError {\r\n readonly __type = \"RagableNetworkError\" as const;\r\n readonly cause: unknown;\r\n constructor(message: string, cause?: unknown) {\r\n super(message);\r\n this.cause = cause;\r\n }\r\n\r\n override toJSON(): Record<string, unknown> {\r\n return {\r\n ...super.toJSON(),\r\n cause: this.cause instanceof Error ? this.cause.message : this.cause,\r\n };\r\n }\r\n}\r\n\r\nexport class RagableAbortError extends RagableSdkError {\r\n readonly __type = \"RagableAbortError\" as const;\r\n constructor(message = \"Request aborted\") {\r\n super(message);\r\n }\r\n}\r\n\r\nexport class RagableTimeoutError extends RagableSdkError {\r\n readonly __type = \"RagableTimeoutError\" as const;\r\n readonly timeoutMs: number;\r\n constructor(timeoutMs: number) {\r\n super(`Request timed out after ${timeoutMs}ms`);\r\n this.timeoutMs = timeoutMs;\r\n }\r\n\r\n override toJSON(): Record<string, unknown> {\r\n return {\r\n ...super.toJSON(),\r\n timeoutMs: this.timeoutMs,\r\n };\r\n }\r\n}\r\n\r\nexport function extractErrorMessage(payload: unknown, fallback: string) {\r\n if (payload && typeof payload === \"object\") {\r\n if (\"error\" in payload && typeof payload.error === \"string\") {\r\n return payload.error;\r\n }\r\n if (\"message\" in payload && typeof payload.message === \"string\") {\r\n return payload.message;\r\n }\r\n }\r\n\r\n if (typeof payload === \"string\" && payload.length > 0) {\r\n return payload;\r\n }\r\n\r\n return fallback || \"Request failed\";\r\n}\r\n\r\nexport class RagableRequestClient {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: string;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultHeaders: HeadersInit | undefined;\r\n\r\n constructor(options: RagableClientOptions) {\r\n this.apiKey = options.apiKey;\r\n this.baseUrl = DEFAULT_RAGABLE_API_BASE.replace(/\\/+$/, \"\");\r\n this.fetchImpl = bindFetch(options.fetch);\r\n this.defaultHeaders = options.headers;\r\n }\r\n\r\n toUrl(path: string) {\r\n const normalizedBase = this.baseUrl.replace(/\\/+$/, \"\");\r\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n return `${normalizedBase}${normalizedPath}`;\r\n }\r\n\r\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\r\n const response = await this.rawFetch(path, options);\r\n const payload = await this.parseResponseBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n return payload as T;\r\n }\r\n\r\n /**\r\n * Low-level fetch with API key and JSON body encoding. Caller handles status and body.\r\n */\r\n async rawFetch(path: string, options: RequestOptions = {}): Promise<Response> {\r\n const headers = new Headers(this.defaultHeaders);\r\n headers.set(\"Authorization\", `Bearer ${this.apiKey}`);\r\n\r\n let body = options.body;\r\n if (body !== undefined && !isBodyInit(body)) {\r\n headers.set(\"Content-Type\", \"application/json\");\r\n body = JSON.stringify(body);\r\n }\r\n\r\n return this.fetchImpl(this.toUrl(path), {\r\n ...options,\r\n headers,\r\n body: body as BodyInit | undefined,\r\n });\r\n }\r\n\r\n private async parseResponseBody(response: Response): Promise<unknown> {\r\n if (response.status === 204) {\r\n return null;\r\n }\r\n\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n if (contentType.includes(\"application/json\")) {\r\n return response.json();\r\n }\r\n\r\n return response.text();\r\n }\r\n}\r\n\r\nexport function isBodyInit(value: unknown): value is BodyInit {\r\n return (\r\n typeof value === \"string\" ||\r\n value instanceof Blob ||\r\n value instanceof FormData ||\r\n value instanceof URLSearchParams ||\r\n value instanceof ArrayBuffer ||\r\n ArrayBuffer.isView(value)\r\n );\r\n}\r\n","import { RagableAbortError, RagableError } from \"./request-client\";\n\nexport interface AgentChatMessage {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface AgentChatParams {\n message: string;\n history?: AgentChatMessage[];\n /** Passed to `fetch` — aborts the HTTP request and SSE body. */\n signal?: AbortSignal;\n}\n\nexport type AgentStreamEvent = Record<string, unknown> & { type: string };\n\n/**\n * First SSE frame for website project agents (`POST …/agents/:name/chat/stream`).\n */\nexport interface AgentStreamAgentInfoEvent {\n type: \"agent:info\";\n name: string;\n agent_name: string;\n}\n\n/** Payload on the terminal `done` event (matches backend {@link AgentChatResult} + usage fields). */\nexport interface AgentChatStreamDonePayload {\n response: string;\n traces: unknown[];\n totalDurationMs: number;\n httpResponse?: unknown;\n inputTokens?: number;\n outputTokens?: number;\n cachedPromptTokens?: number;\n cacheCreationInputTokens?: number;\n completionProviders?: string[];\n creditsCharged?: number;\n agentSteps?: number;\n finishReason?: string | null;\n stopReason?: string | null;\n turnMessages?: unknown;\n promptTokensEstimated?: number;\n contextWindow?: number;\n}\n\n/**\n * Resolved outcome after the stream finishes. `assistantText` is the concatenation of\n * all `token` deltas; `response` is the server’s final string from `done` (authoritative).\n */\nexport interface AgentChatStreamResult extends AgentChatStreamDonePayload {\n assistantText: string;\n reasoningText: string;\n}\n\nexport interface AgentChatStreamHandlers {\n /** Every parsed SSE object (including `ping`, `node:*`, etc.). */\n onEvent?: (event: AgentStreamEvent) => void;\n onAgentInfo?: (info: AgentStreamAgentInfoEvent) => void;\n onToken?: (token: string, ctx: { nodeId: string }) => void;\n onReasoningToken?: (token: string, ctx: { nodeId: string }) => void;\n onToolCall?: (ctx: {\n nodeId: string;\n toolName: string;\n args: unknown;\n }) => void;\n onToolArgsUpdate?: (ctx: {\n nodeId: string;\n args: Record<string, unknown>;\n }) => void;\n onToolResult?: (ctx: {\n nodeId: string;\n toolName: string;\n durationMs: number;\n result?: string;\n }) => void;\n onNodeStart?: (ctx: {\n nodeId: string;\n nodeType: string;\n label: string;\n }) => void;\n onNodeComplete?: (ctx: {\n nodeId: string;\n output: unknown;\n durationMs: number;\n }) => void;\n onNodeError?: (ctx: { nodeId: string; error: string }) => void;\n /** Backend heartbeat — safe to ignore in UI. */\n onPing?: () => void;\n /** Fired when the server emits `done` (before {@link onComplete}). */\n onDone?: (payload: AgentChatStreamDonePayload) => void;\n /**\n * Always called on successful completion (after `done`). Not called if the stream\n * errors or ends without `done`.\n */\n onComplete?: (result: AgentChatStreamResult) => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface RunAgentChatStreamOptions {\n /**\n * Abort while consuming events (in addition to any `signal` on the HTTP request).\n * Stops reading and throws {@link RagableAbortError}.\n */\n signal?: AbortSignal;\n}\n\nfunction assertAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new RagableAbortError();\n }\n}\n\nfunction asString(v: unknown, fallback = \"\"): string {\n return typeof v === \"string\" ? v : fallback;\n}\n\nfunction asNumber(v: unknown, fallback = 0): number {\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\n\nfunction asUnknownArray(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\n/** Narrow `done` events from a loose {@link AgentStreamEvent}. */\nexport function parseAgentStreamDone(\n e: AgentStreamEvent,\n): AgentChatStreamDonePayload | null {\n if (e.type !== \"done\") return null;\n return {\n response: asString(e[\"response\"]),\n traces: asUnknownArray(e[\"traces\"]),\n totalDurationMs: asNumber(e[\"totalDurationMs\"]),\n ...(e[\"httpResponse\"] !== undefined\n ? { httpResponse: e[\"httpResponse\"] }\n : {}),\n ...(typeof e[\"inputTokens\"] === \"number\"\n ? { inputTokens: e[\"inputTokens\"] }\n : {}),\n ...(typeof e[\"outputTokens\"] === \"number\"\n ? { outputTokens: e[\"outputTokens\"] }\n : {}),\n ...(typeof e[\"cachedPromptTokens\"] === \"number\"\n ? { cachedPromptTokens: e[\"cachedPromptTokens\"] }\n : {}),\n ...(typeof e[\"cacheCreationInputTokens\"] === \"number\"\n ? { cacheCreationInputTokens: e[\"cacheCreationInputTokens\"] }\n : {}),\n ...(Array.isArray(e[\"completionProviders\"])\n ? {\n completionProviders: e[\"completionProviders\"].map((x: unknown) => String(x)),\n }\n : {}),\n ...(typeof e[\"creditsCharged\"] === \"number\"\n ? { creditsCharged: e[\"creditsCharged\"] }\n : {}),\n ...(typeof e[\"agentSteps\"] === \"number\"\n ? { agentSteps: e[\"agentSteps\"] }\n : {}),\n ...(e[\"finishReason\"] !== undefined\n ? { finishReason: e[\"finishReason\"] as string | null }\n : {}),\n ...(e[\"stopReason\"] !== undefined\n ? { stopReason: e[\"stopReason\"] as string | null }\n : {}),\n ...(e[\"turnMessages\"] !== undefined\n ? { turnMessages: e[\"turnMessages\"] }\n : {}),\n ...(typeof e[\"promptTokensEstimated\"] === \"number\"\n ? { promptTokensEstimated: e[\"promptTokensEstimated\"] }\n : {}),\n ...(typeof e[\"contextWindow\"] === \"number\"\n ? { contextWindow: e[\"contextWindow\"] }\n : {}),\n };\n}\n\n/** @public Parse the initial `agent:info` SSE frame (website project agents). */\nexport function parseAgentStreamAgentInfo(\n e: AgentStreamEvent,\n): AgentStreamAgentInfoEvent | null {\n if (e.type !== \"agent:info\") return null;\n return {\n type: \"agent:info\",\n name: asString(e[\"name\"]),\n agent_name: asString(e[\"agent_name\"]),\n };\n}\n\nfunction parseAgentInfo(\n e: AgentStreamEvent,\n): AgentStreamAgentInfoEvent | null {\n return parseAgentStreamAgentInfo(e);\n}\n\n/**\n * Consume a Ragable agent SSE stream with callbacks and return the final result.\n *\n * For the same segment model as dashboard `AgentChat` (`streamingSegments` /\n * `streamingContent`), use {@link runAgentChatStreamForUi} or\n * `client.agents.runChatUiByName` instead.\n *\n * Typical low-level chat (string accumulation only):\n *\n * ```ts\n * const result = await client.agents.runChatStreamByName(\"support\", {\n * message: input,\n * history,\n * signal: ac.signal,\n * }, {\n * onToken: (t) => setReply((s) => s + t),\n * });\n * ```\n *\n * Lower-level (same client, manual iterator):\n *\n * ```ts\n * const result = await runAgentChatStream(\n * client.agents.chatStreamByName(\"support\", { message, signal }),\n * { onToken: (t) => append(t) },\n * { signal },\n * );\n * ```\n */\nexport async function runAgentChatStream(\n source: AsyncIterable<AgentStreamEvent>,\n handlers: AgentChatStreamHandlers = {},\n options: RunAgentChatStreamOptions = {},\n): Promise<AgentChatStreamResult> {\n const { signal } = options;\n let assistantText = \"\";\n let reasoningText = \"\";\n let donePayload: AgentChatStreamDonePayload | null = null;\n\n try {\n for await (const event of source) {\n assertAborted(signal);\n handlers.onEvent?.(event);\n\n const info = parseAgentInfo(event);\n if (info) {\n handlers.onAgentInfo?.(info);\n continue;\n }\n\n switch (event.type) {\n case \"ping\":\n handlers.onPing?.();\n break;\n case \"token\": {\n const nodeId = asString(event[\"nodeId\"], \"__self__\");\n const token = asString(event[\"token\"]);\n assistantText += token;\n handlers.onToken?.(token, { nodeId });\n break;\n }\n case \"reasoning_token\": {\n const nodeId = asString(event[\"nodeId\"], \"__self__\");\n const token = asString(event[\"token\"]);\n reasoningText += token;\n handlers.onReasoningToken?.(token, { nodeId });\n break;\n }\n case \"tool:call\":\n handlers.onToolCall?.({\n nodeId: asString(event[\"nodeId\"]),\n toolName: asString(event[\"toolName\"]),\n args: event[\"args\"],\n });\n break;\n case \"tool:args_update\": {\n const raw = event[\"args\"];\n const args =\n raw !== null && typeof raw === \"object\" && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : {};\n handlers.onToolArgsUpdate?.({\n nodeId: asString(event[\"nodeId\"]),\n args,\n });\n break;\n }\n case \"tool:result\":\n handlers.onToolResult?.({\n nodeId: asString(event[\"nodeId\"]),\n toolName: asString(event[\"toolName\"]),\n durationMs: asNumber(event[\"durationMs\"]),\n ...(typeof event[\"result\"] === \"string\"\n ? { result: event[\"result\"] }\n : {}),\n });\n break;\n case \"node:start\":\n handlers.onNodeStart?.({\n nodeId: asString(event[\"nodeId\"]),\n nodeType: asString(event[\"nodeType\"]),\n label: asString(event[\"label\"]),\n });\n break;\n case \"node:complete\":\n handlers.onNodeComplete?.({\n nodeId: asString(event[\"nodeId\"]),\n output: event[\"output\"],\n durationMs: asNumber(event[\"durationMs\"]),\n });\n break;\n case \"node:error\":\n handlers.onNodeError?.({\n nodeId: asString(event[\"nodeId\"]),\n error: asString(event[\"error\"]),\n });\n break;\n case \"done\": {\n const parsed = parseAgentStreamDone(event);\n if (parsed) {\n donePayload = parsed;\n handlers.onDone?.(parsed);\n }\n break;\n }\n default:\n break;\n }\n }\n } catch (err) {\n handlers.onError?.(err);\n throw err;\n }\n\n if (!donePayload) {\n const err = new RagableError(\n \"Agent stream ended without a done event\",\n 502,\n { code: \"SDK_AGENT_STREAM_INCOMPLETE\" },\n );\n handlers.onError?.(err);\n throw err;\n }\n\n const result: AgentChatStreamResult = {\n ...donePayload,\n assistantText,\n reasoningText,\n };\n handlers.onComplete?.(result);\n return result;\n}\n\n/**\n * Like {@link runAgentChatStream} but resolves with `null` if the stream ends without `done`\n * instead of throwing. Errors other than incomplete stream are still thrown.\n */\nexport async function runAgentChatStreamLenient(\n source: AsyncIterable<AgentStreamEvent>,\n handlers: AgentChatStreamHandlers = {},\n options: RunAgentChatStreamOptions = {},\n): Promise<AgentChatStreamResult | null> {\n try {\n return await runAgentChatStream(source, handlers, options);\n } catch (e) {\n if (\n e instanceof RagableError &&\n e.code === \"SDK_AGENT_STREAM_INCOMPLETE\"\n ) {\n return null;\n }\n throw e;\n }\n}\n\n/** True when {@link runAgentChatStream} stopped because no `done` event arrived. */\nexport function isIncompleteAgentStreamError(e: unknown): boolean {\n return e instanceof RagableError && e.code === \"SDK_AGENT_STREAM_INCOMPLETE\";\n}\n","/**\n * UI-oriented agent streaming — folds wire events into the same segment model as\n * `app/web/src/components/AgentChat.tsx` (`StreamSegment`), matching the reducers in\n * `useEngineIDEAgent` / `useIDEAgent` (tool gating, coalesced text/reasoning, etc.).\n */\n\nimport type { AgentStreamEvent } from \"./agent-stream\";\nimport type {\n AgentChatStreamDonePayload,\n AgentStreamAgentInfoEvent,\n RunAgentChatStreamOptions,\n} from \"./agent-stream\";\nimport {\n parseAgentStreamAgentInfo,\n parseAgentStreamDone,\n} from \"./agent-stream\";\nimport { RagableAbortError, RagableError } from \"./request-client\";\n\n/**\n * Chat UI segments — structural parity with `StreamSegment` in dashboard `AgentChat`.\n */\nexport type AgentChatUiSegment =\n | { type: \"text\"; content: string }\n | { type: \"reasoning\"; content: string }\n | {\n type: \"tool\";\n id: string;\n toolName: string;\n status: \"started\" | \"completed\";\n durationMs?: number;\n args?: Record<string, unknown>;\n result?: string;\n }\n | {\n type: \"context_summarized\";\n step: number;\n mode?: \"llm\" | \"heuristic\" | \"llm+heuristic\" | \"aggressive\";\n reason?: \"soft_limit\" | \"forced\";\n tokensRemovedEstimate?: number;\n estimatedTokensAfter?: number;\n }\n | {\n type: \"llm_step\";\n step: number;\n inputTokens: number;\n outputTokens: number;\n cachedPromptTokens?: number;\n cacheCreationInputTokens?: number;\n creditsEstimated: number;\n apiCostUsd?: number;\n provider?: string;\n }\n | { type: \"stop_reason\"; content: string; finishReason: string };\n\n/** Assistant row to append to chat history (add your own `id`). */\nexport interface AgentChatUiAssistantMessage {\n role: \"ai\";\n content: string;\n segments?: AgentChatUiSegment[];\n usage?: {\n inputTokens: number;\n outputTokens: number;\n creditsCharged: number;\n cachedPromptTokens?: number;\n cacheCreationInputTokens?: number;\n };\n durationMs?: number;\n finishReason?: string | null;\n completionProviders?: string[];\n agentSteps?: number;\n}\n\nexport interface AgentChatUiStreamResult {\n /** Segments immediately before `done` (no trailing `stop_reason`). */\n segmentsMidTurn: AgentChatUiSegment[];\n /** Final segments including optional `stop_reason` from `done`. */\n segments: AgentChatUiSegment[];\n /** Persisted assistant message — matches dashboard `ChatMessageData` for `ai` (except `id`). */\n message: AgentChatUiAssistantMessage;\n done: AgentChatStreamDonePayload;\n}\n\nexport interface AgentChatStreamUiHandlers {\n /**\n * Live segment list — pass to `AgentChat` as `streamingSegments` (or your own renderer).\n */\n onSegments?: (segments: AgentChatUiSegment[]) => void;\n /**\n * Plain assistant text — mirrors dashboard `streamingContent` (text channel only).\n */\n onStreamingText?: (text: string) => void;\n onAgentInfo?: (info: AgentStreamAgentInfoEvent) => void;\n onEvent?: (event: AgentStreamEvent) => void;\n onDone?: (payload: AgentChatStreamDonePayload) => void;\n onComplete?: (result: AgentChatUiStreamResult) => void;\n onError?: (error: unknown) => void;\n}\n\nfunction asString(v: unknown, fallback = \"\"): string {\n return typeof v === \"string\" ? v : fallback;\n}\n\nfunction asNumber(v: unknown, fallback = 0): number {\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\n\nfunction assertAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new RagableAbortError();\n }\n}\n\nfunction recordFromUnknown(v: unknown): Record<string, unknown> {\n if (v !== null && typeof v === \"object\" && !Array.isArray(v)) {\n return { ...(v as Record<string, unknown>) };\n }\n return {};\n}\n\nfunction lastToolBlocksStream(\n last: AgentChatUiSegment | undefined,\n): boolean {\n return last?.type === \"tool\" && last.status === \"started\";\n}\n\nfunction toolSegmentId(event: AgentStreamEvent): string {\n const nid = event[\"nodeId\"];\n if (typeof nid === \"string\" && nid.length > 0) return nid;\n const tn = event[\"toolName\"];\n if (typeof tn === \"string\" && tn.length > 0) return tn;\n return \"__tool__\";\n}\n\nfunction normalizeContextSummarizedMode(\n m: unknown,\n): \"llm\" | \"heuristic\" | \"llm+heuristic\" | \"aggressive\" | undefined {\n if (\n m === \"llm\" ||\n m === \"heuristic\" ||\n m === \"llm+heuristic\" ||\n m === \"aggressive\"\n ) {\n return m;\n }\n return undefined;\n}\n\nfunction normalizeContextSummarizedReason(\n r: unknown,\n): \"soft_limit\" | \"forced\" | undefined {\n if (r === \"soft_limit\" || r === \"forced\") return r;\n return undefined;\n}\n\nfunction foldContextSummarized(\n prev: AgentChatUiSegment[],\n event: AgentStreamEvent,\n): AgentChatUiSegment[] {\n const step = asNumber(event[\"step\"], 0);\n const mode = normalizeContextSummarizedMode(event[\"mode\"]);\n const reason = normalizeContextSummarizedReason(event[\"reason\"]);\n const tro = event[\"tokensRemovedEstimate\"];\n const eta = event[\"estimatedTokensAfter\"];\n return [\n ...prev,\n {\n type: \"context_summarized\",\n step,\n ...(mode ? { mode } : {}),\n ...(reason ? { reason } : {}),\n ...(typeof tro === \"number\" && tro > 0\n ? { tokensRemovedEstimate: tro }\n : {}),\n ...(typeof eta === \"number\" && eta > 0\n ? { estimatedTokensAfter: eta }\n : {}),\n },\n ];\n}\n\n/** Concatenate `text` segments (ignores reasoning/tools). */\nexport function collectAssistantTextFromUiSegments(\n segments: AgentChatUiSegment[],\n): string {\n return segments\n .filter((s): s is { type: \"text\"; content: string } => s.type === \"text\")\n .map((s) => s.content)\n .join(\"\");\n}\n\n/**\n * Pure fold: one SSE event → next segment list. Matches `useEngineIDEAgent` / `useIDEAgent`\n * behavior for token gating while a tool is in the `started` state.\n */\nexport function foldAgentStreamIntoUiSegments(\n prev: AgentChatUiSegment[],\n event: AgentStreamEvent,\n): AgentChatUiSegment[] {\n switch (event.type) {\n case \"token\": {\n const last = prev[prev.length - 1];\n if (lastToolBlocksStream(last)) return prev;\n const token = asString(event[\"token\"]);\n if (!token) return prev;\n if (last?.type === \"text\") {\n return [\n ...prev.slice(0, -1),\n { type: \"text\", content: last.content + token },\n ];\n }\n return [...prev, { type: \"text\", content: token }];\n }\n case \"reasoning_token\": {\n const last = prev[prev.length - 1];\n if (lastToolBlocksStream(last)) return prev;\n const token = asString(event[\"token\"]);\n if (!token) return prev;\n if (last?.type === \"reasoning\") {\n return [\n ...prev.slice(0, -1),\n { type: \"reasoning\", content: last.content + token },\n ];\n }\n return [...prev, { type: \"reasoning\", content: token }];\n }\n case \"tool:call\": {\n const id = toolSegmentId(event);\n const toolName = asString(event[\"toolName\"], \"tool\");\n const argsRaw = event[\"args\"];\n const args =\n argsRaw !== null &&\n typeof argsRaw === \"object\" &&\n !Array.isArray(argsRaw)\n ? (argsRaw as Record<string, unknown>)\n : undefined;\n return [\n ...prev,\n {\n type: \"tool\",\n id,\n toolName,\n status: \"started\",\n ...(args !== undefined ? { args } : {}),\n },\n ];\n }\n case \"tool:args_update\": {\n const nodeId = asString(event[\"nodeId\"]);\n const patch = recordFromUnknown(event[\"args\"]);\n return prev.map((seg) => {\n if (seg.type !== \"tool\" || seg.id !== nodeId) return seg;\n const merged = { ...recordFromUnknown(seg.args), ...patch };\n return {\n ...seg,\n args: merged,\n };\n });\n }\n case \"tool:result\": {\n const nodeId = asString(event[\"nodeId\"]);\n const toolName =\n asString(event[\"toolName\"]) || asString(event[\"nodeId\"]);\n const durationMs =\n typeof event[\"durationMs\"] === \"number\" ? event[\"durationMs\"] : undefined;\n const resultStr =\n typeof event[\"result\"] === \"string\" ? event[\"result\"] : undefined;\n\n let idx = -1;\n if (nodeId) {\n for (let i = prev.length - 1; i >= 0; i--) {\n const s = prev[i]!;\n if (\n s.type === \"tool\" &&\n s.status === \"started\" &&\n s.id === nodeId\n ) {\n idx = i;\n break;\n }\n }\n }\n if (idx < 0 && toolName) {\n for (let i = prev.length - 1; i >= 0; i--) {\n const s = prev[i]!;\n if (\n s.type === \"tool\" &&\n s.status === \"started\" &&\n s.toolName === toolName\n ) {\n idx = i;\n break;\n }\n }\n }\n if (idx < 0) return prev;\n const next = [...prev];\n const seg = next[idx]!;\n if (seg.type !== \"tool\") return prev;\n next[idx] = {\n ...seg,\n status: \"completed\",\n ...(durationMs !== undefined ? { durationMs } : {}),\n ...(resultStr !== undefined ? { result: resultStr } : {}),\n };\n return next;\n }\n case \"context_summarized\":\n return foldContextSummarized(prev, event);\n case \"llm_step\": {\n return [\n ...prev,\n {\n type: \"llm_step\",\n step: Number(event[\"step\"]),\n inputTokens: Number(event[\"inputTokens\"] ?? 0),\n outputTokens: Number(event[\"outputTokens\"] ?? 0),\n ...(typeof event[\"cachedPromptTokens\"] === \"number\"\n ? { cachedPromptTokens: event[\"cachedPromptTokens\"] }\n : {}),\n ...(typeof event[\"cacheCreationInputTokens\"] === \"number\"\n ? { cacheCreationInputTokens: event[\"cacheCreationInputTokens\"] }\n : {}),\n creditsEstimated: Number(event[\"creditsEstimated\"] ?? 0),\n ...(typeof event[\"apiCostUsd\"] === \"number\" &&\n Number.isFinite(event[\"apiCostUsd\"])\n ? { apiCostUsd: event[\"apiCostUsd\"] }\n : {}),\n ...(typeof event[\"provider\"] === \"string\" && event[\"provider\"]\n ? { provider: event[\"provider\"] }\n : {}),\n },\n ];\n }\n default:\n return prev;\n }\n}\n\n/**\n * Merge live segments with the terminal `done` payload (optional `stop_reason` segment),\n * and build the persisted assistant message — same shape as dashboard `ChatMessageData` for `ai`.\n */\nexport function finalizeAgentChatUiTurn(\n segments: AgentChatUiSegment[],\n done: AgentChatStreamDonePayload,\n): {\n segments: AgentChatUiSegment[];\n message: AgentChatUiAssistantMessage;\n} {\n let segs: AgentChatUiSegment[] | undefined =\n segments.length > 0 ? [...segments] : undefined;\n if (done.stopReason) {\n const stopSeg: AgentChatUiSegment = {\n type: \"stop_reason\",\n content: done.stopReason,\n finishReason: done.finishReason ?? \"error\",\n };\n segs = segs ? [...segs, stopSeg] : [stopSeg];\n }\n const fromText = segs\n ? collectAssistantTextFromUiSegments(segs)\n : \"\";\n const content =\n done.response ||\n fromText ||\n \"No response.\";\n\n const message: AgentChatUiAssistantMessage = {\n role: \"ai\",\n content,\n ...(segs && segs.length > 0 ? { segments: segs } : {}),\n finishReason: done.finishReason ?? null,\n ...(Array.isArray(done.completionProviders) &&\n done.completionProviders.length > 0\n ? { completionProviders: done.completionProviders }\n : {}),\n ...(typeof done.agentSteps === \"number\" &&\n Number.isFinite(done.agentSteps) &&\n done.agentSteps > 0\n ? { agentSteps: Math.floor(done.agentSteps) }\n : {}),\n usage: {\n inputTokens: done.inputTokens ?? 0,\n outputTokens: done.outputTokens ?? 0,\n creditsCharged: done.creditsCharged ?? 0,\n ...(typeof done.cachedPromptTokens === \"number\" &&\n done.cachedPromptTokens > 0\n ? { cachedPromptTokens: done.cachedPromptTokens }\n : {}),\n ...(typeof done.cacheCreationInputTokens === \"number\" &&\n done.cacheCreationInputTokens > 0\n ? { cacheCreationInputTokens: done.cacheCreationInputTokens }\n : {}),\n },\n ...(typeof done.totalDurationMs === \"number\" && done.totalDurationMs > 0\n ? { durationMs: done.totalDurationMs }\n : {}),\n };\n\n return { segments: segs ?? [], message };\n}\n\n/**\n * Consume a stream and drive dashboard-style UI state: {@link AgentChatStreamUiHandlers.onSegments}\n * / {@link AgentChatStreamUiHandlers.onStreamingText} mirror `AgentChat`’s `streamingSegments` /\n * `streamingContent`; the returned {@link AgentChatUiStreamResult.message} is ready to append\n * to history like `useEngineIDEAgent` does on `done`.\n */\nexport async function runAgentChatStreamForUi(\n source: AsyncIterable<AgentStreamEvent>,\n handlers: AgentChatStreamUiHandlers = {},\n options: RunAgentChatStreamOptions = {},\n): Promise<AgentChatUiStreamResult> {\n const { signal } = options;\n let segments: AgentChatUiSegment[] = [];\n let donePayload: AgentChatStreamDonePayload | null = null;\n\n try {\n for await (const event of source) {\n assertAborted(signal);\n handlers.onEvent?.(event);\n\n const info = parseAgentStreamAgentInfo(event);\n if (info) {\n handlers.onAgentInfo?.(info);\n continue;\n }\n\n if (event.type === \"ping\") continue;\n\n if (event.type === \"done\") {\n const parsed = parseAgentStreamDone(event);\n if (parsed) {\n donePayload = parsed;\n handlers.onDone?.(parsed);\n }\n break;\n }\n\n const next = foldAgentStreamIntoUiSegments(segments, event);\n if (next !== segments) {\n segments = next;\n handlers.onSegments?.(segments);\n if (event.type === \"token\") {\n handlers.onStreamingText?.(\n collectAssistantTextFromUiSegments(segments),\n );\n }\n }\n }\n } catch (err) {\n handlers.onError?.(err);\n throw err;\n }\n\n if (!donePayload) {\n const err = new RagableError(\n \"Agent stream ended without a done event\",\n 502,\n { code: \"SDK_AGENT_STREAM_INCOMPLETE\" },\n );\n handlers.onError?.(err);\n throw err;\n }\n\n const segmentsMidTurn = [...segments];\n const { segments: finalSegs, message } = finalizeAgentChatUiTurn(\n segments,\n donePayload,\n );\n\n const result: AgentChatUiStreamResult = {\n segmentsMidTurn,\n segments: finalSegs,\n message,\n done: donePayload,\n };\n handlers.onComplete?.(result);\n return result;\n}\n","/**\n * Shared SSE parsing for `data: {json}` lines (Ragable agent streams).\n */\nexport type SseJsonEvent = Record<string, unknown> & { type: string };\n\nexport async function parseMaybeJsonBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n return await response.json();\n } catch {\n return null;\n }\n }\n try {\n return await response.text();\n } catch {\n return null;\n }\n}\n\nexport function parseSseDataLine(line: string): SseJsonEvent | null {\n const dataPrefix = \"data: \";\n if (!line.startsWith(dataPrefix)) {\n return null;\n }\n const json = line.slice(dataPrefix.length).trim();\n if (json.length === 0 || json === \"[DONE]\") {\n return null;\n }\n try {\n return JSON.parse(json) as SseJsonEvent;\n } catch {\n return null;\n }\n}\n\n/**\n * Read an SSE body and yield parsed `data:` JSON objects (double-newline framed).\n */\nexport async function* readSseStream(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<SseJsonEvent, void, undefined> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n\n let boundary = buffer.indexOf(\"\\n\\n\");\n while (boundary !== -1) {\n const block = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n for (const line of block.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n boundary = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n if (buffer.trim().length > 0) {\n for (const line of buffer.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import {\r\n bindFetch,\r\n RagableAbortError,\r\n RagableError,\r\n RagableNetworkError,\r\n RagableTimeoutError,\r\n extractErrorMessage,\r\n} from \"./request-client\";\r\n\r\n// ─── Types ───────────────────────────────────────────────────────────────────\r\n\r\nexport type HttpMethod = \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\" | \"HEAD\";\r\n\r\nexport interface RetryOptions {\r\n maxRetries: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n retryOn: number[];\r\n respectRetryAfter: boolean;\r\n}\r\n\r\nexport interface TransportOptions {\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n retry?: Partial<RetryOptions>;\r\n timeoutMs?: number;\r\n onRequest?: (req: TransportRequest) => void;\r\n onResponse?: (req: TransportRequest, res: Response, durationMs: number) => void;\r\n onRetry?: (req: TransportRequest, attempt: number, delayMs: number, reason: string) => void;\r\n}\r\n\r\nexport interface TransportRequest {\r\n url: string;\r\n method: HttpMethod;\r\n headers: Headers;\r\n body?: BodyInit;\r\n signal?: AbortSignal;\r\n idempotencyKey?: string;\r\n retry?: Partial<RetryOptions>;\r\n timeoutMs?: number;\r\n}\r\n\r\n// ─── Defaults ────────────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_RETRY: RetryOptions = {\r\n maxRetries: 3,\r\n baseDelayMs: 200,\r\n maxDelayMs: 5_000,\r\n retryOn: [408, 425, 429, 502, 503, 504],\r\n respectRetryAfter: true,\r\n};\r\n\r\nconst DEFAULT_TIMEOUT_MS = 30_000;\r\n\r\n// ─── Helpers ─────────────────────────────────────────────────────────────────\r\n\r\nfunction jitteredDelay(base: number, attempt: number, max: number): number {\r\n const exp = Math.min(base * 2 ** attempt, max);\r\n return Math.round(exp * (0.5 + Math.random() * 0.5));\r\n}\r\n\r\nfunction parseRetryAfter(header: string | null): number | null {\r\n if (!header) return null;\r\n const seconds = Number(header);\r\n if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1000;\r\n const date = Date.parse(header);\r\n if (Number.isFinite(date)) return Math.max(0, date - Date.now());\r\n return null;\r\n}\r\n\r\nlet _uuidCounter = 0;\r\nexport function generateIdempotencyKey(): string {\r\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\r\n return crypto.randomUUID();\r\n }\r\n _uuidCounter++;\r\n return `idk-${Date.now()}-${_uuidCounter}-${Math.random().toString(36).slice(2, 10)}`;\r\n}\r\n\r\nfunction requestCacheKey(req: TransportRequest): string {\r\n // Scope in-flight dedupe by principal AND target database instance: two\r\n // concurrent same-URL GETs issued under different bearer tokens (a sign-out /\r\n // sign-in race) or against different instances must NOT collapse into one\r\n // shared response, or a caller could receive data authorized as another\r\n // principal or from the wrong instance.\r\n const auth = req.headers.get(\"authorization\") ?? \"\";\r\n const dbInstance = req.headers.get(\"x-database-instance-id\") ?? \"\";\r\n return `${req.method}:${req.url}\\n${auth}\\n${dbInstance}`;\r\n}\r\n\r\n// ─── Transport ───────────────────────────────────────────────────────────────\r\n\r\nexport class Transport {\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultHeaders: HeadersInit | undefined;\r\n private readonly defaultRetry: RetryOptions;\r\n private readonly defaultTimeoutMs: number;\r\n private readonly onRequest?: TransportOptions[\"onRequest\"];\r\n private readonly onResponse?: TransportOptions[\"onResponse\"];\r\n private readonly onRetry?: TransportOptions[\"onRetry\"];\r\n\r\n private readonly inflightGets = new Map<string, Promise<Response>>();\r\n\r\n private _refreshHandler: (() => Promise<string | null>) | null = null;\r\n\r\n constructor(options: TransportOptions = {}) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n this.defaultHeaders = options.headers;\r\n this.defaultRetry = { ...DEFAULT_RETRY, ...options.retry };\r\n this.defaultTimeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\r\n this.onRequest = options.onRequest;\r\n this.onResponse = options.onResponse;\r\n this.onRetry = options.onRetry;\r\n }\r\n\r\n setRefreshHandler(handler: (() => Promise<string | null>) | null): void {\r\n this._refreshHandler = handler;\r\n }\r\n\r\n async execute(req: TransportRequest): Promise<Response> {\r\n if (req.method === \"GET\") {\r\n const key = requestCacheKey(req);\r\n let base = this.inflightGets.get(key);\r\n if (!base) {\r\n base = this._executeWithRetry(req);\r\n this.inflightGets.set(key, base);\r\n const clear = () => {\r\n if (this.inflightGets.get(key) === base) this.inflightGets.delete(key);\r\n };\r\n base.then(clear, clear);\r\n }\r\n // Hand every awaiter (including the first) an independent clone. A Response\r\n // body is single-read; returning the same Response to concurrent callers\r\n // makes the second `.text()`/`.json()` throw \"body stream already read\"\r\n // (guaranteed under React 18 StrictMode double-effects). The cached `base`\r\n // Response is never read directly, so cloning it stays valid.\r\n return base.then((r) => r.clone());\r\n }\r\n return this._executeWithRetry(req);\r\n }\r\n\r\n private async _executeWithRetry(req: TransportRequest): Promise<Response> {\r\n const retryOpts: RetryOptions = {\r\n ...this.defaultRetry,\r\n ...req.retry,\r\n };\r\n const timeoutMs = req.timeoutMs ?? this.defaultTimeoutMs;\r\n\r\n const headers = new Headers(this.defaultHeaders);\r\n req.headers.forEach((v, k) => headers.set(k, v));\r\n if (req.idempotencyKey) {\r\n headers.set(\"Idempotency-Key\", req.idempotencyKey);\r\n }\r\n\r\n const finalReq: TransportRequest = { ...req, headers };\r\n\r\n this.onRequest?.(finalReq);\r\n\r\n let lastError: unknown;\r\n const maxAttempts = 1 + retryOpts.maxRetries;\r\n let did401Refresh = false;\r\n\r\n // Only auto-retry methods that are safe to repeat. The backend does not yet\r\n // honor Idempotency-Key on data writes, so retrying a POST/PATCH/PUT/DELETE\r\n // that may have already been applied (a 502/504 after the gateway committed\r\n // it, or a lost response) would double-apply the write. Writes retry only\r\n // when the caller explicitly opts in via `req.retry` (e.g. a known-idempotent\r\n // endpoint). The 401-refresh path below is exempt: a 401 means the request\r\n // was rejected, not applied, so re-authing and retrying once is always safe.\r\n const isIdempotent = req.method === \"GET\" || req.method === \"HEAD\";\r\n const retryEnabled = retryOpts.maxRetries > 0 && (isIdempotent || req.retry !== undefined);\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n try {\r\n const response = await this._singleFetch(finalReq, timeoutMs);\r\n\r\n if (response.status === 401 && this._refreshHandler && !did401Refresh) {\r\n did401Refresh = true;\r\n const newToken = await this._refreshHandler();\r\n if (newToken) {\r\n finalReq.headers.set(\"Authorization\", `Bearer ${newToken}`);\r\n attempt--;\r\n continue;\r\n }\r\n }\r\n\r\n if (retryEnabled && !response.ok && retryOpts.retryOn.includes(response.status) && attempt < maxAttempts - 1) {\r\n let delayMs = jitteredDelay(retryOpts.baseDelayMs, attempt, retryOpts.maxDelayMs);\r\n if (retryOpts.respectRetryAfter) {\r\n const ra = parseRetryAfter(response.headers.get(\"retry-after\"));\r\n if (ra !== null) delayMs = Math.min(ra, retryOpts.maxDelayMs);\r\n }\r\n this.onRetry?.(finalReq, attempt + 1, delayMs, `HTTP ${response.status}`);\r\n await sleep(delayMs);\r\n continue;\r\n }\r\n\r\n return response;\r\n } catch (e) {\r\n if (e instanceof RagableAbortError || e instanceof RagableTimeoutError) {\r\n throw e;\r\n }\r\n lastError = e;\r\n if (retryEnabled && attempt < maxAttempts - 1) {\r\n const delayMs = jitteredDelay(retryOpts.baseDelayMs, attempt, retryOpts.maxDelayMs);\r\n this.onRetry?.(finalReq, attempt + 1, delayMs, (e as Error).message);\r\n await sleep(delayMs);\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n throw lastError instanceof RagableNetworkError\r\n ? lastError\r\n : new RagableNetworkError(\r\n (lastError as Error)?.message ?? \"Network request failed\",\r\n lastError,\r\n );\r\n }\r\n\r\n private async _singleFetch(req: TransportRequest, timeoutMs: number): Promise<Response> {\r\n const controller = new AbortController();\r\n const signals: AbortSignal[] = [controller.signal];\r\n if (req.signal) signals.push(req.signal);\r\n\r\n const combinedSignal = signals.length === 1\r\n ? controller.signal\r\n : AbortSignal.any\r\n ? AbortSignal.any(signals)\r\n : controller.signal;\r\n\r\n if (req.signal?.aborted) {\r\n throw new RagableAbortError();\r\n }\r\n\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n const externalAbortHandler = req.signal\r\n ? () => controller.abort()\r\n : null;\r\n if (externalAbortHandler && req.signal) {\r\n req.signal.addEventListener(\"abort\", externalAbortHandler, { once: true });\r\n }\r\n\r\n const start = Date.now();\r\n try {\r\n const response = await this.fetchImpl(req.url, {\r\n method: req.method,\r\n headers: req.headers,\r\n body: req.body,\r\n signal: combinedSignal,\r\n });\r\n this.onResponse?.(req, response, Date.now() - start);\r\n return response;\r\n } catch (e) {\r\n if ((e as Error).name === \"AbortError\") {\r\n if (req.signal?.aborted) throw new RagableAbortError();\r\n throw new RagableTimeoutError(timeoutMs);\r\n }\r\n throw new RagableNetworkError((e as Error).message, e);\r\n } finally {\r\n clearTimeout(timer);\r\n if (externalAbortHandler && req.signal) {\r\n req.signal.removeEventListener(\"abort\", externalAbortHandler);\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function parseTransportResponse<T>(response: Response): Promise<T> {\r\n if (response.status === 204) return null as T;\r\n const text = await response.text();\r\n if (!text) return null as T;\r\n let payload: unknown;\r\n try {\r\n payload = JSON.parse(text);\r\n } catch {\r\n if (!response.ok) {\r\n throw new RagableError(text.slice(0, 200), response.status, null);\r\n }\r\n return text as T;\r\n }\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n}\r\n","import { RagableError, RagableSdkError } from \"./request-client\";\r\nimport type {\r\n ColumnName,\r\n ColumnValue,\r\n DefaultRagableDatabase,\r\n RagableDatabase,\r\n RagableTableNames,\r\n TableInsertRow,\r\n TableRow,\r\n TableUpdatePatch,\r\n} from \"./database-schema\";\r\nimport { generateIdempotencyKey } from \"./transport\";\r\n\r\n// ─── Legacy types kept for backward compat (raw SQL path) ────────────────────\r\n\r\n/** @deprecated Kept for backward compat with `database.query()`. Not used by PostgREST path. */\r\nexport interface BrowserSqlExecParams {\r\n databaseInstanceId: string;\r\n sql: string;\r\n params?: unknown[];\r\n readOnly?: boolean;\r\n timeoutMs?: number;\r\n rowLimit?: number;\r\n}\r\n\r\n/** @deprecated Kept for backward compat with `database.query()`. Not used by PostgREST path. */\r\nexport interface BrowserSqlExecResult<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> {\r\n command: string;\r\n rowCount: number;\r\n truncated: boolean;\r\n rows: Row[];\r\n}\r\n\r\n/** @deprecated Use PostgRESTFetch instead. Kept for `database.query()` backward compat. */\r\nexport type RunQuery = <\r\n R extends Record<string, unknown> = Record<string, unknown>,\r\n>(\r\n p: BrowserSqlExecParams,\r\n) => Promise<BrowserSqlExecResult<R>>;\r\n\r\n// ─── PostgREST HTTP transport ────────────────────────────────────────────────\r\n\r\nexport interface PostgRESTFetchParams {\r\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\r\n table: string;\r\n searchParams: URLSearchParams;\r\n body?: unknown;\r\n headers?: Record<string, string>;\r\n databaseInstanceId: string;\r\n signal?: AbortSignal;\r\n idempotencyKey?: string;\r\n}\r\n\r\nexport type PostgRESTFetch = (\r\n params: PostgRESTFetchParams,\r\n) => Promise<Response>;\r\n\r\n// ─── Result types ────────────────────────────────────────────────────────────\r\n\r\nexport type PostgrestResult<T> =\r\n | {\r\n data: T;\r\n error: null;\r\n }\r\n | {\r\n data: null;\r\n error: RagableError;\r\n };\r\n\r\n/** Discriminated result for easier TypeScript narrowing than `{ data, error }` after destructuring. */\r\nexport type RagableResult<T, E = RagableError> =\r\n | { ok: true; value: T }\r\n | { ok: false; error: E };\r\n\r\nexport function toRagableResult<T>(r: PostgrestResult<T>): RagableResult<T> {\r\n if (r.error) return { ok: false, error: r.error };\r\n return { ok: true, value: r.data };\r\n}\r\n\r\n/**\r\n * Narrows a {@link PostgrestResult} after an `if (result.error)` guard.\r\n * Prefer checking `result.error` on the result object (not destructured `{ data, error }`)\r\n * so TypeScript narrows `data` automatically; use this when you need a throw or assertion.\r\n */\r\nexport function assertPostgrestSuccess<T>(\r\n r: PostgrestResult<T>,\r\n): asserts r is { data: T; error: null } {\r\n if (r.error) throw r.error;\r\n}\r\n\r\n/** Returns `data` or throws `RagableError` / the failure case. */\r\nexport function unwrapPostgrest<T>(r: PostgrestResult<T>): T {\r\n if (r.error) throw r.error;\r\n return r.data;\r\n}\r\n\r\nexport async function asPostgrestResponse<T>(\r\n fn: () => Promise<T>,\r\n): Promise<PostgrestResult<T>> {\r\n try {\r\n const data = await fn();\r\n return { data, error: null };\r\n } catch (e) {\r\n let err: RagableError;\r\n if (e instanceof RagableError) {\r\n err = e;\r\n } else if (e instanceof RagableSdkError) {\r\n err = new RagableError(e.message, 0, { originalError: e.__type, cause: e.message });\r\n } else {\r\n const message =\r\n e instanceof Error ? e.message : typeof e === \"string\" ? e : \"Unknown error\";\r\n err = new RagableError(message, 0, null);\r\n }\r\n return { data: null, error: err };\r\n }\r\n}\r\n\r\n// ─── PostgREST filter operators ──────────────────────────────────────────────\r\n\r\ntype FilterOp = \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"like\" | \"ilike\" | \"is\" | \"in\";\r\n\r\ninterface Filter {\r\n op: FilterOp;\r\n column: string;\r\n value: unknown;\r\n}\r\n\r\nfunction encodeFilterValue(op: FilterOp, value: unknown): string {\r\n if (op === \"is\") return `is.${value}`;\r\n if (op === \"in\") {\r\n const vals = value as unknown[];\r\n return `in.(${vals.map(String).join(\",\")})`;\r\n }\r\n return `${op}.${value}`;\r\n}\r\n\r\n// ─── Response parsing helpers ────────────────────────────────────────────────\r\n\r\nfunction extractPostgRESTErrorMessage(\r\n payload: unknown,\r\n status: number,\r\n statusText: string,\r\n): string {\r\n const st = (statusText ?? \"\").trim();\r\n if (typeof payload !== \"object\" || payload === null) {\r\n return st || `HTTP ${status}`;\r\n }\r\n const p = payload as Record<string, unknown>;\r\n const raw = p.message ?? p.error ?? p.hint;\r\n let msg: string;\r\n if (typeof raw === \"string\") {\r\n msg = raw;\r\n } else if (typeof raw === \"number\" || typeof raw === \"boolean\") {\r\n msg = String(raw);\r\n } else if (raw !== null && raw !== undefined && typeof raw === \"object\") {\r\n msg = JSON.stringify(raw);\r\n } else {\r\n msg = st || `HTTP ${status}`;\r\n }\r\n msg = msg.trim();\r\n if (!msg) return st || `HTTP ${status}`;\r\n return msg;\r\n}\r\n\r\nasync function parsePostgRESTResponse<T>(response: Response): Promise<T> {\r\n if (response.status === 204 && response.ok) return null as T;\r\n\r\n const text = await response.text();\r\n\r\n // An error response with an EMPTY body (e.g. a bare 401/403/500/502 from an\r\n // upstream proxy) must still throw — otherwise it would resolve to\r\n // `{ data: null, error: null }`, indistinguishable from \"no rows\", and the\r\n // app would silently render empty data on an auth failure.\r\n if (!text) {\r\n if (!response.ok) {\r\n throw new RagableError(\r\n response.statusText || `HTTP ${response.status}`,\r\n response.status,\r\n null,\r\n );\r\n }\r\n return null as T;\r\n }\r\n\r\n let payload: unknown;\r\n try {\r\n payload = JSON.parse(text);\r\n } catch {\r\n if (!response.ok) {\r\n throw new RagableError(\r\n extractPostgRESTErrorMessage(text, response.status, response.statusText),\r\n response.status,\r\n null,\r\n );\r\n }\r\n throw new RagableError(\r\n `PostgREST response parse error: ${text.slice(0, 200)}`,\r\n response.status,\r\n null,\r\n );\r\n }\r\n\r\n if (!response.ok) {\r\n const msg = extractPostgRESTErrorMessage(payload, response.status, response.statusText);\r\n throw new RagableError(msg, response.status, payload);\r\n }\r\n\r\n return payload as T;\r\n}\r\n\r\n// ─── Shared filter mixin ─────────────────────────────────────────────────────\r\n\r\ntype FilterableBuilder<\r\n D extends RagableDatabase,\r\n T extends RagableTableNames<D>,\r\n Self,\r\n> = {\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): Self;\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): Self;\r\n match(query: Partial<TableRow<D, T>>): Self;\r\n};\r\n\r\nfunction addFilterMethods<\r\n D extends RagableDatabase,\r\n T extends RagableTableNames<D>,\r\n B extends { filters: Filter[] },\r\n>(builder: B): B & FilterableBuilder<D, T, B> {\r\n const b = builder as B & FilterableBuilder<D, T, B>;\r\n for (const op of [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\", \"like\", \"ilike\"] as const) {\r\n (b as Record<string, unknown>)[op] = function (column: string, value: unknown) {\r\n b.filters.push({ op, column, value });\r\n return b;\r\n };\r\n }\r\n (b as Record<string, unknown>).is = function (column: string, value: null | boolean) {\r\n b.filters.push({ op: \"is\", column, value });\r\n return b;\r\n };\r\n (b as Record<string, unknown>).in = function (column: string, values: unknown[]) {\r\n b.filters.push({ op: \"in\", column, value: values });\r\n return b;\r\n };\r\n (b as Record<string, unknown>).match = function (query: Record<string, unknown>) {\r\n for (const [col, val] of Object.entries(query)) {\r\n if (val === null) {\r\n b.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n b.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return b;\r\n };\r\n return b;\r\n}\r\n\r\n// ─── SELECT builder ──────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Chainable SELECT (PostgREST / Supabase-style). Filters and modifiers apply to the **base**\r\n * table of the query (the table passed to `client.from(...)`); the `select` string controls columns\r\n * and **resource embedding** (joins).\r\n *\r\n * **Joins** use the same embedded `select` syntax as\r\n * [Supabase `.select()`](https://supabase.com/docs/reference/javascript/select) / PostgREST, for example:\r\n * - `*,related_table(*)` — include related rows\r\n * - `related_table!inner(*)` — inner-style embed\r\n * - `related_table!fkey_column_or_constraint(*)` — disambiguate when multiple FKs exist\r\n * - `alias:related_table(*)` — rename the JSON key for the nested object/array\r\n *\r\n * **Ragable limits** (server-side): only **one level** of embedding is supported — no nested\r\n * `relation(nested(...))`. Prefer embed aliases above; top-level column rename forms like\r\n * `alias:column` may not be accepted for scalar columns.\r\n *\r\n * **API note:** Supabase’s second `select(columns, options?)` argument (`count`, `head`, etc.) is\r\n * not supported in Ragable yet; joins use the **first** argument only.\r\n *\r\n * For nested result shapes, pass a type argument on {@link PostgrestTableApi.select}:\r\n * `from('orders').select<OrderWithLines>(\\`*, lines (*)\\`)`.\r\n */\r\nexport class PostgrestSelectBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n D extends RagableDatabase = DefaultRagableDatabase,\r\n T extends RagableTableNames<D> = RagableTableNames<D>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n filters: Filter[] = [];\r\n private _limit?: number;\r\n private _offset?: number;\r\n private _order?: { column: string; ascending: boolean; nullsFirst?: boolean };\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly columns: string,\r\n ) {\r\n addFilterMethods<D, T, this>(this);\r\n }\r\n\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"eq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"neq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"like\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"ilike\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): this {\r\n this.filters.push({ op: \"is\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): this {\r\n this.filters.push({ op: \"in\", column: column as string, value: values });\r\n return this;\r\n }\r\n\r\n match(query: Partial<TableRow<D, T>>): this {\r\n for (const [col, val] of Object.entries(query as Record<string, unknown>)) {\r\n if (val === null) {\r\n this.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n this.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n limit(n: number): this {\r\n this._limit = n;\r\n return this;\r\n }\r\n\r\n offset(n: number): this {\r\n this._offset = n;\r\n return this;\r\n }\r\n\r\n range(from: number, to: number): this {\r\n this._offset = from;\r\n this._limit = to - from + 1;\r\n return this;\r\n }\r\n\r\n order(\r\n column: ColumnName<D, T>,\r\n options?: { ascending?: boolean; nullsFirst?: boolean },\r\n ): this {\r\n this._order = {\r\n column: column as string,\r\n ascending: options?.ascending !== false,\r\n nullsFirst: options?.nullsFirst,\r\n };\r\n return this;\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n private buildSearchParams(): URLSearchParams {\r\n const sp = new URLSearchParams();\r\n if (this.columns && this.columns !== \"*\") {\r\n sp.set(\"select\", this.columns);\r\n }\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n if (this._order) {\r\n let orderStr = `${this._order.column}.${this._order.ascending ? \"asc\" : \"desc\"}`;\r\n if (this._order.nullsFirst === true) orderStr += \".nullsfirst\";\r\n else if (this._order.nullsFirst === false) orderStr += \".nullslast\";\r\n sp.set(\"order\", orderStr);\r\n }\r\n if (this._limit != null) {\r\n sp.set(\"limit\", String(Math.max(0, Math.floor(this._limit))));\r\n }\r\n if (this._offset != null && this._offset > 0) {\r\n sp.set(\"offset\", String(Math.max(0, Math.floor(this._offset))));\r\n }\r\n return sp;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n const response = await this.pgFetch({\r\n method: \"GET\",\r\n table: this.table,\r\n searchParams: this.buildSearchParams(),\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n return asPostgrestResponse(async () => {\r\n const sp = this.buildSearchParams();\r\n const response = await this.pgFetch({\r\n method: \"GET\",\r\n table: this.table,\r\n searchParams: sp,\r\n headers: { Accept: \"application/vnd.pgrst.object+json\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n });\r\n return parsePostgRESTResponse<Row>(response);\r\n });\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── INSERT builders ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Awaitable `{ data: null, error }` chain when `.insert()` is called with invalid extra\r\n * arguments — matches Supabase-style result shapes without throwing.\r\n */\r\nexport class PostgrestInsertSdkErrorRoot<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n constructor(private readonly error: RagableError) {}\r\n\r\n select(_columns = \"*\"): PostgrestInsertSdkErrorReturning<Row> {\r\n return new PostgrestInsertSdkErrorReturning(this.error);\r\n }\r\n\r\n abortSignal(_signal: AbortSignal): this {\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return Promise.resolve({ data: null, error: this.error }).then(onfulfilled, onrejected);\r\n }\r\n}\r\n\r\nexport class PostgrestInsertSdkErrorReturning<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(private readonly error: RagableError) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return Promise.resolve({ data: null, error: this.error }).then(onfulfilled, onrejected);\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n return { data: null, error: this.error };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n return { data: null, error: this.error };\r\n }\r\n}\r\n\r\nexport class PostgrestInsertRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly rows: Record<string, unknown>[],\r\n ) {}\r\n\r\n select(columns = \"*\"): PostgrestInsertReturningBuilder<Row> {\r\n return new PostgrestInsertReturningBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n this.rows,\r\n columns,\r\n this._signal,\r\n );\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n if (this.rows.length === 0) return null;\r\n const body = this.rows.length === 1 ? this.rows[0] : this.rows;\r\n const response = await this.pgFetch({\r\n method: \"POST\",\r\n table: this.table,\r\n searchParams: new URLSearchParams(),\r\n body,\r\n headers: { Prefer: \"return=minimal\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n await parsePostgRESTResponse<null>(response);\r\n return null;\r\n });\r\n }\r\n}\r\n\r\nexport class PostgrestInsertReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly rows: Record<string, unknown>[],\r\n private readonly returning: string,\r\n private readonly _signal?: AbortSignal,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n if (this.rows.length === 0) return [];\r\n const body = this.rows.length === 1 ? this.rows[0] : this.rows;\r\n const sp = new URLSearchParams();\r\n if (this.returning && this.returning !== \"*\") {\r\n sp.set(\"select\", this.returning);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"POST\",\r\n table: this.table,\r\n searchParams: sp,\r\n body,\r\n headers: { Prefer: \"return=representation\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── UPDATE builders ─────────────────────────────────────────────────────────\r\n\r\nexport class PostgrestUpdateRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n D extends RagableDatabase = DefaultRagableDatabase,\r\n T extends RagableTableNames<D> = RagableTableNames<D>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n filters: Filter[] = [];\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly patch: Record<string, unknown>,\r\n ) {}\r\n\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"eq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"neq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"like\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"ilike\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): this {\r\n this.filters.push({ op: \"is\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): this {\r\n this.filters.push({ op: \"in\", column: column as string, value: values });\r\n return this;\r\n }\r\n\r\n match(query: Partial<TableRow<D, T>>): this {\r\n for (const [col, val] of Object.entries(query as Record<string, unknown>)) {\r\n if (val === null) {\r\n this.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n this.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n select(columns = \"*\"): PostgrestUpdateReturningBuilder<Row> {\r\n return new PostgrestUpdateReturningBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n this.patch,\r\n this.filters,\r\n columns,\r\n this._signal,\r\n );\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private buildSearchParams(): URLSearchParams {\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n return sp;\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n const keys = Object.keys(this.patch);\r\n if (keys.length === 0) {\r\n throw new RagableError(\"Empty update payload\", 400, null);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"PATCH\",\r\n table: this.table,\r\n searchParams: this.buildSearchParams(),\r\n body: this.patch,\r\n headers: { Prefer: \"return=minimal\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n await parsePostgRESTResponse<null>(response);\r\n return null;\r\n });\r\n }\r\n}\r\n\r\nexport class PostgrestUpdateReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly patch: Record<string, unknown>,\r\n private readonly filters: Filter[],\r\n private readonly returning: string,\r\n private readonly _signal?: AbortSignal,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n const keys = Object.keys(this.patch);\r\n if (keys.length === 0) {\r\n throw new RagableError(\"Empty update payload\", 400, null);\r\n }\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n if (this.returning && this.returning !== \"*\") {\r\n sp.set(\"select\", this.returning);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"PATCH\",\r\n table: this.table,\r\n searchParams: sp,\r\n body: this.patch,\r\n headers: { Prefer: \"return=representation\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── DELETE builders ─────────────────────────────────────────────────────────\r\n\r\nexport class PostgrestDeleteRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n D extends RagableDatabase = DefaultRagableDatabase,\r\n T extends RagableTableNames<D> = RagableTableNames<D>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n filters: Filter[] = [];\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n ) {}\r\n\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"eq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"neq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"like\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"ilike\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): this {\r\n this.filters.push({ op: \"is\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): this {\r\n this.filters.push({ op: \"in\", column: column as string, value: values });\r\n return this;\r\n }\r\n\r\n match(query: Partial<TableRow<D, T>>): this {\r\n for (const [col, val] of Object.entries(query as Record<string, unknown>)) {\r\n if (val === null) {\r\n this.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n this.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n select(columns = \"*\"): PostgrestDeleteReturningBuilder<Row> {\r\n return new PostgrestDeleteReturningBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n this.filters,\r\n columns,\r\n this._signal,\r\n );\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n const response = await this.pgFetch({\r\n method: \"DELETE\",\r\n table: this.table,\r\n searchParams: sp,\r\n headers: { Prefer: \"return=minimal\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n await parsePostgRESTResponse<null>(response);\r\n return null;\r\n });\r\n }\r\n}\r\n\r\nexport class PostgrestDeleteReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly filters: Filter[],\r\n private readonly returning: string,\r\n private readonly _signal?: AbortSignal,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n if (this.returning && this.returning !== \"*\") {\r\n sp.set(\"select\", this.returning);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"DELETE\",\r\n table: this.table,\r\n searchParams: sp,\r\n headers: { Prefer: \"return=representation\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── UPSERT builders ─────────────────────────────────────────────────────────\r\n\r\nexport interface PostgrestUpsertOptions {\r\n onConflict: string;\r\n ignoreDuplicates?: boolean;\r\n}\r\n\r\nexport class PostgrestUpsertRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly rows: Record<string, unknown>[],\r\n private readonly onConflict: string,\r\n private readonly ignoreDuplicates: boolean,\r\n ) {}\r\n\r\n select(columns = \"*\"): PostgrestUpsertReturningBuilder<Row> {\r\n return new PostgrestUpsertReturningBuilder(this, columns);\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n await this.runUpsert(\"return=minimal\", null);\r\n return null;\r\n });\r\n }\r\n\r\n async runUpsert(\r\n prefer: string,\r\n selectCols: string | null,\r\n ): Promise<Row[]> {\r\n if (this.rows.length === 0) return [];\r\n\r\n const body = this.rows.length === 1 ? this.rows[0] : this.rows;\r\n const sp = new URLSearchParams();\r\n sp.set(\"on_conflict\", this.onConflict);\r\n if (selectCols && selectCols !== \"*\") {\r\n sp.set(\"select\", selectCols);\r\n }\r\n\r\n const resolution = this.ignoreDuplicates\r\n ? \"resolution=ignore-duplicates\"\r\n : \"resolution=merge-duplicates\";\r\n\r\n const response = await this.pgFetch({\r\n method: \"POST\",\r\n table: this.table,\r\n searchParams: sp,\r\n body,\r\n headers: { Prefer: `${prefer},${resolution}` },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n\r\n if (prefer.includes(\"return=minimal\")) {\r\n await parsePostgRESTResponse<null>(response);\r\n return [];\r\n }\r\n\r\n return parsePostgRESTResponse<Row[]>(response);\r\n }\r\n}\r\n\r\nexport class PostgrestUpsertReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly root: PostgrestUpsertRootBuilder<Row>,\r\n private readonly returning: string,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n return this.root.runUpsert(\"return=representation\", this.returning);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── Table entry point ───────────────────────────────────────────────────────\r\n\r\nexport class PostgrestTableApi<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n TableName extends RagableTableNames<Database> = RagableTableNames<Database>,\r\n> {\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: TableName extends string ? string : string,\r\n ) {}\r\n\r\n /**\r\n * Start a SELECT. Pass a PostgREST `select` string; use embedded resources for joins — see\r\n * {@link PostgrestSelectBuilder}.\r\n *\r\n * @param columns Column list and optional embeds (default `\"*\"`). Omitted or `\"*\"` means all base columns.\r\n * @typeParam RowResult Row shape returned by the query; defaults to this table’s `Row`. Override when using joins.\r\n */\r\n select<\r\n RowResult extends Record<string, unknown> = TableRow<Database, TableName>,\r\n >(columns = \"*\"): PostgrestSelectBuilder<RowResult, Database, TableName> {\r\n return new PostgrestSelectBuilder<RowResult, Database, TableName>(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n columns,\r\n );\r\n }\r\n\r\n insert(\r\n values:\r\n | TableInsertRow<Database, TableName>\r\n | TableInsertRow<Database, TableName>[],\r\n ...rest: unknown[]\r\n ): PostgrestInsertRootBuilder<TableRow<Database, TableName>> {\r\n if (rest.length > 0) {\r\n const err = new RagableError(\r\n \".insert() accepts only one argument: the row object or an array of rows. \" +\r\n \"Do not pass readOnly, options, or a second object — those apply only to database.query({ sql, readOnly }). \" +\r\n \"PostgREST inserts are writes by default.\",\r\n 400,\r\n { code: \"SDK_INSERT_EXTRA_ARGS\" },\r\n );\r\n return new PostgrestInsertSdkErrorRoot<TableRow<Database, TableName>>(\r\n err,\r\n ) as unknown as PostgrestInsertRootBuilder<TableRow<Database, TableName>>;\r\n }\r\n const rows = (Array.isArray(values) ? values : [values]) as Record<\r\n string,\r\n unknown\r\n >[];\r\n return new PostgrestInsertRootBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n rows,\r\n );\r\n }\r\n\r\n update(\r\n patch: TableUpdatePatch<Database, TableName>,\r\n ): PostgrestUpdateRootBuilder<TableRow<Database, TableName>, Database, TableName> {\r\n return new PostgrestUpdateRootBuilder<TableRow<Database, TableName>, Database, TableName>(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n patch as Record<string, unknown>,\r\n );\r\n }\r\n\r\n delete(): PostgrestDeleteRootBuilder<TableRow<Database, TableName>, Database, TableName> {\r\n return new PostgrestDeleteRootBuilder<TableRow<Database, TableName>, Database, TableName>(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n );\r\n }\r\n\r\n upsert(\r\n values:\r\n | TableInsertRow<Database, TableName>\r\n | TableInsertRow<Database, TableName>[],\r\n options: PostgrestUpsertOptions,\r\n ): PostgrestUpsertRootBuilder<TableRow<Database, TableName>> {\r\n const rows = (Array.isArray(values) ? values : [values]) as Record<\r\n string,\r\n unknown\r\n >[];\r\n return new PostgrestUpsertRootBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n rows,\r\n options.onConflict,\r\n options.ignoreDuplicates === true,\r\n );\r\n }\r\n}\r\n","// ─── SessionStorage interface ────────────────────────────────────────────────\n\nexport interface SessionStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\n// ─── Adapters ────────────────────────────────────────────────────────────────\n\nexport class LocalStorageAdapter implements SessionStorage {\n getItem(key: string): string | null {\n try {\n return globalThis.localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n setItem(key: string, value: string): void {\n try {\n globalThis.localStorage.setItem(key, value);\n } catch { /* quota exceeded or blocked — best effort */ }\n }\n\n removeItem(key: string): void {\n try {\n globalThis.localStorage.removeItem(key);\n } catch { /* noop */ }\n }\n}\n\nexport class SessionStorageAdapter implements SessionStorage {\n getItem(key: string): string | null {\n try {\n return globalThis.sessionStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n setItem(key: string, value: string): void {\n try {\n globalThis.sessionStorage.setItem(key, value);\n } catch { /* noop */ }\n }\n\n removeItem(key: string): void {\n try {\n globalThis.sessionStorage.removeItem(key);\n } catch { /* noop */ }\n }\n}\n\nexport class MemoryStorageAdapter implements SessionStorage {\n private store = new Map<string, string>();\n\n getItem(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n removeItem(key: string): void {\n this.store.delete(key);\n }\n}\n\nexport class CookieStorageAdapter implements SessionStorage {\n constructor(\n private readonly maxAge = 30 * 24 * 60 * 60,\n private readonly path = \"/\",\n private readonly sameSite: \"Lax\" | \"Strict\" | \"None\" = \"Lax\",\n ) {}\n\n getItem(key: string): string | null {\n if (typeof document === \"undefined\") return null;\n const match = document.cookie\n .split(\"; \")\n .find((c) => c.startsWith(`${encodeURIComponent(key)}=`));\n if (!match) return null;\n return decodeURIComponent(match.split(\"=\").slice(1).join(\"=\"));\n }\n\n setItem(key: string, value: string): void {\n if (typeof document === \"undefined\") return;\n const parts = [\n `${encodeURIComponent(key)}=${encodeURIComponent(value)}`,\n `path=${this.path}`,\n `max-age=${this.maxAge}`,\n `SameSite=${this.sameSite}`,\n ];\n if (this.sameSite === \"None\") parts.push(\"Secure\");\n document.cookie = parts.join(\"; \");\n }\n\n removeItem(key: string): void {\n if (typeof document === \"undefined\") return;\n document.cookie = `${encodeURIComponent(key)}=; path=${this.path}; max-age=0`;\n }\n}\n\n// ─── Default storage detection ───────────────────────────────────────────────\n\nexport function detectStorage(): SessionStorage {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.localStorage !== \"undefined\") {\n try {\n const testKey = \"__ragable_test__\";\n globalThis.localStorage.setItem(testKey, \"1\");\n globalThis.localStorage.removeItem(testKey);\n return new LocalStorageAdapter();\n } catch { /* blocked */ }\n }\n return new MemoryStorageAdapter();\n}\n\n// ─── BroadcastChannel helper ─────────────────────────────────────────────────\n\nexport type AuthBroadcastMessage =\n | { type: \"SESSION_UPDATED\"; payload: string }\n | { type: \"SESSION_REMOVED\" };\n\nexport class AuthBroadcastChannel {\n private channel: BroadcastChannel | null = null;\n\n constructor(channelName: string) {\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n this.channel = new BroadcastChannel(channelName);\n } catch { /* unsupported */ }\n }\n }\n\n onMessage(cb: (msg: AuthBroadcastMessage) => void): void {\n if (this.channel) {\n this.channel.onmessage = (e: MessageEvent) => {\n const data = e.data as AuthBroadcastMessage;\n if (data && typeof data.type === \"string\") {\n cb(data);\n }\n };\n }\n }\n\n postSessionUpdated(serialized: string): void {\n this.channel?.postMessage({ type: \"SESSION_UPDATED\", payload: serialized } satisfies AuthBroadcastMessage);\n }\n\n postSessionRemoved(): void {\n this.channel?.postMessage({ type: \"SESSION_REMOVED\" } satisfies AuthBroadcastMessage);\n }\n\n close(): void {\n this.channel?.close();\n this.channel = null;\n }\n}\n","import {\r\n bindFetch,\r\n DEFAULT_RAGABLE_API_BASE,\r\n extractErrorMessage,\r\n RagableError,\r\n} from \"./request-client\";\r\nimport type {\r\n SessionStorage,\r\n} from \"./auth-storage\";\r\nimport {\r\n AuthBroadcastChannel,\r\n detectStorage,\r\n} from \"./auth-storage\";\r\nimport {\r\n asPostgrestResponse,\r\n type PostgrestResult,\r\n} from \"./browser-postgrest\";\r\n\r\n// ─── Types ───────────────────────────────────────────────────────────────────\r\n\r\nexport type AuthChangeEvent =\r\n | \"INITIAL_SESSION\"\r\n | \"SIGNED_IN\"\r\n | \"SIGNED_OUT\"\r\n | \"TOKEN_REFRESHED\"\r\n | \"TOKEN_REFRESH_FAILED\"\r\n | \"USER_UPDATED\";\r\n\r\n/**\r\n * Outcome of a low-level refresh attempt. `terminal` distinguishes a definitively\r\n * rejected refresh token (the server said 400/401/403 — purge the session) from a\r\n * transient failure (offline, 5xx, timeout — keep the session and let a later call\r\n * recover it). Conflating the two is what silently logs users out on a flaky reload.\r\n */\r\ntype RefreshOutcome<U extends object> =\r\n | { ok: true; session: AuthSession<U> }\r\n | { ok: false; terminal: boolean; error: unknown };\r\n\r\n/** setTimeout clamps to a 32-bit signed int of milliseconds (~24.8 days); larger\r\n * delays fire immediately in browsers, which would hammer /refresh. */\r\nconst MAX_TIMEOUT_MS = 2 ** 31 - 1;\r\n\r\nexport type AuthUserMetadata = Record<string, unknown>;\r\n\r\nexport interface DefaultAuthUser<\r\n Metadata extends AuthUserMetadata = AuthUserMetadata,\r\n> {\r\n id: string;\r\n email: string;\r\n name: string | null;\r\n status: \"active\" | \"disabled\" | (string & {});\r\n metadata: Metadata;\r\n createdAt?: string;\r\n updatedAt?: string;\r\n lastSignInAt?: string | null;\r\n}\r\n\r\nexport interface AuthSession<\r\n U extends object = DefaultAuthUser,\r\n> {\r\n access_token: string;\r\n refresh_token: string;\r\n expires_in: number;\r\n expires_at: number;\r\n token_type: \"bearer\";\r\n user: U;\r\n}\r\n\r\nexport interface AuthOptions {\r\n persistSession?: boolean;\r\n autoRefreshToken?: boolean;\r\n storage?: SessionStorage;\r\n storageKey?: string;\r\n refreshSkewSeconds?: number;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface RagableAuthConfig {\r\n authGroupId: string;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n auth?: AuthOptions;\r\n}\r\n\r\nexport type AuthSignUpCredentials<\r\n Metadata extends AuthUserMetadata = AuthUserMetadata,\r\n> = {\r\n email: string;\r\n password: string;\r\n options?: {\r\n data?: Partial<Metadata> & {\r\n name?: string | null;\r\n };\r\n };\r\n};\r\n\r\nexport type AuthUpdateUserAttributes<\r\n Metadata extends AuthUserMetadata = AuthUserMetadata,\r\n> = {\r\n email?: string;\r\n password?: string;\r\n data?: Partial<Metadata> & {\r\n name?: string | null;\r\n };\r\n};\r\n\r\ntype MetadataForUser<U extends object> = U extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Metadata\r\n : AuthUserMetadata\r\n : AuthUserMetadata;\r\n\r\ntype AuthListener<U extends object> = (\r\n event: AuthChangeEvent,\r\n session: AuthSession<U> | null,\r\n) => void;\r\n\r\ninterface Subscription {\r\n id: string;\r\n unsubscribe: () => void;\r\n}\r\n\r\n// ─── Helpers ─────────────────────────────────────────────────────────────────\r\n\r\nfunction parseExpiresInSeconds(raw: string | number): number {\r\n if (typeof raw === \"number\") return raw;\r\n const s = raw.trim().toLowerCase();\r\n const m = /^(\\d+)([smhd])?$/.exec(s);\r\n if (m) {\r\n const n = Number(m[1]);\r\n const u = m[2] ?? \"s\";\r\n const mult =\r\n u === \"s\" ? 1 : u === \"m\" ? 60 : u === \"h\" ? 3600 : u === \"d\" ? 86400 : 1;\r\n return n * mult;\r\n }\r\n const asNum = Number(s);\r\n return Number.isFinite(asNum) ? asNum : 0;\r\n}\r\n\r\nasync function parseJsonOrThrow<T>(response: Response): Promise<T> {\r\n const text = await response.text();\r\n let payload: unknown;\r\n try {\r\n payload = text ? JSON.parse(text) : null;\r\n } catch {\r\n throw new RagableError(`Response parse error: ${text.slice(0, 200)}`, response.status, null);\r\n }\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n}\r\n\r\nlet _subCounter = 0;\r\n\r\n// ─── RagableAuth ─────────────────────────────────────────────────────────────\r\n\r\nexport class RagableAuth<\r\n U extends object = DefaultAuthUser,\r\n> {\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly baseUrl: string;\r\n private readonly authGroupId: string;\r\n private readonly defaultHeaders: HeadersInit | undefined;\r\n private readonly persistSession: boolean;\r\n private readonly autoRefreshToken: boolean;\r\n private readonly storage: SessionStorage;\r\n private readonly storageKey: string;\r\n private readonly refreshSkewSeconds: number;\r\n private readonly debug: boolean;\r\n\r\n private currentSession: AuthSession<U> | null = null;\r\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\r\n private refreshPromise: Promise<AuthSession<U> | null> | null = null;\r\n private listeners = new Map<string, AuthListener<U>>();\r\n private broadcast: AuthBroadcastChannel | null = null;\r\n private visibilityHandler: (() => void) | null = null;\r\n /** Memoizes the one-shot restore so concurrent callers (constructor eager init,\r\n * every `onAuthStateChange` subscriber, `getSession`) share a single result.\r\n * Non-null also means \"restore has started\", replacing the old boolean flag. */\r\n private initializePromise: Promise<AuthSession<U> | null> | null = null;\r\n /** Bumped on every explicit session change (sign-in/out, refresh). The async\r\n * restore captures this and refuses to overwrite a newer session op that\r\n * landed while it was reading storage (e.g. a sign-out during page load). */\r\n private sessionEpoch = 0;\r\n\r\n constructor(config: RagableAuthConfig) {\r\n this.baseUrl = DEFAULT_RAGABLE_API_BASE.replace(/\\/+$/, \"\");\r\n this.authGroupId = config.authGroupId;\r\n this.fetchImpl = bindFetch(config.fetch);\r\n this.defaultHeaders = config.headers;\r\n\r\n const auth = config.auth ?? {};\r\n this.persistSession = auth.persistSession !== false;\r\n this.autoRefreshToken = auth.autoRefreshToken !== false;\r\n this.storage = auth.storage ?? detectStorage();\r\n this.storageKey = auth.storageKey ?? `ragable.session.${this.authGroupId}`;\r\n this.refreshSkewSeconds = auth.refreshSkewSeconds ?? 60;\r\n this.debug = auth.debug ?? false;\r\n\r\n this.broadcast = new AuthBroadcastChannel(`ragable-auth-${this.authGroupId}`);\r\n this.broadcast.onMessage((msg) => {\r\n if (msg.type === \"SESSION_UPDATED\") {\r\n try {\r\n const session = JSON.parse(msg.payload) as AuthSession<U>;\r\n this.currentSession = session;\r\n this.scheduleRefresh(session);\r\n this.emit(\"TOKEN_REFRESHED\", session);\r\n } catch { /* ignore bad data from other tab */ }\r\n } else if (msg.type === \"SESSION_REMOVED\") {\r\n this.currentSession = null;\r\n this.clearRefreshTimer();\r\n this.emit(\"SIGNED_OUT\", null);\r\n }\r\n });\r\n\r\n this.setupVisibilityListener();\r\n }\r\n\r\n private log(...args: unknown[]): void {\r\n if (this.debug) console.debug(\"[RagableAuth]\", ...args);\r\n }\r\n\r\n // ── Lifecycle ──────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Restore a persisted session (once). Memoized: every caller awaits the same\r\n * promise, so the eager constructor init, `getSession`, and each\r\n * `onAuthStateChange` subscriber's INITIAL_SESSION replay never race or\r\n * double-restore. Does NOT emit `INITIAL_SESSION` globally — that event is\r\n * delivered per-subscriber by `onAuthStateChange` (Supabase-parity), so a\r\n * listener attached after restore still sees the existing session.\r\n */\r\n initialize(): Promise<AuthSession<U> | null> {\r\n if (this.initializePromise) return this.initializePromise;\r\n this.initializePromise = this._initialize();\r\n return this.initializePromise;\r\n }\r\n\r\n private async _initialize(): Promise<AuthSession<U> | null> {\r\n if (!this.persistSession) return this.currentSession;\r\n const epoch = this.sessionEpoch;\r\n try {\r\n const raw = await this.storage.getItem(this.storageKey);\r\n if (!raw) return this.currentSession;\r\n // A sign-in/out/refresh landed while we were reading storage — that newer\r\n // state wins; do not clobber it with the just-read (now stale) session.\r\n if (this.sessionEpoch !== epoch) return this.currentSession;\r\n const session = JSON.parse(raw) as AuthSession<U>;\r\n const stillValid = !!session.expires_at && session.expires_at > nowSeconds();\r\n if (stillValid) {\r\n this.currentSession = session;\r\n this.scheduleRefresh(session);\r\n this.log(\"Restored session from storage\");\r\n } else if (session.refresh_token) {\r\n // Hold the stale session as context, then attempt a refresh. On a\r\n // TERMINAL failure (refresh token rejected) `singleFlightRefresh`\r\n // purges storage and emits SIGNED_OUT; on a TRANSIENT failure\r\n // (offline/5xx) it keeps the stored session so a later online call can\r\n // recover — we must NOT delete it here.\r\n this.currentSession = session;\r\n this.log(\"Stored session expired, attempting refresh\");\r\n const refreshed = await this.singleFlightRefresh(session.refresh_token);\r\n if (refreshed) this.currentSession = refreshed;\r\n } else {\r\n // Expired and unrefreshable — drop it.\r\n await this.storage.removeItem(this.storageKey);\r\n }\r\n } catch (e) {\r\n this.log(\"Failed to restore session\", e);\r\n }\r\n return this.currentSession;\r\n }\r\n\r\n // ── Auth methods ───────────────────────────────────────────────────────────\r\n\r\n async signUp(\r\n credentials: AuthSignUpCredentials<MetadataForUser<U>>,\r\n ): Promise<PostgrestResult<{ user: U; session: AuthSession<U> }>> {\r\n return asPostgrestResponse(async () => {\r\n const name =\r\n typeof credentials.options?.data?.name === \"string\"\r\n ? credentials.options.data.name\r\n : undefined;\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/register\", \"POST\", {\r\n email: credentials.email,\r\n password: credentials.password,\r\n ...(name !== undefined ? { name } : {}),\r\n ...(credentials.options?.data !== undefined\r\n ? { data: credentials.options.data }\r\n : {}),\r\n });\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return { user: session.user, session };\r\n });\r\n }\r\n\r\n async signInWithPassword(credentials: {\r\n email: string;\r\n password: string;\r\n }): Promise<PostgrestResult<{ user: U; session: AuthSession<U> }>> {\r\n return asPostgrestResponse(async () => {\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/login\", \"POST\", {\r\n email: credentials.email,\r\n password: credentials.password,\r\n });\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return { user: session.user, session };\r\n });\r\n }\r\n\r\n async signOut(_options?: { scope?: \"global\" | \"local\" }): Promise<{ error: null }> {\r\n this.sessionEpoch++;\r\n this.currentSession = null;\r\n this.clearRefreshTimer();\r\n if (this.persistSession) {\r\n await this.storage.removeItem(this.storageKey);\r\n }\r\n this.broadcast?.postSessionRemoved();\r\n this.emit(\"SIGNED_OUT\", null);\r\n return { error: null };\r\n }\r\n\r\n async refreshSession(\r\n refreshToken?: string,\r\n ): Promise<PostgrestResult<{ session: AuthSession<U>; user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n const token = refreshToken ?? this.currentSession?.refresh_token;\r\n if (!token) throw new RagableError(\"No refresh token available\", 401, null);\r\n const session = await this.singleFlightRefresh(token);\r\n if (!session) throw new RagableError(\"Refresh failed\", 401, null);\r\n return { session, user: session.user };\r\n });\r\n }\r\n\r\n async getSession(): Promise<PostgrestResult<{ session: AuthSession<U> | null }>> {\r\n await this.initialize();\r\n return { data: { session: this.currentSession }, error: null };\r\n }\r\n\r\n async getUser(): Promise<PostgrestResult<{ user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n // Restore a persisted session and refresh if near expiry before reading\r\n // /me, so a freshly-loaded page (or a long-lived tab) doesn't report\r\n // \"Not authenticated\" despite a valid stored session.\r\n const token = await this.getValidAccessToken();\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n return this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", token);\r\n });\r\n }\r\n\r\n async setSession(tokens: {\r\n access_token: string;\r\n refresh_token: string;\r\n }): Promise<PostgrestResult<{ session: AuthSession<U>; user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n const me = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", tokens.access_token);\r\n const decoded = decodeJwtExpiry(tokens.access_token);\r\n const expiresIn = decoded ? decoded - nowSeconds() : 3600;\r\n const session: AuthSession<U> = {\r\n access_token: tokens.access_token,\r\n refresh_token: tokens.refresh_token,\r\n expires_in: expiresIn,\r\n expires_at: nowSeconds() + expiresIn,\r\n token_type: \"bearer\",\r\n user: me.user,\r\n };\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return { session, user: me.user };\r\n });\r\n }\r\n\r\n async updateUser(attributes: {\r\n email?: string;\r\n password?: string;\r\n data?: (Partial<MetadataForUser<U>> & { name?: string | null });\r\n }): Promise<PostgrestResult<{ user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n const token = this.currentSession?.access_token;\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n const result = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"PATCH\", token, {\r\n ...(attributes.email !== undefined ? { email: attributes.email } : {}),\r\n ...(attributes.password !== undefined ? { password: attributes.password } : {}),\r\n ...(attributes.data !== undefined ? { data: attributes.data } : {}),\r\n ...(attributes.data?.name !== undefined ? { name: attributes.data.name } : {}),\r\n });\r\n if (this.currentSession) {\r\n this.currentSession = { ...this.currentSession, user: result.user };\r\n await this.persistCurrentSession();\r\n }\r\n this.emit(\"USER_UPDATED\", this.currentSession);\r\n return result;\r\n });\r\n }\r\n\r\n // ── Event subscription ─────────────────────────────────────────────────────\r\n\r\n onAuthStateChange(\r\n callback: AuthListener<U>,\r\n ): { data: { subscription: Subscription } } {\r\n _subCounter++;\r\n const id = `sub-${_subCounter}`;\r\n this.listeners.set(id, callback);\r\n // Replay the restored session to THIS subscriber as INITIAL_SESSION once\r\n // restore completes (Supabase v2 parity). Without this, a listener attached\r\n // after page load — i.e. every React `useEffect` — never learns about the\r\n // session already sitting in storage, so apps render logged-out on reload.\r\n void this.initialize().then((session) => {\r\n const cb = this.listeners.get(id);\r\n if (!cb) return; // unsubscribed during restore\r\n try {\r\n cb(\"INITIAL_SESSION\", session);\r\n } catch (e) {\r\n this.log(\"Listener threw\", e);\r\n }\r\n });\r\n const unsubscribe = () => {\r\n this.listeners.delete(id);\r\n };\r\n return { data: { subscription: { id, unsubscribe } } };\r\n }\r\n\r\n // ── Accessors ──────────────────────────────────────────────────────────────\r\n\r\n getAccessToken(): string | null {\r\n return this.currentSession?.access_token ?? null;\r\n }\r\n\r\n /**\r\n * Returns an access token guaranteed fresh for at least `refreshSkewSeconds`,\r\n * refreshing (single-flight) if needed. Pass `force: true` to bypass the skew\r\n * check and refresh now — used by the transport's 401 handler so a token the\r\n * server rejected (key rotation, clock skew, early revocation) self-heals on\r\n * retry instead of failing the call.\r\n */\r\n async getValidAccessToken(force = false): Promise<string | null> {\r\n await this.initialize();\r\n const session = this.currentSession;\r\n if (!session) return null;\r\n const secondsUntilExpiry = session.expires_at - nowSeconds();\r\n if (force || secondsUntilExpiry <= this.refreshSkewSeconds) {\r\n const refreshed = await this.singleFlightRefresh(session.refresh_token);\r\n return refreshed?.access_token ?? null;\r\n }\r\n return session.access_token;\r\n }\r\n\r\n getCurrentSession(): AuthSession<U> | null {\r\n return this.currentSession;\r\n }\r\n\r\n // ── Back-compat: raw Ragable auth methods ──────────────────────────────────\r\n\r\n async register(body: {\r\n email: string;\r\n password: string;\r\n name?: string;\r\n data?: Partial<MetadataForUser<U>> & { name?: string | null };\r\n }): Promise<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }> {\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/register\", \"POST\", body);\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return raw;\r\n }\r\n\r\n async login(body: {\r\n email: string;\r\n password: string;\r\n }): Promise<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }> {\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/login\", \"POST\", body);\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return raw;\r\n }\r\n\r\n async refresh(body: { refreshToken: string }): Promise<{\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }> {\r\n return this.fetchAuth(\"/refresh\", \"POST\", body);\r\n }\r\n\r\n async getMe(): Promise<{ user: U }> {\r\n const token = this.currentSession?.access_token;\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n return this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", token);\r\n }\r\n\r\n async updateMe(body: {\r\n email?: string;\r\n name?: string | null;\r\n password?: string;\r\n data?: Partial<MetadataForUser<U>> & { name?: string | null };\r\n }): Promise<{ user: U }> {\r\n const token = this.currentSession?.access_token;\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n const result = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"PATCH\", token, body);\r\n if (this.currentSession) {\r\n this.currentSession = { ...this.currentSession, user: result.user };\r\n await this.persistCurrentSession();\r\n }\r\n this.emit(\"USER_UPDATED\", this.currentSession);\r\n return result;\r\n }\r\n\r\n // ── Cleanup ────────────────────────────────────────────────────────────────\r\n\r\n destroy(): void {\r\n this.clearRefreshTimer();\r\n this.broadcast?.close();\r\n this.listeners.clear();\r\n if (this.visibilityHandler && typeof document !== \"undefined\") {\r\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\r\n }\r\n }\r\n\r\n // ─── Internal ──────────────────────────────────────────────────────────────\r\n\r\n private authPrefix(): string {\r\n return `/auth-groups/${this.authGroupId}/auth`;\r\n }\r\n\r\n private toUrl(path: string): string {\r\n return `${this.baseUrl}${this.authPrefix()}${path}`;\r\n }\r\n\r\n private baseHeaders(json: boolean): Headers {\r\n const h = new Headers(this.defaultHeaders);\r\n if (json) h.set(\"Content-Type\", \"application/json\");\r\n return h;\r\n }\r\n\r\n private async fetchAuth<T>(\r\n path: string,\r\n method: \"GET\" | \"POST\" | \"PATCH\",\r\n body?: unknown,\r\n ): Promise<T> {\r\n const headers = this.baseHeaders(body !== undefined);\r\n const response = await this.fetchImpl(this.toUrl(path), {\r\n method,\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n return parseJsonOrThrow<T>(response);\r\n }\r\n\r\n private async fetchAuthWithBearer<T>(\r\n path: string,\r\n method: \"GET\" | \"POST\" | \"PATCH\",\r\n token: string,\r\n body?: unknown,\r\n ): Promise<T> {\r\n const headers = this.baseHeaders(body !== undefined);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n const response = await this.fetchImpl(this.toUrl(path), {\r\n method,\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n return parseJsonOrThrow<T>(response);\r\n }\r\n\r\n private rawToSession(raw: {\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }): AuthSession<U> {\r\n const expiresIn = parseExpiresInSeconds(raw.expiresIn);\r\n return {\r\n access_token: raw.accessToken,\r\n refresh_token: raw.refreshToken,\r\n expires_in: expiresIn,\r\n expires_at: nowSeconds() + expiresIn,\r\n token_type: \"bearer\",\r\n user: raw.user,\r\n };\r\n }\r\n\r\n private async setSessionInternal(\r\n session: AuthSession<U>,\r\n event: AuthChangeEvent,\r\n ): Promise<void> {\r\n this.sessionEpoch++;\r\n this.currentSession = session;\r\n await this.persistCurrentSession();\r\n this.broadcast?.postSessionUpdated(JSON.stringify(session));\r\n this.scheduleRefresh(session);\r\n this.emit(event, session);\r\n }\r\n\r\n private async persistCurrentSession(): Promise<void> {\r\n if (!this.persistSession || !this.currentSession) return;\r\n try {\r\n await this.storage.setItem(this.storageKey, JSON.stringify(this.currentSession));\r\n } catch (e) {\r\n this.log(\"Failed to persist session\", e);\r\n }\r\n }\r\n\r\n private emit(event: AuthChangeEvent, session: AuthSession<U> | null): void {\r\n this.log(event, session?.user);\r\n for (const cb of this.listeners.values()) {\r\n try {\r\n cb(event, session);\r\n } catch (e) {\r\n this.log(\"Listener threw\", e);\r\n }\r\n }\r\n }\r\n\r\n // ─── Refresh scheduling ────────────────────────────────────────────────────\r\n\r\n private scheduleRefresh(session: AuthSession<U>): void {\r\n this.clearRefreshTimer();\r\n if (!this.autoRefreshToken) return;\r\n const secondsUntilExpiry = session.expires_at - nowSeconds();\r\n const refreshIn = Math.max(0, secondsUntilExpiry - this.refreshSkewSeconds);\r\n // Clamp to setTimeout's 32-bit ceiling. A configured access-token lifetime\r\n // over ~24.8 days would otherwise overflow and fire instantly, looping.\r\n const delayMs = Math.min(refreshIn * 1000, MAX_TIMEOUT_MS);\r\n this.log(`Scheduling refresh in ${Math.round(delayMs / 1000)}s`);\r\n this.refreshTimer = setTimeout(() => {\r\n this.singleFlightRefresh(session.refresh_token).catch((e) => {\r\n this.log(\"Scheduled refresh failed\", e);\r\n });\r\n }, delayMs);\r\n }\r\n\r\n private clearRefreshTimer(): void {\r\n if (this.refreshTimer !== null) {\r\n clearTimeout(this.refreshTimer);\r\n this.refreshTimer = null;\r\n }\r\n }\r\n\r\n /**\r\n * Refresh the session, deduplicating concurrent callers onto one in-flight\r\n * request. Side effects (persisting the new session, or clearing it and\r\n * emitting SIGNED_OUT / TOKEN_REFRESH_FAILED) run exactly once inside the\r\n * shared promise, so two callers can't double-emit. Resolves to the new\r\n * session, or `null` when the refresh failed.\r\n */\r\n async singleFlightRefresh(refreshToken: string): Promise<AuthSession<U> | null> {\r\n if (this.refreshPromise) return this.refreshPromise;\r\n this.refreshPromise = (async () => {\r\n const outcome = await this._doRefresh(refreshToken);\r\n if (outcome.ok) return outcome.session;\r\n if (outcome.terminal) {\r\n // Refresh token is permanently invalid — purge and notify so the app\r\n // can route to sign-in.\r\n await this.handleTerminalRefreshFailure();\r\n } else {\r\n // Transient (offline / 5xx / timeout): keep the persisted session for a\r\n // later recovery, but signal the failure so UIs can surface \"reconnecting\".\r\n this.emit(\"TOKEN_REFRESH_FAILED\", this.currentSession);\r\n }\r\n return null;\r\n })().finally(() => {\r\n this.refreshPromise = null;\r\n });\r\n return this.refreshPromise;\r\n }\r\n\r\n /** Clear the session locally and emit SIGNED_OUT after a definitively-rejected\r\n * refresh, so onAuthStateChange-driven UI redirects to login. */\r\n private async handleTerminalRefreshFailure(): Promise<void> {\r\n this.sessionEpoch++;\r\n this.currentSession = null;\r\n this.clearRefreshTimer();\r\n if (this.persistSession) {\r\n try {\r\n await this.storage.removeItem(this.storageKey);\r\n } catch (e) {\r\n this.log(\"Failed to clear session after terminal refresh failure\", e);\r\n }\r\n }\r\n this.broadcast?.postSessionRemoved();\r\n this.emit(\"TOKEN_REFRESH_FAILED\", null);\r\n this.emit(\"SIGNED_OUT\", null);\r\n }\r\n\r\n private async _doRefresh(refreshToken: string): Promise<RefreshOutcome<U>> {\r\n let raw: { accessToken: string; refreshToken: string; expiresIn: string };\r\n try {\r\n raw = await this.fetchAuth<{\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/refresh\", \"POST\", { refreshToken });\r\n } catch (e) {\r\n // Only a 4xx from /refresh means the token itself is rejected. Network\r\n // errors, timeouts, and 5xx are transient — keep the session.\r\n const status = e instanceof RagableError ? e.status : 0;\r\n const terminal = status === 400 || status === 401 || status === 403;\r\n this.log(\"Refresh request failed\", { status, terminal });\r\n return { ok: false, terminal, error: e };\r\n }\r\n try {\r\n const me = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", raw.accessToken);\r\n const expiresIn = parseExpiresInSeconds(raw.expiresIn);\r\n const session: AuthSession<U> = {\r\n access_token: raw.accessToken,\r\n refresh_token: raw.refreshToken,\r\n expires_in: expiresIn,\r\n expires_at: nowSeconds() + expiresIn,\r\n token_type: \"bearer\",\r\n user: me.user,\r\n };\r\n await this.setSessionInternal(session, \"TOKEN_REFRESHED\");\r\n return { ok: true, session };\r\n } catch (e) {\r\n // We obtained new tokens but the follow-up /me failed. Treat as transient\r\n // (don't purge a freshly-minted session over a hydration hiccup).\r\n this.log(\"Post-refresh /me failed\", e);\r\n return { ok: false, terminal: false, error: e };\r\n }\r\n }\r\n\r\n // ─── Visibility listener ───────────────────────────────────────────────────\r\n\r\n private setupVisibilityListener(): void {\r\n if (typeof document === \"undefined\") return;\r\n this.visibilityHandler = () => {\r\n if (document.visibilityState === \"visible\" && this.currentSession) {\r\n const secondsUntilExpiry = this.currentSession.expires_at - nowSeconds();\r\n if (secondsUntilExpiry <= this.refreshSkewSeconds) {\r\n this.singleFlightRefresh(this.currentSession.refresh_token).catch(() => {});\r\n } else {\r\n this.scheduleRefresh(this.currentSession);\r\n }\r\n } else {\r\n this.clearRefreshTimer();\r\n }\r\n };\r\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\r\n }\r\n}\r\n\r\nfunction nowSeconds(): number {\r\n return Math.floor(Date.now() / 1000);\r\n}\r\n\r\nfunction decodeJwtExpiry(jwt: string): number | null {\r\n try {\r\n const parts = jwt.split(\".\");\r\n if (parts.length !== 3) return null;\r\n const payload = JSON.parse(atob(parts[1]!.replace(/-/g, \"+\").replace(/_/g, \"/\")));\r\n return typeof payload.exp === \"number\" ? payload.exp : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n","/**\n * Best-effort parser for incomplete JSON streamed token-by-token from an LLM.\n *\n * Used by `streamObject` to emit partial objects as the model writes them.\n * Strategy:\n * 1. Try `JSON.parse(text)` — if it works, the JSON is already complete.\n * 2. Otherwise scan the text and close any open `{`, `[`, or string literal\n * so the result is parseable.\n * 3. If a trailing comma is the problem, strip it and retry.\n *\n * Returns `undefined` when no parseable prefix can be recovered.\n *\n * Designed to be allocation-light and dep-free.\n */\nexport function tryParsePartialJson(text: string): unknown | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n\n // Direct parse — fast path when the model already produced complete JSON.\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n // fall through to repair\n }\n\n const repaired = repairOpenStructures(trimmed);\n if (!repaired) return undefined;\n\n try {\n return JSON.parse(repaired) as unknown;\n } catch {\n // Strip a trailing comma inside the last open container and retry.\n const noTrailingComma = stripTrailingCommas(trimmed);\n const repaired2 = repairOpenStructures(noTrailingComma);\n if (!repaired2) return undefined;\n try {\n return JSON.parse(repaired2) as unknown;\n } catch {\n return undefined;\n }\n }\n}\n\n/**\n * Close any open `{`, `[`, or string literal in `text` so the result is\n * syntactically valid JSON. Returns `null` if the input doesn't begin with\n * a JSON-ish character (so we don't pretend \"Hello\" is recoverable).\n */\nfunction repairOpenStructures(text: string): string | null {\n const first = text[0];\n if (first !== \"{\" && first !== \"[\") {\n // Allow primitive top-level values (number, \"string\", true/false/null).\n return text;\n }\n\n const stack: Array<\"}\" | \"]\"> = [];\n let inString = false;\n let escaped = false;\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (ch === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (ch === '\"') {\n inString = !inString;\n continue;\n }\n if (inString) continue;\n if (ch === \"{\") stack.push(\"}\");\n else if (ch === \"[\") stack.push(\"]\");\n else if (ch === \"}\" || ch === \"]\") {\n if (stack.length === 0) return null; // mismatched close\n stack.pop();\n }\n }\n\n // If we're mid-key/value, we usually have a dangling `\"key\":` or `\"key\": <partial>`.\n // Trim back to the last position that's safe to close.\n let safe = text;\n if (inString) {\n safe += '\"'; // close the open string first\n }\n // Drop a dangling colon or trailing comma so the structure parses.\n safe = safe.replace(/,\\s*$/, \"\").replace(/:\\s*$/, ': null');\n\n // Append closing brackets in reverse stack order.\n let suffix = \"\";\n for (let i = stack.length - 1; i >= 0; i--) suffix += stack[i];\n return safe + suffix;\n}\n\nfunction stripTrailingCommas(text: string): string {\n return text.replace(/,(\\s*[}\\]])/g, \"$1\").replace(/,\\s*$/, \"\");\n}\n","/**\r\n * Vercel AI SDK–style stream part types, used by both `client.ai.streamText`\r\n * (Fireworks chunks via the Ragable proxy) and `client.agents.run` (existing\r\n * agent SSE events). Keep this module zero-dep so it can be re-exported from\r\n * the SDK entrypoint without dragging in agent/browser code.\r\n */\r\n\r\nexport type FinishReason =\r\n | \"stop\"\r\n | \"length\"\r\n | \"tool-calls\"\r\n | \"content-filter\"\r\n | \"error\"\r\n | \"unknown\";\r\n\r\nexport interface TokenUsage {\r\n promptTokens: number;\r\n completionTokens: number;\r\n totalTokens: number;\r\n /** Prompt-cache read tokens reported by the upstream provider, when available. */\r\n cachedPromptTokens?: number;\r\n}\r\n\r\nexport type StreamPart =\r\n | { type: \"text-delta\"; textDelta: string }\r\n | { type: \"reasoning\"; textDelta: string }\r\n | {\r\n type: \"tool-call\";\r\n toolCallId: string;\r\n toolName: string;\r\n args: unknown;\r\n }\r\n | {\r\n type: \"tool-result\";\r\n toolCallId: string;\r\n toolName: string;\r\n result: unknown;\r\n durationMs?: number;\r\n }\r\n | { type: \"finish\"; finishReason: FinishReason; usage: TokenUsage }\r\n | { type: \"error\"; error: unknown };\r\n\r\nexport interface Message {\r\n role: \"system\" | \"user\" | \"assistant\";\r\n content: string;\r\n}\r\n\r\n/**\r\n * OpenAI/Fireworks SSE chunk shape, only the fields we actually consume.\r\n * Kept as a local type so we don't depend on backend internals.\r\n */\r\nexport interface OpenAiStreamChunk {\r\n choices?: Array<{\r\n delta?: {\r\n content?: string | null;\r\n reasoning_content?: string | null;\r\n reasoning?: string | null;\r\n tool_calls?: Array<{\r\n index?: number;\r\n id?: string | null;\r\n type?: string;\r\n function?: { name?: string | null; arguments?: string | null };\r\n }>;\r\n };\r\n finish_reason?: string | null;\r\n }>;\r\n usage?: {\r\n prompt_tokens?: number;\r\n completion_tokens?: number;\r\n total_tokens?: number;\r\n prompt_tokens_details?: { cached_tokens?: number };\r\n cache_read_input_tokens?: number;\r\n };\r\n error?: { code?: number; message?: string };\r\n}\r\n\r\nfunction normalizeFinishReason(raw: string | null | undefined): FinishReason {\r\n switch (raw) {\r\n case \"stop\":\r\n case \"length\":\r\n case \"content-filter\":\r\n case \"error\":\r\n return raw;\r\n case \"tool_calls\":\r\n return \"tool-calls\";\r\n case null:\r\n case undefined:\r\n case \"\":\r\n return \"unknown\";\r\n default:\r\n return \"unknown\";\r\n }\r\n}\r\n\r\nfunction chunkUsage(chunk: OpenAiStreamChunk): TokenUsage {\r\n const u = chunk.usage ?? {};\r\n const cached =\r\n u.prompt_tokens_details?.cached_tokens ?? u.cache_read_input_tokens;\r\n return {\r\n promptTokens: typeof u.prompt_tokens === \"number\" ? u.prompt_tokens : 0,\r\n completionTokens:\r\n typeof u.completion_tokens === \"number\" ? u.completion_tokens : 0,\r\n totalTokens: typeof u.total_tokens === \"number\" ? u.total_tokens : 0,\r\n ...(typeof cached === \"number\" ? { cachedPromptTokens: cached } : {}),\r\n };\r\n}\r\n\r\n/**\r\n * Accumulator for partial tool-call function arguments streamed across\r\n * multiple chunks (Fireworks streams the `arguments` JSON token-by-token).\r\n */\r\nexport interface ToolCallAccumulator {\r\n byIndex: Map<\r\n number,\r\n { id: string; name: string; argsBuffer: string; emitted: boolean }\r\n >;\r\n}\r\n\r\nexport function createToolCallAccumulator(): ToolCallAccumulator {\r\n return { byIndex: new Map() };\r\n}\r\n\r\nfunction parseJsonOrRaw(raw: string): unknown {\r\n try {\r\n return JSON.parse(raw);\r\n } catch {\r\n return raw;\r\n }\r\n}\r\n\r\n/**\r\n * Map a single Fireworks/OpenAI chunk into zero or more StreamParts.\r\n * Tool calls are buffered until their `arguments` JSON is parseable, then\r\n * emitted as a single `tool-call` part — same convention as Vercel AI SDK.\r\n */\r\nexport function mapFireworksChunk(\r\n chunk: OpenAiStreamChunk,\r\n acc: ToolCallAccumulator,\r\n): StreamPart[] {\r\n const out: StreamPart[] = [];\r\n\r\n if (chunk.error?.message) {\r\n out.push({ type: \"error\", error: chunk.error.message });\r\n return out;\r\n }\r\n\r\n const choice = chunk.choices?.[0];\r\n const delta = choice?.delta;\r\n\r\n if (delta?.content) {\r\n out.push({ type: \"text-delta\", textDelta: delta.content });\r\n }\r\n\r\n const reasoning = delta?.reasoning_content ?? delta?.reasoning;\r\n if (typeof reasoning === \"string\" && reasoning.length > 0) {\r\n out.push({ type: \"reasoning\", textDelta: reasoning });\r\n }\r\n\r\n if (Array.isArray(delta?.tool_calls)) {\r\n for (const tc of delta.tool_calls) {\r\n const idx = typeof tc.index === \"number\" ? tc.index : 0;\r\n let entry = acc.byIndex.get(idx);\r\n if (!entry) {\r\n entry = { id: \"\", name: \"\", argsBuffer: \"\", emitted: false };\r\n acc.byIndex.set(idx, entry);\r\n }\r\n if (tc.id) entry.id = tc.id;\r\n if (tc.function?.name) entry.name = tc.function.name;\r\n if (typeof tc.function?.arguments === \"string\") {\r\n entry.argsBuffer += tc.function.arguments;\r\n }\r\n }\r\n }\r\n\r\n if (choice?.finish_reason) {\r\n // Flush any remaining tool calls whose args weren't a closing brace mid-stream.\r\n for (const entry of acc.byIndex.values()) {\r\n if (entry.emitted || !entry.name) continue;\r\n entry.emitted = true;\r\n out.push({\r\n type: \"tool-call\",\r\n toolCallId: entry.id || `call_${entry.name}_${Date.now()}`,\r\n toolName: entry.name,\r\n args: entry.argsBuffer ? parseJsonOrRaw(entry.argsBuffer) : {},\r\n });\r\n }\r\n out.push({\r\n type: \"finish\",\r\n finishReason: normalizeFinishReason(choice.finish_reason),\r\n usage: chunkUsage(chunk),\r\n });\r\n } else if (chunk.usage) {\r\n // Some providers emit usage in a trailing chunk without finish_reason.\r\n out.push({\r\n type: \"finish\",\r\n finishReason: \"unknown\",\r\n usage: chunkUsage(chunk),\r\n });\r\n }\r\n\r\n return out;\r\n}\r\n\r\n/**\r\n * Minimal shape of an `AgentStreamEvent` from `agent-stream.ts`. Inlined to\r\n * keep this module zero-import.\r\n */\r\nexport interface AgentStreamLikeEvent {\r\n type: string;\r\n [k: string]: unknown;\r\n}\r\n\r\nfunction asStr(v: unknown, fallback = \"\"): string {\r\n return typeof v === \"string\" ? v : fallback;\r\n}\r\n\r\nfunction asNum(v: unknown, fallback = 0): number {\r\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\r\n}\r\n\r\n/**\r\n * Map an existing agent SSE event (`token`, `reasoning_token`, `tool:call`,\r\n * `tool:result`, `done`) into a StreamPart, or `null` for events that don't\r\n * map (`ping`, `agent:info`, `node:*`).\r\n */\r\nexport function mapAgentEvent(event: AgentStreamLikeEvent): StreamPart | null {\r\n switch (event.type) {\r\n case \"token\":\r\n return { type: \"text-delta\", textDelta: asStr(event.token) };\r\n case \"reasoning_token\":\r\n return { type: \"reasoning\", textDelta: asStr(event.token) };\r\n case \"tool:call\":\r\n return {\r\n type: \"tool-call\",\r\n toolCallId: asStr(event.nodeId),\r\n toolName: asStr(event.toolName),\r\n args: event.args,\r\n };\r\n case \"tool:result\":\r\n return {\r\n type: \"tool-result\",\r\n toolCallId: asStr(event.nodeId),\r\n toolName: asStr(event.toolName),\r\n result: event.result,\r\n ...(typeof event.durationMs === \"number\"\r\n ? { durationMs: event.durationMs }\r\n : {}),\r\n };\r\n case \"done\": {\r\n const usage: TokenUsage = {\r\n promptTokens: asNum(event.inputTokens),\r\n completionTokens: asNum(event.outputTokens),\r\n totalTokens: asNum(event.inputTokens) + asNum(event.outputTokens),\r\n ...(typeof event.cachedPromptTokens === \"number\"\r\n ? { cachedPromptTokens: event.cachedPromptTokens }\r\n : {}),\r\n };\r\n return {\r\n type: \"finish\",\r\n finishReason: normalizeFinishReason(\r\n asStr(event.finishReason) || asStr(event.stopReason) || null,\r\n ),\r\n usage,\r\n };\r\n }\r\n default:\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Vercel AI SDK–style raw inference for `@ragable/sdk`. Routes through the\r\n * Ragable backend's Fireworks proxy\r\n * (`POST /public/organizations/:id/websites/:websiteId/inference/stream`)\r\n * so callers don't need a provider API key and credit usage is tracked\r\n * against the website's organization.\r\n */\r\n\r\nimport { bindFetch, extractErrorMessage, RagableError } from \"./request-client\";\r\nimport { tryParsePartialJson } from \"./partial-json\";\r\nimport { parseMaybeJsonBody, parseSseDataLine } from \"./sse\";\r\nimport {\r\n createToolCallAccumulator,\r\n mapFireworksChunk,\r\n type FinishReason,\r\n type Message,\r\n type OpenAiStreamChunk,\r\n type StreamPart,\r\n type TokenUsage,\r\n type ToolCallAccumulator,\r\n} from \"./stream-parts\";\r\n\r\n/** JSON Schema for a structured response. Plain object — no Zod dep. */\r\nexport type JsonSchema = Record<string, unknown>;\r\n\r\nexport interface StreamTextParams {\r\n model: string;\r\n messages: Message[];\r\n system?: string;\r\n temperature?: number;\r\n maxTokens?: number;\r\n topP?: number;\r\n reasoningEffort?: \"none\" | \"low\" | \"medium\" | \"high\";\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface ToolCallRecord {\r\n toolCallId: string;\r\n toolName: string;\r\n args: unknown;\r\n}\r\n\r\nexport interface StreamTextResult {\r\n /** Stream of text deltas only. Same content as `fullStream.filter(p => p.type === \"text-delta\")`. */\r\n textStream: AsyncIterable<string>;\r\n /** Full event stream — text deltas, reasoning, tool calls, finish, error. */\r\n fullStream: AsyncIterable<StreamPart>;\r\n /** Resolves to the concatenation of all `text-delta` parts once the stream finishes. */\r\n text: Promise<string>;\r\n /** Resolves to the concatenation of all `reasoning` parts. */\r\n reasoning: Promise<string>;\r\n /** Resolves to token usage from the final chunk (zeros if not reported). */\r\n usage: Promise<TokenUsage>;\r\n /** Resolves to the upstream finish reason. */\r\n finishReason: Promise<FinishReason>;\r\n /** Resolves to the list of tool calls extracted from this turn. */\r\n toolCalls: Promise<ToolCallRecord[]>;\r\n}\r\n\r\nexport interface GenerateTextResult {\r\n text: string;\r\n reasoning: string;\r\n usage: TokenUsage;\r\n finishReason: FinishReason;\r\n toolCalls: ToolCallRecord[];\r\n}\r\n\r\nexport interface StreamObjectParams {\r\n model: string;\r\n /**\r\n * JSON Schema describing the expected output. Constrains the model via the\r\n * Fireworks `response_format: { type: \"json_object\", schema }` mode.\r\n */\r\n schema: JsonSchema;\r\n /** Optional name for the schema (passed through to providers that support it). */\r\n schemaName?: string;\r\n /** Optional natural-language description of the schema. */\r\n schemaDescription?: string;\r\n messages: Message[];\r\n system?: string;\r\n temperature?: number;\r\n maxTokens?: number;\r\n topP?: number;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface StreamObjectResult<T = unknown> {\r\n /** Raw text deltas — the JSON string as it streams in. */\r\n textStream: AsyncIterable<string>;\r\n /**\r\n * Async iterable of best-effort parsed partial objects. Emits whenever the\r\n * accumulated JSON parses cleanly under the partial-JSON repair rules.\r\n * Subsequent values are *replacements*, not patches — each is a snapshot.\r\n */\r\n partialObjectStream: AsyncIterable<T>;\r\n /** Resolves to the final parsed object once the stream ends. Rejects if the final JSON is invalid. */\r\n object: Promise<T>;\r\n /** Resolves to the raw JSON string the model produced. */\r\n text: Promise<string>;\r\n usage: Promise<TokenUsage>;\r\n finishReason: Promise<FinishReason>;\r\n /**\r\n * Resolves to tool calls the model made during this turn.\r\n * Empty for `client.ai.streamObject` (no tools exposed on raw inference);\r\n * populated for `client.agents.runObject` when the agent has tools.\r\n */\r\n toolCalls: Promise<ToolCallRecord[]>;\r\n}\r\n\r\nexport interface GenerateObjectResult<T = unknown> {\r\n object: T;\r\n usage: TokenUsage;\r\n finishReason: FinishReason;\r\n toolCalls: ToolCallRecord[];\r\n}\r\n\r\ninterface ResolvedPart {\r\n parts: StreamPart[];\r\n resolved: boolean;\r\n error: unknown;\r\n waiters: Array<() => void>;\r\n}\r\n\r\nclass PartBroadcast {\r\n private state: ResolvedPart = {\r\n parts: [],\r\n resolved: false,\r\n error: null,\r\n waiters: [],\r\n };\r\n\r\n push(part: StreamPart): void {\r\n this.state.parts.push(part);\r\n this.notify();\r\n }\r\n\r\n end(): void {\r\n if (this.state.resolved) return;\r\n this.state.resolved = true;\r\n this.notify();\r\n }\r\n\r\n fail(error: unknown): void {\r\n if (this.state.resolved) return;\r\n this.state.error = error;\r\n this.state.resolved = true;\r\n this.notify();\r\n }\r\n\r\n private notify(): void {\r\n const waiters = this.state.waiters;\r\n this.state.waiters = [];\r\n for (const w of waiters) w();\r\n }\r\n\r\n consume(): AsyncIterable<StreamPart> {\r\n const state = this.state;\r\n return {\r\n [Symbol.asyncIterator]: (): AsyncIterator<StreamPart> => {\r\n let idx = 0;\r\n return {\r\n next: async (): Promise<IteratorResult<StreamPart>> => {\r\n while (true) {\r\n if (idx < state.parts.length) {\r\n return { value: state.parts[idx++]!, done: false };\r\n }\r\n if (state.resolved) {\r\n if (state.error) throw state.error;\r\n return { value: undefined as unknown as StreamPart, done: true };\r\n }\r\n await new Promise<void>((resolve) => {\r\n state.waiters.push(resolve);\r\n });\r\n }\r\n },\r\n };\r\n },\r\n };\r\n }\r\n}\r\n\r\ninterface DeferredPromise<T> {\r\n promise: Promise<T>;\r\n resolve: (value: T) => void;\r\n reject: (reason: unknown) => void;\r\n}\r\n\r\nfunction defer<T>(): DeferredPromise<T> {\r\n let resolve!: (value: T) => void;\r\n let reject!: (reason: unknown) => void;\r\n const promise = new Promise<T>((res, rej) => {\r\n resolve = res;\r\n reject = rej;\r\n });\r\n return { promise, resolve, reject };\r\n}\r\n\r\nconst ZERO_USAGE: TokenUsage = {\r\n promptTokens: 0,\r\n completionTokens: 0,\r\n totalTokens: 0,\r\n};\r\n\r\n/**\r\n * Build the JSON body for the inference proxy. Public so tests can assert it.\r\n * Accepts an optional `responseFormat` so the same builder serves both\r\n * `streamText` and `streamObject`.\r\n */\r\nexport function buildInferenceRequestBody(\r\n params: StreamTextParams,\r\n responseFormat?: Record<string, unknown>,\r\n): Record<string, unknown> {\r\n const body: Record<string, unknown> = {\r\n model: params.model,\r\n messages: params.messages,\r\n };\r\n if (params.system !== undefined) body.system = params.system;\r\n if (typeof params.temperature === \"number\")\r\n body.temperature = params.temperature;\r\n if (typeof params.maxTokens === \"number\") body.max_tokens = params.maxTokens;\r\n if (typeof params.topP === \"number\") body.top_p = params.topP;\r\n if (params.reasoningEffort) body.reasoning_effort = params.reasoningEffort;\r\n if (responseFormat) body.response_format = responseFormat;\r\n return body;\r\n}\r\n\r\n/**\r\n * Build the `response_format` payload for a JSON-Schema-constrained call.\r\n * Emits Fireworks' canonical shape (also accepted by OpenAI):\r\n *\r\n * { type: \"json_schema\",\r\n * json_schema: { name, schema, description?, strict? } }\r\n *\r\n * @see https://docs.fireworks.ai/structured-responses/structured-response-formatting\r\n */\r\nexport function buildResponseFormat(params: {\r\n schema: JsonSchema;\r\n name?: string;\r\n description?: string;\r\n /** Default `true` — providers ignore unknown fields safely. */\r\n strict?: boolean;\r\n}): Record<string, unknown> {\r\n const json_schema: Record<string, unknown> = {\r\n name: params.name ?? \"Output\",\r\n schema: params.schema,\r\n strict: params.strict ?? true,\r\n };\r\n if (params.description) json_schema.description = params.description;\r\n return { type: \"json_schema\", json_schema };\r\n}\r\n\r\n/**\r\n * Consume a Fireworks-shaped SSE body and push StreamParts onto `broadcast`.\r\n * Resolves the deferred result promises when the stream ends or errors.\r\n */\r\nasync function consumeInferenceStream(\r\n body: ReadableStream<Uint8Array>,\r\n broadcast: PartBroadcast,\r\n deferreds: {\r\n text: DeferredPromise<string>;\r\n reasoning: DeferredPromise<string>;\r\n usage: DeferredPromise<TokenUsage>;\r\n finishReason: DeferredPromise<FinishReason>;\r\n toolCalls: DeferredPromise<ToolCallRecord[]>;\r\n },\r\n): Promise<void> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n const acc: ToolCallAccumulator = createToolCallAccumulator();\r\n\r\n let textBuffer = \"\";\r\n let reasoningBuffer = \"\";\r\n let lastUsage: TokenUsage = ZERO_USAGE;\r\n let lastFinish: FinishReason = \"unknown\";\r\n const toolCallsArr: ToolCallRecord[] = [];\r\n let buffer = \"\";\r\n\r\n const dispatch = (rawLine: string): void => {\r\n const parsed = parseSseDataLine(rawLine);\r\n if (!parsed) return;\r\n const chunk = parsed as unknown as OpenAiStreamChunk;\r\n const parts = mapFireworksChunk(chunk, acc);\r\n for (const part of parts) {\r\n if (part.type === \"text-delta\") textBuffer += part.textDelta;\r\n else if (part.type === \"reasoning\") reasoningBuffer += part.textDelta;\r\n else if (part.type === \"tool-call\") {\r\n toolCallsArr.push({\r\n toolCallId: part.toolCallId,\r\n toolName: part.toolName,\r\n args: part.args,\r\n });\r\n } else if (part.type === \"finish\") {\r\n lastFinish = part.finishReason;\r\n lastUsage = part.usage;\r\n }\r\n broadcast.push(part);\r\n }\r\n };\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n let boundary = buffer.indexOf(\"\\n\\n\");\r\n while (boundary !== -1) {\r\n const block = buffer.slice(0, boundary);\r\n buffer = buffer.slice(boundary + 2);\r\n for (const line of block.split(\"\\n\")) dispatch(line);\r\n boundary = buffer.indexOf(\"\\n\\n\");\r\n }\r\n }\r\n if (buffer.trim().length > 0) {\r\n for (const line of buffer.split(\"\\n\")) dispatch(line);\r\n }\r\n\r\n broadcast.end();\r\n deferreds.text.resolve(textBuffer);\r\n deferreds.reasoning.resolve(reasoningBuffer);\r\n deferreds.usage.resolve(lastUsage);\r\n deferreds.finishReason.resolve(lastFinish);\r\n deferreds.toolCalls.resolve(toolCallsArr);\r\n } catch (error) {\r\n broadcast.fail(error);\r\n deferreds.text.reject(error);\r\n deferreds.reasoning.reject(error);\r\n deferreds.usage.reject(error);\r\n deferreds.finishReason.reject(error);\r\n deferreds.toolCalls.reject(error);\r\n } finally {\r\n try {\r\n reader.releaseLock();\r\n } catch {\r\n // already released\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Build a `StreamTextResult` from a pre-existing async iterable of StreamParts.\r\n * Used by `client.agents.run()` to share the same DX as `client.ai.streamText`.\r\n */\r\nexport function createStreamResultFromParts(\r\n source: AsyncIterable<StreamPart>,\r\n): StreamTextResult {\r\n const broadcast = new PartBroadcast();\r\n const text = defer<string>();\r\n const reasoning = defer<string>();\r\n const usage = defer<TokenUsage>();\r\n const finishReason = defer<FinishReason>();\r\n const toolCalls = defer<ToolCallRecord[]>();\r\n\r\n void (async () => {\r\n let textBuffer = \"\";\r\n let reasoningBuffer = \"\";\r\n let lastUsage: TokenUsage = ZERO_USAGE;\r\n let lastFinish: FinishReason = \"unknown\";\r\n const toolCallsArr: ToolCallRecord[] = [];\r\n try {\r\n for await (const part of source) {\r\n if (part.type === \"text-delta\") textBuffer += part.textDelta;\r\n else if (part.type === \"reasoning\")\r\n reasoningBuffer += part.textDelta;\r\n else if (part.type === \"tool-call\") {\r\n toolCallsArr.push({\r\n toolCallId: part.toolCallId,\r\n toolName: part.toolName,\r\n args: part.args,\r\n });\r\n } else if (part.type === \"finish\") {\r\n lastFinish = part.finishReason;\r\n lastUsage = part.usage;\r\n }\r\n broadcast.push(part);\r\n }\r\n broadcast.end();\r\n text.resolve(textBuffer);\r\n reasoning.resolve(reasoningBuffer);\r\n usage.resolve(lastUsage);\r\n finishReason.resolve(lastFinish);\r\n toolCalls.resolve(toolCallsArr);\r\n } catch (error) {\r\n broadcast.fail(error);\r\n text.reject(error);\r\n reasoning.reject(error);\r\n usage.reject(error);\r\n finishReason.reject(error);\r\n toolCalls.reject(error);\r\n }\r\n })();\r\n\r\n return {\r\n fullStream: broadcast.consume(),\r\n textStream: {\r\n [Symbol.asyncIterator]: (): AsyncIterator<string> => {\r\n const inner = broadcast.consume()[Symbol.asyncIterator]();\r\n return {\r\n next: async (): Promise<IteratorResult<string>> => {\r\n while (true) {\r\n const r = await inner.next();\r\n if (r.done)\r\n return { value: undefined as unknown as string, done: true };\r\n if (r.value.type === \"text-delta\") {\r\n return { value: r.value.textDelta, done: false };\r\n }\r\n }\r\n },\r\n };\r\n },\r\n },\r\n text: text.promise,\r\n reasoning: reasoning.promise,\r\n usage: usage.promise,\r\n finishReason: finishReason.promise,\r\n toolCalls: toolCalls.promise,\r\n };\r\n}\r\n\r\nexport interface InferenceRequestContext {\r\n /** Resolved URL of the inference endpoint. */\r\n url: string;\r\n /** Pre-built request headers (`Content-Type` already set). */\r\n headers: Headers;\r\n /** Bound fetch (already wraps user `fetch` option). */\r\n fetch: typeof fetch;\r\n}\r\n\r\n/**\r\n * Open the inference SSE stream and return a `StreamTextResult`. Exposed\r\n * separately so `agents.run` can share the same fan-out plumbing later if\r\n * we ever want a backend-agnostic chunk format.\r\n */\r\nexport function streamInferenceFromContext(\r\n ctx: InferenceRequestContext,\r\n params: StreamTextParams,\r\n): StreamTextResult {\r\n const broadcast = new PartBroadcast();\r\n const text = defer<string>();\r\n const reasoning = defer<string>();\r\n const usage = defer<TokenUsage>();\r\n const finishReason = defer<FinishReason>();\r\n const toolCalls = defer<ToolCallRecord[]>();\r\n\r\n const start = async (): Promise<void> => {\r\n const response = await ctx.fetch(ctx.url, {\r\n method: \"POST\",\r\n headers: ctx.headers,\r\n body: JSON.stringify(buildInferenceRequestBody(params)),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n });\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n if (!response.body) {\r\n throw new RagableError(\"Inference stream has no body\", 502, {\r\n code: \"SDK_INFERENCE_STREAM_NO_BODY\",\r\n });\r\n }\r\n\r\n await consumeInferenceStream(response.body, broadcast, {\r\n text,\r\n reasoning,\r\n usage,\r\n finishReason,\r\n toolCalls,\r\n });\r\n };\r\n\r\n // Kick off in background — the consumer drives it via the iterables / promises.\r\n start().catch((err) => {\r\n broadcast.fail(err);\r\n text.reject(err);\r\n reasoning.reject(err);\r\n usage.reject(err);\r\n finishReason.reject(err);\r\n toolCalls.reject(err);\r\n });\r\n\r\n return {\r\n fullStream: broadcast.consume(),\r\n textStream: {\r\n [Symbol.asyncIterator]: (): AsyncIterator<string> => {\r\n const inner = broadcast.consume()[Symbol.asyncIterator]();\r\n return {\r\n next: async (): Promise<IteratorResult<string>> => {\r\n while (true) {\r\n const r = await inner.next();\r\n if (r.done) return { value: undefined as unknown as string, done: true };\r\n if (r.value.type === \"text-delta\") {\r\n return { value: r.value.textDelta, done: false };\r\n }\r\n }\r\n },\r\n };\r\n },\r\n },\r\n text: text.promise,\r\n reasoning: reasoning.promise,\r\n usage: usage.promise,\r\n finishReason: finishReason.promise,\r\n toolCalls: toolCalls.promise,\r\n };\r\n}\r\n\r\ninterface AiClientOptions {\r\n organizationId: string;\r\n websiteId?: string;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n /** API base override; defaults to the shared SDK base. */\r\n apiBase: string;\r\n}\r\n\r\nexport class RagableBrowserAiClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(private readonly options: AiClientOptions) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const id = this.options.websiteId?.trim();\r\n if (!id) {\r\n throw new RagableError(\r\n \"client.ai.streamText requires websiteId on the client. Pass createBrowserClient({ websiteId, organizationId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return id;\r\n }\r\n\r\n private buildContext(): InferenceRequestContext {\r\n const url = `${this.options.apiBase}/public/organizations/${encodeURIComponent(\r\n this.options.organizationId,\r\n )}/websites/${encodeURIComponent(\r\n this.requireWebsiteId(),\r\n )}/inference/stream`;\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n headers.set(\"Accept\", \"text/event-stream\");\r\n return { url, headers, fetch: this.fetchImpl };\r\n }\r\n\r\n streamText(params: StreamTextParams): StreamTextResult {\r\n return streamInferenceFromContext(this.buildContext(), params);\r\n }\r\n\r\n async generateText(params: StreamTextParams): Promise<GenerateTextResult> {\r\n const result = this.streamText(params);\r\n // Drain the fullStream so promises settle even if the caller never iterates.\r\n for await (const _ of result.fullStream) {\r\n void _;\r\n }\r\n const [text, reasoning, usage, finishReason, toolCalls] = await Promise.all(\r\n [\r\n result.text,\r\n result.reasoning,\r\n result.usage,\r\n result.finishReason,\r\n result.toolCalls,\r\n ],\r\n );\r\n return { text, reasoning, usage, finishReason, toolCalls };\r\n }\r\n\r\n /**\r\n * Stream a JSON-Schema-constrained response. Matches Vercel AI SDK's\r\n * `streamObject` shape — returns a synchronous result with `partialObjectStream`\r\n * (best-effort incremental parses) and `object` (the final parsed JSON).\r\n *\r\n * ```ts\r\n * const { partialObjectStream, object } = client.ai.streamObject({\r\n * model: \"accounts/fireworks/models/kimi-k2p5\",\r\n * schema: {\r\n * type: \"object\",\r\n * properties: {\r\n * title: { type: \"string\" },\r\n * tags: { type: \"array\", items: { type: \"string\" } },\r\n * },\r\n * required: [\"title\", \"tags\"],\r\n * },\r\n * messages: [{ role: \"user\", content: \"Give me a blog post idea about AI.\" }],\r\n * });\r\n * for await (const partial of partialObjectStream) renderPreview(partial);\r\n * const final = await object;\r\n * ```\r\n */\r\n streamObject<T = unknown>(\r\n params: StreamObjectParams,\r\n ): StreamObjectResult<T> {\r\n return streamObjectFromContext<T>(this.buildContext(), params);\r\n }\r\n\r\n /**\r\n * Non-streaming variant of {@link streamObject}. Resolves once the model\r\n * finishes; rejects if the final text isn't valid JSON for the schema.\r\n */\r\n async generateObject<T = unknown>(\r\n params: StreamObjectParams,\r\n ): Promise<GenerateObjectResult<T>> {\r\n const result = this.streamObject<T>(params);\r\n // Drain partials so promises settle even if the caller skips iteration.\r\n for await (const _ of result.partialObjectStream) {\r\n void _;\r\n }\r\n const [object, usage, finishReason, toolCalls] = await Promise.all([\r\n result.object,\r\n result.usage,\r\n result.finishReason,\r\n result.toolCalls,\r\n ]);\r\n return { object, usage, finishReason, toolCalls };\r\n }\r\n}\r\n\r\n/**\r\n * Open a JSON-mode inference stream against the proxy and return a\r\n * `StreamObjectResult`. Exposed for advanced callers; most code should use\r\n * `RagableBrowserAiClient.streamObject`.\r\n */\r\nexport function streamObjectFromContext<T = unknown>(\r\n ctx: InferenceRequestContext,\r\n params: StreamObjectParams,\r\n): StreamObjectResult<T> {\r\n // Reuse streamText's wire path — the response_format is the only diff.\r\n const textParams: StreamTextParams = {\r\n model: params.model,\r\n messages: params.messages,\r\n ...(params.system !== undefined ? { system: params.system } : {}),\r\n ...(typeof params.temperature === \"number\"\r\n ? { temperature: params.temperature }\r\n : {}),\r\n ...(typeof params.maxTokens === \"number\"\r\n ? { maxTokens: params.maxTokens }\r\n : {}),\r\n ...(typeof params.topP === \"number\" ? { topP: params.topP } : {}),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n };\r\n const responseFormat = buildResponseFormat({\r\n schema: params.schema,\r\n ...(params.schemaName !== undefined ? { name: params.schemaName } : {}),\r\n ...(params.schemaDescription !== undefined\r\n ? { description: params.schemaDescription }\r\n : {}),\r\n });\r\n\r\n // Custom request body builder that injects response_format.\r\n const overrideCtx: InferenceRequestContext = {\r\n ...ctx,\r\n // Wrap fetch to substitute the body. We can't change buildInferenceRequestBody\r\n // signature on the call site cleanly, so intercept here.\r\n fetch: ((input, init) => {\r\n if (init && typeof init.body === \"string\") {\r\n const parsed = JSON.parse(init.body) as Record<string, unknown>;\r\n parsed.response_format = responseFormat;\r\n const newInit: RequestInit = { ...init, body: JSON.stringify(parsed) };\r\n return ctx.fetch(input, newInit);\r\n }\r\n return ctx.fetch(input, init);\r\n }) as typeof fetch,\r\n };\r\n\r\n const inner = streamInferenceFromContext(overrideCtx, textParams);\r\n return wrapStreamTextAsObject<T>(inner);\r\n}\r\n\r\n/**\r\n * Wrap a `StreamTextResult` (text-only stream) into a `StreamObjectResult`\r\n * by parsing the accumulated text as JSON. The text path stays the source of\r\n * truth for `text`/`usage`/`finishReason`/`toolCalls`; this helper only adds\r\n * `partialObjectStream` and `object` on top.\r\n *\r\n * Public so `client.agents.runObject` can reuse the parsing logic — agents\r\n * stream text through their own SSE protocol, but the structured-output\r\n * conversion is identical.\r\n */\r\nexport function wrapStreamTextAsObject<T = unknown>(\r\n inner: StreamTextResult,\r\n): StreamObjectResult<T> {\r\n const partialBroadcast = new PartialObjectBroadcast<T>();\r\n const objectDeferred = defer<T>();\r\n\r\n void (async () => {\r\n let acc = \"\";\r\n let lastEmitted: unknown = Symbol(\"none\");\r\n try {\r\n for await (const delta of inner.textStream) {\r\n acc += delta;\r\n const candidate = tryParsePartialJson(acc);\r\n if (candidate !== undefined && !sameSnapshot(candidate, lastEmitted)) {\r\n lastEmitted = candidate;\r\n partialBroadcast.push(candidate as T);\r\n }\r\n }\r\n const finalText = await inner.text;\r\n // Strict parse for the final value — partial-mode repairs are not allowed here.\r\n let finalObj: T;\r\n try {\r\n finalObj = JSON.parse(finalText) as T;\r\n } catch (e) {\r\n const err = new RagableError(\r\n `Model output is not valid JSON: ${(e as Error).message}`,\r\n 502,\r\n {\r\n code: \"SDK_OBJECT_PARSE_FAILED\",\r\n raw: finalText.slice(0, 1000),\r\n },\r\n );\r\n partialBroadcast.fail(err);\r\n objectDeferred.reject(err);\r\n return;\r\n }\r\n if (!sameSnapshot(finalObj, lastEmitted)) {\r\n partialBroadcast.push(finalObj);\r\n }\r\n partialBroadcast.end();\r\n objectDeferred.resolve(finalObj);\r\n } catch (err) {\r\n partialBroadcast.fail(err);\r\n objectDeferred.reject(err);\r\n }\r\n })();\r\n\r\n return {\r\n textStream: inner.textStream,\r\n partialObjectStream: partialBroadcast.consume(),\r\n object: objectDeferred.promise,\r\n text: inner.text,\r\n usage: inner.usage,\r\n finishReason: inner.finishReason,\r\n toolCalls: inner.toolCalls,\r\n };\r\n}\r\n\r\n/** Tiny snapshot comparator — JSON.stringify is fine for the sizes we deal with. */\r\nfunction sameSnapshot(a: unknown, b: unknown): boolean {\r\n if (a === b) return true;\r\n try {\r\n return JSON.stringify(a) === JSON.stringify(b);\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/** Replay-from-start broadcast of partial objects. Mirrors PartBroadcast but typed. */\r\nclass PartialObjectBroadcast<T> {\r\n private items: T[] = [];\r\n private resolved = false;\r\n private error: unknown = null;\r\n private waiters: Array<() => void> = [];\r\n\r\n push(item: T): void {\r\n this.items.push(item);\r\n this.notify();\r\n }\r\n\r\n end(): void {\r\n if (this.resolved) return;\r\n this.resolved = true;\r\n this.notify();\r\n }\r\n\r\n fail(error: unknown): void {\r\n if (this.resolved) return;\r\n this.error = error;\r\n this.resolved = true;\r\n this.notify();\r\n }\r\n\r\n private notify(): void {\r\n const w = this.waiters;\r\n this.waiters = [];\r\n for (const fn of w) fn();\r\n }\r\n\r\n consume(): AsyncIterable<T> {\r\n const self = this;\r\n return {\r\n [Symbol.asyncIterator]: (): AsyncIterator<T> => {\r\n let idx = 0;\r\n return {\r\n next: async (): Promise<IteratorResult<T>> => {\r\n while (true) {\r\n if (idx < self.items.length) {\r\n return { value: self.items[idx++]!, done: false };\r\n }\r\n if (self.resolved) {\r\n if (self.error) throw self.error;\r\n return { value: undefined as unknown as T, done: true };\r\n }\r\n await new Promise<void>((res) => self.waiters.push(res));\r\n }\r\n },\r\n };\r\n },\r\n };\r\n }\r\n}\r\n","import type {\r\n AgentChatStreamUiHandlers,\r\n AgentChatUiStreamResult,\r\n} from \"./agent-chat-ui\";\r\nimport { runAgentChatStreamForUi } from \"./agent-chat-ui\";\r\nimport {\r\n runAgentChatStream,\r\n type AgentChatStreamHandlers,\r\n type AgentChatStreamResult,\r\n type AgentChatParams,\r\n type AgentStreamEvent,\r\n} from \"./agent-stream\";\r\nimport {\r\n bindFetch,\r\n DEFAULT_RAGABLE_API_BASE,\r\n extractErrorMessage,\r\n RagableError,\r\n} from \"./request-client\";\r\nimport type {\r\n DefaultRagableDatabase,\r\n RagableDatabase,\r\n RagableTableNames,\r\n TableInsertRow,\r\n TableRow,\r\n TableUpdatePatch,\r\n} from \"./database-schema\";\r\nimport { parseMaybeJsonBody, readSseStream } from \"./sse\";\r\nimport {\r\n asPostgrestResponse,\r\n PostgrestTableApi,\r\n type PostgRESTFetch,\r\n type PostgRESTFetchParams,\r\n type PostgrestResult,\r\n} from \"./browser-postgrest\";\r\nexport {\r\n assertPostgrestSuccess,\r\n toRagableResult,\r\n unwrapPostgrest,\r\n} from \"./browser-postgrest\";\r\nimport {\r\n RagableAuth,\r\n type AuthSignUpCredentials,\r\n type AuthChangeEvent,\r\n type AuthOptions,\r\n type AuthSession,\r\n type AuthUpdateUserAttributes,\r\n type AuthUserMetadata,\r\n type DefaultAuthUser,\r\n} from \"./auth\";\r\nimport { Transport, type TransportOptions } from \"./transport\";\r\nimport {\r\n RagableBrowserAiClient,\r\n buildResponseFormat,\r\n createStreamResultFromParts,\r\n wrapStreamTextAsObject,\r\n type GenerateObjectResult,\r\n type JsonSchema,\r\n type StreamObjectResult,\r\n type StreamTextResult,\r\n} from \"./ai\";\r\nimport type {\r\n DefaultRagableFunctions,\r\n FunctionInvoker,\r\n RagableFunctionInvokeOptions,\r\n RagableFunctions,\r\n} from \"./functions\";\r\nimport { mapAgentEvent, type StreamPart, type Message } from \"./stream-parts\";\r\n\r\n/** Canonical browser/server API base (`…/api`, no trailing slash). */\r\nexport function normalizeBrowserApiBase(): string {\r\n return DEFAULT_RAGABLE_API_BASE.replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport type BrowserDataAuthMode = \"user\" | \"publicAnon\" | \"admin\" | \"auto\";\r\n\r\n/**\r\n * Resolves how database / storage requests are authorized.\r\n *\r\n * Default (when `dataAuth` is omitted):\r\n * - **`auto`** when BOTH a static data key AND user auth (an `authGroupId` or a\r\n * `getAccessToken` callback) are configured — the generated-site case. This is\r\n * the Supabase model: send the signed-in user's JWT when a session exists, and\r\n * fall back to the public anon key for logged-out visitors. Without this, a\r\n * shipped anon key permanently shadows the user session, so owner/group/claim/\r\n * authenticated collection grants can never match a signed-in user.\r\n * - **`publicAnon`** when only a static key is configured (no auth group) — a\r\n * purely public app.\r\n * - **`user`** when neither — JWT-only.\r\n *\r\n * Set `dataAuth` explicitly to override: `\"user\"` (JWT required), `\"publicAnon\"`\r\n * (anon key only, never upgrade), or `\"admin\"` (the static key is a data-admin key).\r\n */\r\nexport function effectiveDataAuth(\r\n options: RagableBrowserClientOptions,\r\n): BrowserDataAuthMode {\r\n if (options.dataAuth) return options.dataAuth;\r\n const hasStatic =\r\n Boolean(options.dataStaticKey?.trim()) ||\r\n typeof options.getDataStaticKey === \"function\";\r\n const canUserAuth =\r\n Boolean(options.authGroupId?.trim()) ||\r\n typeof options.getAccessToken === \"function\";\r\n if (hasStatic && canUserAuth) return \"auto\";\r\n if (hasStatic) return \"publicAnon\";\r\n return \"user\";\r\n}\r\n\r\nexport interface RagableBrowserClientOptions {\r\n organizationId: string;\r\n websiteId?: string;\r\n authGroupId?: string;\r\n databaseInstanceId?: string;\r\n /** When omitted, inferred from static keys — see {@link effectiveDataAuth}. */\r\n dataAuth?: BrowserDataAuthMode;\r\n /** Public anon or data-admin key from the dashboard (Browser Data API keys). */\r\n dataStaticKey?: string;\r\n getDataStaticKey?: () => string | null | Promise<string | null>;\r\n getAccessToken?: () => string | null | Promise<string | null>;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n auth?: AuthOptions;\r\n transport?: Partial<TransportOptions>;\r\n}\r\n\r\nfunction requireAuthGroupId(options: RagableBrowserClientOptions): string {\r\n const id = options.authGroupId?.trim();\r\n if (!id) {\r\n throw new RagableError(\r\n \"authGroupId is required for auth and database methods on the browser client\",\r\n 400,\r\n { code: \"SDK_MISSING_AUTH_GROUP_ID\" },\r\n );\r\n }\r\n return id;\r\n}\r\n\r\n/**\r\n * Best-effort signed-in user token: the SDK-managed session (auto-refreshed) if\r\n * present, else a caller-supplied `getAccessToken`. Returns null instead of\r\n * throwing, so callers can fall back to an anon key.\r\n */\r\nasync function tryGetUserAccessToken(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n): Promise<string | null> {\r\n if (ragableAuth) {\r\n const token = await ragableAuth.getValidAccessToken().catch(() => null);\r\n if (token?.trim()) return token.trim();\r\n }\r\n const getter = options.getAccessToken;\r\n if (getter) {\r\n const token = await getter();\r\n if (token?.trim()) return token.trim();\r\n }\r\n return null;\r\n}\r\n\r\n/** Resolve the configured static browser-data key (anon or admin), or null. */\r\nasync function resolveStaticDataKey(\r\n options: RagableBrowserClientOptions,\r\n): Promise<string | null> {\r\n const fromGetter = options.getDataStaticKey\r\n ? await options.getDataStaticKey()\r\n : null;\r\n const key = (fromGetter?.trim() || options.dataStaticKey?.trim()) ?? \"\";\r\n return key || null;\r\n}\r\n\r\nasync function requireAccessToken(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n): Promise<string> {\r\n const token = await tryGetUserAccessToken(options, ragableAuth);\r\n if (token) return token;\r\n throw new RagableError(\r\n \"No access token available. Sign in first with auth.signInWithPassword() or provide getAccessToken callback.\",\r\n 401,\r\n { code: \"SDK_NO_ACCESS_TOKEN\" },\r\n );\r\n}\r\n\r\n/**\r\n * Resolve the Bearer used for database / storage requests, per {@link effectiveDataAuth}.\r\n * In `auto` mode a live user session takes precedence over the anon key, so a\r\n * signed-in user's identity reaches the data plane automatically.\r\n */\r\nasync function resolveDatabaseAuthBearer(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n): Promise<string> {\r\n const mode = effectiveDataAuth(options);\r\n if (mode === \"user\") {\r\n return requireAccessToken(options, ragableAuth);\r\n }\r\n if (mode === \"auto\") {\r\n const userTok = await tryGetUserAccessToken(options, ragableAuth);\r\n if (userTok) return userTok;\r\n const key = await resolveStaticDataKey(options);\r\n if (key) return key;\r\n throw new RagableError(\r\n \"No access token or data key available. Sign in with auth.signInWithPassword() or configure dataStaticKey.\",\r\n 401,\r\n { code: \"SDK_NO_ACCESS_TOKEN\" },\r\n );\r\n }\r\n // publicAnon | admin: the static key is the only accepted credential.\r\n const key = await resolveStaticDataKey(options);\r\n if (!key) {\r\n throw new RagableError(\r\n mode === \"publicAnon\"\r\n ? \"dataAuth publicAnon requires getDataStaticKey or dataStaticKey\"\r\n : \"dataAuth admin requires getDataStaticKey or dataStaticKey\",\r\n 400,\r\n { code: \"SDK_MISSING_STATIC_KEY\" },\r\n );\r\n }\r\n return key;\r\n}\r\n\r\n// ─── Session types (kept for back-compat) ────────────────────────────────────\r\n\r\nexport interface BrowserAuthSession<\r\n AuthUser extends object = DefaultAuthUser,\r\n> {\r\n user: AuthUser;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n}\r\n\r\nexport interface BrowserAuthTokens {\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n}\r\n\r\nexport interface SupabaseCompatSession<\r\n AuthUser extends object = DefaultAuthUser,\r\n> {\r\n access_token: string;\r\n refresh_token: string;\r\n expires_in: number;\r\n token_type: \"bearer\";\r\n user: AuthUser;\r\n}\r\n\r\nexport type { PostgrestResult };\r\nexport type { RagableResult } from \"./browser-postgrest\";\r\n\r\n// ─── RagableBrowserAuthClient (back-compat shim) ─────────────────────────────\r\n\r\nexport class RagableBrowserAuthClient<\r\n AuthUser extends object = DefaultAuthUser,\r\n> {\r\n constructor(\r\n _options: RagableBrowserClientOptions,\r\n private readonly ragableAuth: RagableAuth<AuthUser> | null = null,\r\n ) {}\r\n\r\n private get auth(): RagableAuth<AuthUser> {\r\n if (!this.ragableAuth) {\r\n throw new Error(\"Auth not initialized — provide authGroupId to enable auth\");\r\n }\r\n return this.ragableAuth;\r\n }\r\n\r\n async signUp(\r\n credentials: AuthSignUpCredentials<\r\n AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Metadata\r\n : AuthUserMetadata\r\n : AuthUserMetadata\r\n >,\r\n ): Promise<\r\n PostgrestResult<{\r\n user: AuthUser;\r\n session: SupabaseCompatSession<AuthUser>;\r\n }>\r\n > {\r\n const result = await this.auth.signUp(credentials);\r\n if (result.error) return { data: null, error: result.error };\r\n const session = result.data!.session;\r\n return {\r\n data: {\r\n user: session.user,\r\n session: {\r\n access_token: session.access_token,\r\n refresh_token: session.refresh_token,\r\n expires_in: session.expires_in,\r\n token_type: \"bearer\",\r\n user: session.user,\r\n },\r\n },\r\n error: null,\r\n };\r\n }\r\n\r\n async signInWithPassword(credentials: {\r\n email: string;\r\n password: string;\r\n }): Promise<\r\n PostgrestResult<{\r\n user: AuthUser;\r\n session: SupabaseCompatSession<AuthUser>;\r\n }>\r\n > {\r\n const result = await this.auth.signInWithPassword(credentials);\r\n if (result.error) return { data: null, error: result.error };\r\n const session = result.data!.session;\r\n return {\r\n data: {\r\n user: session.user,\r\n session: {\r\n access_token: session.access_token,\r\n refresh_token: session.refresh_token,\r\n expires_in: session.expires_in,\r\n token_type: \"bearer\",\r\n user: session.user,\r\n },\r\n },\r\n error: null,\r\n };\r\n }\r\n\r\n async refreshSession(refreshToken: string): Promise<\r\n PostgrestResult<{ session: SupabaseCompatSession<AuthUser>; user: AuthUser }>\r\n > {\r\n const result = await this.auth.refreshSession(refreshToken);\r\n if (result.error) return { data: null, error: result.error };\r\n const session = result.data!.session;\r\n return {\r\n data: {\r\n user: session.user,\r\n session: {\r\n access_token: session.access_token,\r\n refresh_token: session.refresh_token,\r\n expires_in: session.expires_in,\r\n token_type: \"bearer\",\r\n user: session.user,\r\n },\r\n },\r\n error: null,\r\n };\r\n }\r\n\r\n async getUser(): Promise<PostgrestResult<{ user: AuthUser }>> {\r\n return this.auth.getUser();\r\n }\r\n\r\n async updateUser(\r\n attributes: AuthUpdateUserAttributes<\r\n AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Metadata\r\n : AuthUserMetadata\r\n : AuthUserMetadata\r\n >,\r\n ): Promise<PostgrestResult<{ user: AuthUser }>> {\r\n return this.auth.updateUser(attributes);\r\n }\r\n\r\n async signOut(_options?: { scope?: \"global\" | \"local\" }): Promise<{\r\n error: null;\r\n }> {\r\n return this.auth.signOut(_options);\r\n }\r\n\r\n async register(body: {\r\n email: string;\r\n password: string;\r\n name?: string;\r\n data?: AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Partial<Metadata> & { name?: string | null }\r\n : Record<string, unknown>\r\n : Record<string, unknown>;\r\n }): Promise<BrowserAuthSession<AuthUser>> {\r\n return this.auth.register(body as Parameters<RagableAuth<AuthUser>[\"register\"]>[0]);\r\n }\r\n\r\n async login(body: {\r\n email: string;\r\n password: string;\r\n }): Promise<BrowserAuthSession<AuthUser>> {\r\n return this.auth.login(body);\r\n }\r\n\r\n async refresh(body: { refreshToken: string }): Promise<BrowserAuthTokens> {\r\n return this.auth.refresh(body);\r\n }\r\n\r\n async getMe(): Promise<{ user: AuthUser }> {\r\n return this.auth.getMe();\r\n }\r\n\r\n async updateMe(body: {\r\n email?: string;\r\n name?: string | null;\r\n password?: string;\r\n data?: AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Partial<Metadata> & { name?: string | null }\r\n : Record<string, unknown>\r\n : Record<string, unknown>;\r\n }): Promise<{ user: AuthUser }> {\r\n return this.auth.updateMe(body as Parameters<RagableAuth<AuthUser>[\"updateMe\"]>[0]);\r\n }\r\n\r\n onAuthStateChange(\r\n callback: (event: AuthChangeEvent, session: AuthSession<AuthUser> | null) => void,\r\n ): { data: { subscription: { id: string; unsubscribe: () => void } } } {\r\n return this.auth.onAuthStateChange(callback);\r\n }\r\n\r\n getSession(): Promise<PostgrestResult<{ session: AuthSession<AuthUser> | null }>> {\r\n return this.auth.getSession();\r\n }\r\n\r\n /**\r\n * Returns a valid (auto-refreshed) access token for the current session, or\r\n * `null` if signed out. The sanctioned way to obtain a token for a hand-rolled\r\n * `fetch` to a custom endpoint — never read tokens out of storage yourself.\r\n */\r\n getValidAccessToken(): Promise<string | null> {\r\n return this.ragableAuth\r\n ? this.ragableAuth.getValidAccessToken()\r\n : Promise.resolve(null);\r\n }\r\n}\r\n\r\n// ─── SQL query types ─────────────────────────────────────────────────────────\r\n\r\nexport interface BrowserSqlQueryParams {\r\n databaseInstanceId?: string;\r\n sql: string;\r\n params?: unknown[];\r\n readOnly?: boolean;\r\n timeoutMs?: number;\r\n rowLimit?: number;\r\n}\r\n\r\nexport interface BrowserSqlQueryResult<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> {\r\n command: string;\r\n rowCount: number;\r\n truncated: boolean;\r\n rows: Row[];\r\n}\r\n\r\n// ─── Database client ─────────────────────────────────────────────────────────\r\n\r\nexport interface BrowserCollectionRecord<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> {\r\n [key: string]: unknown;\r\n id: string;\r\n data: Row;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\n/**\r\n * Collection APIs return record envelopes, but user schema `Row` types should be\r\n * the JSON row inside `record.data`. If generated app types accidentally use the\r\n * envelope as `Row`, unwrap it so consumers still get `record.data.<field>`.\r\n */\r\nexport type BrowserCollectionRowData<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = Row extends {\r\n id: string;\r\n data: infer Data;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n ? Data extends Record<string, unknown>\r\n ? Data\r\n : Row\r\n : Row;\r\n\r\ntype BrowserCollectionInsertData<\r\n Row extends Record<string, unknown>,\r\n Insert extends Record<string, unknown>,\r\n> = BrowserCollectionRowData<Row> extends Row\r\n ? Insert\r\n : Insert extends {\r\n data: infer Data;\r\n }\r\n ? Data extends Record<string, unknown>\r\n ? Data\r\n : BrowserCollectionRowData<Row>\r\n : BrowserCollectionRowData<Row>;\r\n\r\ntype BrowserCollectionUpdateData<\r\n Row extends Record<string, unknown>,\r\n Update extends Record<string, unknown>,\r\n> = BrowserCollectionRowData<Row> extends Row\r\n ? Update\r\n : Update extends {\r\n data?: infer Data;\r\n }\r\n ? Data extends Record<string, unknown>\r\n ? Partial<Data>\r\n : Partial<BrowserCollectionRowData<Row>>\r\n : Partial<BrowserCollectionRowData<Row>>;\r\n\r\nexport interface BrowserCollectionDefinition {\r\n id: string;\r\n name: string;\r\n schema: Record<string, unknown> | null;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\n/**\r\n * Prisma-style operator object for a single field (server-supported ops).\r\n * Typed loosely so schema-specific refinements can be added in app code.\r\n */\r\nexport type WhereOperatorObject = {\r\n eq?: unknown;\r\n neq?: unknown;\r\n gt?: number;\r\n gte?: number;\r\n lt?: number;\r\n lte?: number;\r\n in?: unknown;\r\n contains?: unknown;\r\n};\r\n\r\n/**\r\n * `where` filters: equality on values, or per-field operator objects.\r\n * Use `id`, `createdAt`, `updatedAt` to match the record envelope (DB columns), not `data` JSON\r\n * (unless you also have those keys in your JSON — prefer envelope keys for `id`).\r\n */\r\nexport type WhereInput<Row extends Record<string, unknown>> = {\r\n [K in keyof Row]?: Row[K] | WhereOperatorObject | null;\r\n} & {\r\n id?: string | WhereOperatorObject;\r\n createdAt?: string | WhereOperatorObject;\r\n updatedAt?: string | WhereOperatorObject;\r\n};\r\n\r\n/** @deprecated Use {@link WhereInput} — same shape. */\r\nexport type CollectionWhere<Row extends Record<string, unknown>> = WhereInput<Row>;\r\n\r\ntype CollectionFilter<Row extends Record<string, unknown>> = {\r\n [Field in Extract<keyof Row, string>]: {\r\n field: Field;\r\n op?: \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\" | \"contains\";\r\n value: Row[Field];\r\n };\r\n}[Extract<keyof Row, string>];\r\n\r\nexport type CollectionReturnMode = \"envelope\" | \"flat\";\r\n\r\n/**\r\n * One row: JSON fields at the top level, envelope fields under `meta`\r\n * (when using {@link BrowserCollectionApi.findMany} with `return: \"flat\"`).\r\n */\r\nexport type CollectionRowWithMeta<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = Row & {\r\n meta: { id: string; createdAt: string; updatedAt: string };\r\n};\r\n\r\nexport function collectionRecordToRowWithMeta<Row extends Record<string, unknown>>(\r\n record: BrowserCollectionRecord<Row>,\r\n): CollectionRowWithMeta<Row> {\r\n const { data, id, createdAt, updatedAt } = record;\r\n return { ...(data as Row), meta: { id, createdAt, updatedAt } };\r\n}\r\n\r\nexport function collectionRecordsToRowWithMeta<Row extends Record<string, unknown>>(\r\n records: BrowserCollectionRecord<Row>[],\r\n): CollectionRowWithMeta<Row>[] {\r\n return records.map(collectionRecordToRowWithMeta);\r\n}\r\n\r\n/**\r\n * Rows returned by a find: {@link CollectionRowWithMeta} when the params carry\r\n * a literal `return: \"flat\"`, envelope {@link BrowserCollectionRecord}s\r\n * otherwise. Keeps the default (envelope) call sites free of union-narrowing —\r\n * `res.data[0].data` typechecks without a cast.\r\n */\r\nexport type CollectionFindResult<\r\n Row extends Record<string, unknown>,\r\n Params,\r\n> = Params extends { return: \"flat\" }\r\n ? CollectionRowWithMeta<Row>[]\r\n : BrowserCollectionRecord<Row>[];\r\n\r\nconst FIND_QUERY_KEYS = [\r\n \"where\",\r\n \"filters\",\r\n \"limit\",\r\n \"offset\",\r\n \"orderBy\",\r\n \"orderDirection\",\r\n \"return\",\r\n] as const;\r\n\r\nexport type BrowserCollectionFindParams<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = {\r\n where?: WhereInput<Row>;\r\n filters?: Array<{\r\n field: Extract<keyof Row, string> | (string & {});\r\n op?: \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\" | \"contains\";\r\n value: unknown;\r\n } | CollectionFilter<Row>>;\r\n limit?: number;\r\n offset?: number;\r\n orderBy?:\r\n | Extract<keyof Row, string>\r\n | \"id\"\r\n | \"createdAt\"\r\n | \"updatedAt\"\r\n | (string & {});\r\n orderDirection?: \"asc\" | \"desc\";\r\n /**\r\n * - `envelope` (default): `Array<{ id, data, createdAt, updatedAt }>`\r\n * - `flat`: {@link CollectionRowWithMeta} — row fields at top level + `meta` for `id` / timestamps\r\n */\r\n return?: CollectionReturnMode;\r\n};\r\n\r\nexport type CollectionRowData<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = BrowserCollectionRowData<Row>;\r\n\r\ntype RowD<Row extends Record<string, unknown>> = BrowserCollectionRowData<Row>;\r\n\r\nexport class BrowserCollectionApi<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n Insert extends Record<string, unknown> = Row,\r\n Update extends Record<string, unknown> = Partial<Row>,\r\n> {\r\n constructor(\r\n private readonly database: RagableBrowserDatabaseClient<any>,\r\n private readonly name: string,\r\n private readonly databaseInstanceId?: string,\r\n ) {}\r\n\r\n private normalizeFindArgs(whereOrParams: unknown): {\r\n returnMode: CollectionReturnMode;\r\n body: Record<string, unknown>;\r\n } {\r\n const hasQueryKeys =\r\n typeof whereOrParams === \"object\" &&\r\n whereOrParams !== null &&\r\n FIND_QUERY_KEYS.some((key) =>\r\n Object.prototype.hasOwnProperty.call(whereOrParams, key),\r\n );\r\n const raw: Record<string, unknown> = hasQueryKeys\r\n ? { ...(whereOrParams as object) }\r\n : { where: whereOrParams };\r\n const returnMode: CollectionReturnMode =\r\n raw[\"return\"] === \"flat\" ? \"flat\" : \"envelope\";\r\n delete raw[\"return\"];\r\n return { returnMode, body: raw };\r\n }\r\n\r\n private requestFind = (\r\n body: Record<string, unknown>,\r\n ): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>> =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>[]>(\r\n \"POST\",\r\n `/${encodeURIComponent(this.name)}/find`,\r\n body,\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Query collection rows. Prefer this over the deprecated `find` alias.\r\n * Use `return: \"flat\"` to get {@link CollectionRowWithMeta} without nested `.data`.\r\n */\r\n findMany = async <\r\n Params extends\r\n | WhereInput<RowD<Row>>\r\n | BrowserCollectionFindParams<RowD<Row>>,\r\n >(\r\n whereOrParams: Params = {} as Params,\r\n ): Promise<PostgrestResult<CollectionFindResult<RowD<Row>, Params>>> => {\r\n const { returnMode, body } = this.normalizeFindArgs(whereOrParams);\r\n const res = await this.requestFind(body);\r\n if (res.error) return res;\r\n const data =\r\n returnMode === \"flat\"\r\n ? collectionRecordsToRowWithMeta<RowD<Row>>(res.data)\r\n : res.data;\r\n return {\r\n data: data as CollectionFindResult<RowD<Row>, Params>,\r\n error: null,\r\n };\r\n };\r\n\r\n /**\r\n * @deprecated Use {@link BrowserCollectionApi.findMany} — same behavior.\r\n */\r\n find = <\r\n Params extends\r\n | WhereInput<RowD<Row>>\r\n | BrowserCollectionFindParams<RowD<Row>>,\r\n >(\r\n whereOrParams: Params = {} as Params,\r\n ): Promise<PostgrestResult<CollectionFindResult<RowD<Row>, Params>>> =>\r\n this.findMany(whereOrParams);\r\n\r\n /**\r\n * At most one row, `data` is the record or `null` if none match (not an error).\r\n */\r\n findFirst = async (\r\n whereOrParams:\r\n | WhereInput<RowD<Row>>\r\n | Omit<BrowserCollectionFindParams<RowD<Row>>, \"return\"> = {},\r\n ): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>> | null>> => {\r\n const { body } = this.normalizeFindArgs(whereOrParams);\r\n const withCap = { ...body, limit: 1, offset: body[\"offset\"] ?? 0 };\r\n const res = await this.requestFind(withCap);\r\n if (res.error) return res;\r\n return { data: res.data[0] ?? null, error: null };\r\n };\r\n\r\n /**\r\n * Lookup by primary key `id` (envelope). Equivalent to\r\n * `findFirst({ where: { id }, limit: 1 })` with a typed `where.id`.\r\n */\r\n findUnique = async (args: {\r\n where: { id: string } & Partial<WhereInput<RowD<Row>>>;\r\n }): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>> | null>> => {\r\n return this.findFirst({ where: args.where });\r\n };\r\n\r\n insert = (\r\n data: BrowserCollectionInsertData<Row, Insert>,\r\n ): Promise<\r\n PostgrestResult<BrowserCollectionRecord<RowD<Row>>>\r\n > =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>>(\r\n \"POST\",\r\n `/${encodeURIComponent(this.name)}/records`,\r\n { data },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Insert multiple rows in one request (server multi-value `INSERT`, single transaction).\r\n * Empty **`items`** resolves to an empty array. Max batch size is enforced on the server (500).\r\n */\r\n insertMany = (\r\n items: BrowserCollectionInsertData<Row, Insert>[],\r\n ): Promise<\r\n PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>\r\n > =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>[]>(\r\n \"POST\",\r\n `/${encodeURIComponent(this.name)}/records/batch`,\r\n { items },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Update rows matching `where` (JSON fields, plus envelope `id` / `createdAt` / `updatedAt`).\r\n */\r\n update = (\r\n where: WhereInput<RowD<Row>>,\r\n patch: BrowserCollectionUpdateData<Row, Update>,\r\n options?: { limit?: number },\r\n ): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>> =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>[]>(\r\n \"PATCH\",\r\n `/${encodeURIComponent(this.name)}/records`,\r\n { where, patch, ...(options?.limit ? { limit: options.limit } : {}) },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Like {@link BrowserCollectionApi.update} but the success payload includes\r\n * `meta.count` (number of rows returned from the update, bounded by `limit`).\r\n */\r\n updateMany = async (\r\n where: WhereInput<RowD<Row>>,\r\n patch: BrowserCollectionUpdateData<Row, Update>,\r\n options?: { limit?: number },\r\n ): Promise<\r\n PostgrestResult<{\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n meta: { count: number };\r\n }>\r\n > => {\r\n const r = await this.update(where, patch, options);\r\n if (r.error) return r;\r\n return { data: { records: r.data, meta: { count: r.data.length } }, error: null };\r\n };\r\n\r\n delete = (\r\n where: WhereInput<RowD<Row>>,\r\n options?: { limit?: number },\r\n ): Promise<\r\n PostgrestResult<{\r\n deleted: number;\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n }>\r\n > =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<{\r\n deleted: number;\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n }>(\r\n \"DELETE\",\r\n `/${encodeURIComponent(this.name)}/records`,\r\n { where, ...(options?.limit ? { limit: options.limit } : {}) },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Like {@link BrowserCollectionApi.delete} but the success payload includes **`meta.count`**\r\n * (number of deleted rows), matching {@link BrowserCollectionApi.updateMany}.\r\n */\r\n deleteMany = async (\r\n where: WhereInput<RowD<Row>>,\r\n options?: { limit?: number },\r\n ): Promise<\r\n PostgrestResult<{\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n meta: { count: number };\r\n }>\r\n > => {\r\n const r = await this.delete(where, options);\r\n if (r.error) return r;\r\n return {\r\n data: {\r\n records: r.data.records,\r\n meta: { count: r.data.deleted },\r\n },\r\n error: null,\r\n };\r\n };\r\n}\r\n\r\nexport type BrowserCollections<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n> = [keyof Database[\"public\"][\"Tables\"]] extends [never]\r\n ? Record<string, BrowserCollectionApi<Record<string, unknown>>>\r\n : {\r\n readonly [Name in RagableTableNames<Database>]: BrowserCollectionApi<\r\n TableRow<Database, Name>,\r\n TableInsertRow<Database, Name>,\r\n TableUpdatePatch<Database, Name>\r\n >;\r\n };\r\n\r\nexport type BrowserCollectionFactory<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n> = {\r\n <Name extends RagableTableNames<Database>>(\r\n name: Name,\r\n databaseInstanceId?: string,\r\n ): BrowserCollectionApi<\r\n TableRow<Database, Name>,\r\n TableInsertRow<Database, Name>,\r\n TableUpdatePatch<Database, Name>\r\n >;\r\n <Row extends Record<string, unknown>>(\r\n name: string,\r\n databaseInstanceId?: string,\r\n ): BrowserCollectionApi<Row>;\r\n};\r\n\r\nexport class RagableBrowserDatabaseClient<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n> {\r\n private readonly fetchImpl: typeof fetch;\r\n private _transport: Transport | null = null;\r\n readonly collections: BrowserCollections<Database>;\r\n readonly collection: BrowserCollectionFactory<Database>;\r\n\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly ragableAuth: RagableAuth | null = null,\r\n ) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n this.collections = new Proxy(\r\n {},\r\n {\r\n get: (_target, prop) => {\r\n if (typeof prop !== \"string\") return undefined;\r\n if (prop === \"then\") return undefined;\r\n return this.collection(prop);\r\n },\r\n },\r\n ) as BrowserCollections<Database>;\r\n this.collection = ((name: string, databaseInstanceId?: string) =>\r\n new BrowserCollectionApi(\r\n this,\r\n name,\r\n databaseInstanceId,\r\n )) as BrowserCollectionFactory<Database>;\r\n }\r\n\r\n /** @internal Called by RagableBrowser to share the Transport instance. */\r\n _setTransport(transport: Transport): void {\r\n this._transport = transport;\r\n }\r\n\r\n /**\r\n * PostgREST table access. Instance field so `client.database.from` is always an own,\r\n * enumerable function (avoids rare prototype/bundler issues).\r\n */\r\n from = <TableName extends RagableTableNames<Database>>(\r\n table: TableName,\r\n databaseInstanceId?: string,\r\n ): PostgrestTableApi<Database, TableName> => {\r\n const id =\r\n databaseInstanceId?.trim() || this.options.databaseInstanceId?.trim() || \"\";\r\n const ragableAuth = this.ragableAuth;\r\n const opts = this.options;\r\n const transport = this._transport;\r\n const fetchImpl = this.fetchImpl;\r\n\r\n const pgFetch: PostgRESTFetch = async (params: PostgRESTFetchParams) => {\r\n if (!params.databaseInstanceId?.trim()) {\r\n throw new RagableError(\r\n \"database.from() requires databaseInstanceId in client options or as the second argument\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n const gid = requireAuthGroupId(opts);\r\n const token = await resolveDatabaseAuthBearer(opts, ragableAuth);\r\n const apiBase = normalizeBrowserApiBase();\r\n const qs = params.searchParams.toString();\r\n const url = `${apiBase}/auth-groups/${gid}/data/rest/${params.table}${qs ? `?${qs}` : \"\"}`;\r\n\r\n const headers = new Headers(opts.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"X-Database-Instance-Id\", params.databaseInstanceId);\r\n if (params.body !== undefined) {\r\n headers.set(\"Content-Type\", \"application/json\");\r\n }\r\n if (params.headers) {\r\n for (const [k, v] of Object.entries(params.headers)) {\r\n headers.set(k, v);\r\n }\r\n }\r\n\r\n if (transport) {\r\n return transport.execute({\r\n url,\r\n method: params.method,\r\n headers,\r\n body: params.body !== undefined ? JSON.stringify(params.body) : undefined,\r\n signal: params.signal,\r\n idempotencyKey: params.idempotencyKey,\r\n });\r\n }\r\n\r\n return fetchImpl(url, {\r\n method: params.method,\r\n headers,\r\n body: params.body !== undefined ? JSON.stringify(params.body) : undefined,\r\n signal: params.signal,\r\n });\r\n };\r\n return new PostgrestTableApi<Database, TableName>(pgFetch, id, table);\r\n };\r\n\r\n private toUrl(path: string): string {\r\n return `${normalizeBrowserApiBase()}${path.startsWith(\"/\") ? path : `/${path}`}`;\r\n }\r\n\r\n defineCollection = (\r\n name: string,\r\n schema?: Record<string, unknown>,\r\n databaseInstanceId?: string,\r\n ): Promise<PostgrestResult<BrowserCollectionDefinition>> =>\r\n asPostgrestResponse(() =>\r\n this._requestCollection<BrowserCollectionDefinition>(\r\n \"POST\",\r\n \"/\",\r\n { name, ...(schema ? { schema } : {}) },\r\n databaseInstanceId,\r\n ),\r\n );\r\n\r\n listCollections = (\r\n databaseInstanceId?: string,\r\n ): Promise<PostgrestResult<BrowserCollectionDefinition[]>> =>\r\n asPostgrestResponse(() =>\r\n this._requestCollection<BrowserCollectionDefinition[]>(\r\n \"GET\",\r\n \"/\",\r\n undefined,\r\n databaseInstanceId,\r\n ),\r\n );\r\n\r\n async _requestCollection<T>(\r\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\r\n path: string,\r\n body?: unknown,\r\n databaseInstanceId?: string,\r\n ): Promise<T> {\r\n const gid = requireAuthGroupId(this.options);\r\n const token = await resolveDatabaseAuthBearer(this.options, this.ragableAuth);\r\n const id = databaseInstanceId?.trim() || this.options.databaseInstanceId?.trim();\r\n if (!id) {\r\n throw new RagableError(\r\n \"db.collections requires databaseInstanceId in client options. For dynamic collection() calls, you can also pass databaseInstanceId as the second argument.\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n const headers = this.baseHeaders();\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"X-Database-Instance-Id\", id);\r\n if (body !== undefined) headers.set(\"Content-Type\", \"application/json\");\r\n const response = await this.fetchImpl(\r\n this.toUrl(`/auth-groups/${gid}/data/collections${path}`),\r\n {\r\n method,\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n },\r\n );\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n }\r\n\r\n query = async <Row extends Record<string, unknown> = Record<string, unknown>>(\r\n params: BrowserSqlQueryParams,\r\n ): Promise<PostgrestResult<BrowserSqlQueryResult<Row>>> => {\r\n return asPostgrestResponse(async () => {\r\n const gid = requireAuthGroupId(this.options);\r\n const token = await resolveDatabaseAuthBearer(this.options, this.ragableAuth);\r\n const databaseInstanceId =\r\n params.databaseInstanceId?.trim() ||\r\n this.options.databaseInstanceId?.trim();\r\n if (!databaseInstanceId) {\r\n throw new RagableError(\r\n \"database.query requires databaseInstanceId in the request or on createBrowserClient({ databaseInstanceId })\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n const headers = this.baseHeaders();\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n // Force read-only only when the request actually goes out under the public\r\n // anon key: always in publicAnon mode, and in auto mode ONLY when no user\r\n // session is signed in. A signed-in user (auto → JWT) or an admin key may write.\r\n const dataMode = effectiveDataAuth(this.options);\r\n let readOnly: boolean;\r\n if (dataMode === \"publicAnon\") {\r\n readOnly = true;\r\n } else if (dataMode === \"auto\") {\r\n const userTok = await tryGetUserAccessToken(this.options, this.ragableAuth);\r\n readOnly = userTok ? params.readOnly !== false : true;\r\n } else {\r\n readOnly = params.readOnly !== false;\r\n }\r\n const response = await this.fetchImpl(\r\n this.toUrl(`/auth-groups/${gid}/data/query`),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({\r\n databaseInstanceId,\r\n sql: params.sql,\r\n ...(params.params !== undefined ? { params: params.params } : {}),\r\n readOnly,\r\n ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs } : {}),\r\n ...(params.rowLimit !== undefined ? { rowLimit: params.rowLimit } : {}),\r\n }),\r\n },\r\n );\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as BrowserSqlQueryResult<Row>;\r\n });\r\n };\r\n\r\n private baseHeaders(): Headers {\r\n return new Headers(this.options.headers);\r\n }\r\n\r\n /**\r\n * Postgres `LISTEN` / `NOTIFY` realtime via server-proxied SSE.\r\n * Channels must be lowercase identifiers: `[a-z_][a-z0-9_]*` (max 63 chars).\r\n */\r\n /**\r\n * Postgres `LISTEN` / `NOTIFY` realtime via server-proxied SSE.\r\n *\r\n * Returns a `BrowserRealtimeSubscription` with:\r\n * - `unsubscribe()` — permanently close the subscription (stops reconnects).\r\n * - `status` — current connection state: `\"connecting\"` | `\"connected\"` | `\"reconnecting\"` | `\"disconnected\"`.\r\n *\r\n * The subscription automatically reconnects with exponential backoff when the\r\n * stream drops. Server heartbeats (every 15 s) are monitored — if none arrive\r\n * within `heartbeatTimeoutMs` (default 45 s), the connection is treated as dead\r\n * and a reconnect is triggered. Auth errors (401/403/404) are non-retryable.\r\n *\r\n * Channel names must be lowercase identifiers: `[a-z_][a-z0-9_]*` (max 63 chars).\r\n */\r\n realtime = {\r\n subscribe: (\r\n params: BrowserRealtimeSubscribeParams,\r\n ): Promise<BrowserRealtimeSubscription> =>\r\n subscribeBrowserRealtime(\r\n this.options,\r\n this.ragableAuth,\r\n this.fetchImpl,\r\n params,\r\n ),\r\n };\r\n}\r\n\r\n/**\r\n * A single NOTIFY message received from a Postgres channel.\r\n *\r\n * - `channel` — the lowercase channel name that fired.\r\n * - `payload` — the text payload (may be null if NOTIFY was sent without one).\r\n * - `processId` — the PID of the Postgres backend that called NOTIFY.\r\n */\r\nexport interface BrowserRealtimeNotification {\r\n channel: string;\r\n payload: string | null;\r\n processId: number;\r\n}\r\n\r\n/**\r\n * Connection status of a realtime subscription.\r\n *\r\n * - `\"connecting\"` — establishing or re-establishing the SSE stream.\r\n * - `\"connected\"` — stream is open, heartbeats are arriving, NOTIFY events are flowing.\r\n * - `\"reconnecting\"` — the stream dropped and the SDK is waiting before the next retry.\r\n * - `\"disconnected\"` — permanently stopped (via `unsubscribe()`, `signal` abort, or max retries exceeded).\r\n */\r\nexport type BrowserRealtimeStatus =\r\n | \"connecting\"\r\n | \"connected\"\r\n | \"reconnecting\"\r\n | \"disconnected\";\r\n\r\nexport interface BrowserRealtimeSubscribeParams {\r\n databaseInstanceId?: string;\r\n /** Channel names (normalized to lowercase on the server). */\r\n channels: string[];\r\n /** When aborted, the subscription stops permanently (equivalent to calling `unsubscribe()`). */\r\n signal?: AbortSignal;\r\n\r\n // ── Callbacks ──\r\n\r\n /** Called each time a Postgres NOTIFY message arrives. */\r\n onNotify?: (msg: BrowserRealtimeNotification) => void;\r\n /** Called once per connection attempt when the server confirms LISTEN is active. */\r\n onReady?: (channels: string[]) => void;\r\n /** Called when the stream encounters a non-retryable error or the server sends an error event. */\r\n onError?: (message: string) => void;\r\n /** Called whenever the connection status changes (connecting → connected → reconnecting → …). */\r\n onStatusChange?: (status: BrowserRealtimeStatus) => void;\r\n /** Called when the stream drops and the SDK will attempt to reconnect. `attempt` is 1-indexed. */\r\n onDisconnect?: (info: { attempt: number; retryInMs: number }) => void;\r\n /** Called when a reconnect attempt succeeds (stream is open again). */\r\n onReconnect?: (info: { attempt: number }) => void;\r\n\r\n // ── Reconnect tuning (safe defaults; override for advanced use) ──\r\n\r\n /** Maximum number of reconnect attempts before giving up. Set `0` to disable reconnect. Default: **Infinity** (never stops). */\r\n maxReconnectAttempts?: number;\r\n /** Base delay for exponential backoff (ms). Default: **1000**. */\r\n reconnectBaseDelayMs?: number;\r\n /** Maximum delay between reconnect attempts (ms). Default: **30000**. */\r\n reconnectMaxDelayMs?: number;\r\n /** How long to wait without a heartbeat before considering the connection dead (ms). Default: **45000** (3× the server's 15 s heartbeat interval). */\r\n heartbeatTimeoutMs?: number;\r\n}\r\n\r\n/**\r\n * Handle returned by `database.realtime.subscribe()`.\r\n *\r\n * - Call `unsubscribe()` to permanently close the subscription (no more reconnects).\r\n * - Read `status` to check the current connection state at any time.\r\n */\r\nexport interface BrowserRealtimeSubscription {\r\n unsubscribe: () => void;\r\n readonly status: BrowserRealtimeStatus;\r\n}\r\n\r\nfunction followAbortSignal(\r\n parent: AbortSignal | undefined,\r\n child: AbortController,\r\n): void {\r\n if (!parent) return;\r\n if (parent.aborted) {\r\n child.abort();\r\n return;\r\n }\r\n parent.addEventListener(\"abort\", () => child.abort(), { once: true });\r\n}\r\n\r\nfunction backoffDelay(\r\n attempt: number,\r\n baseMs: number,\r\n maxMs: number,\r\n): number {\r\n const exp = Math.min(baseMs * 2 ** (attempt - 1), maxMs);\r\n const jitter = exp * (0.5 + Math.random() * 0.5);\r\n return Math.round(jitter);\r\n}\r\n\r\nasync function subscribeBrowserRealtime(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n fetchImpl: typeof fetch,\r\n params: BrowserRealtimeSubscribeParams,\r\n): Promise<BrowserRealtimeSubscription> {\r\n const gid = requireAuthGroupId(options);\r\n const databaseInstanceId =\r\n params.databaseInstanceId?.trim() || options.databaseInstanceId?.trim();\r\n if (!databaseInstanceId) {\r\n throw new RagableError(\r\n \"realtime.subscribe requires databaseInstanceId in params or on createBrowserClient({ databaseInstanceId })\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n if (!Array.isArray(params.channels) || params.channels.length === 0) {\r\n throw new RagableError(\r\n \"realtime.subscribe requires a non-empty channels array\",\r\n 400,\r\n { code: \"SDK_REALTIME_CHANNELS_REQUIRED\" },\r\n );\r\n }\r\n\r\n const maxAttempts = params.maxReconnectAttempts ?? Infinity;\r\n const baseDelay = params.reconnectBaseDelayMs ?? 1_000;\r\n const maxDelay = params.reconnectMaxDelayMs ?? 30_000;\r\n const heartbeatTimeout = params.heartbeatTimeoutMs ?? 45_000;\r\n\r\n const lifecycleAc = new AbortController();\r\n followAbortSignal(params.signal, lifecycleAc);\r\n\r\n let currentStatus: BrowserRealtimeStatus = \"connecting\";\r\n const setStatus = (s: BrowserRealtimeStatus) => {\r\n if (s === currentStatus) return;\r\n currentStatus = s;\r\n params.onStatusChange?.(s);\r\n };\r\n\r\n const subscription: BrowserRealtimeSubscription = {\r\n unsubscribe: () => lifecycleAc.abort(),\r\n get status() {\r\n return currentStatus;\r\n },\r\n };\r\n\r\n setStatus(\"connecting\");\r\n\r\n async function connectOnce(\r\n signal: AbortSignal,\r\n ): Promise<\"stream_ended\" | \"aborted\"> {\r\n const token = await resolveDatabaseAuthBearer(options, ragableAuth);\r\n const headers = new Headers(options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n\r\n const response = await fetchImpl(\r\n `${normalizeBrowserApiBase()}/auth-groups/${gid}/data/realtime/stream`,\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({\r\n databaseInstanceId,\r\n channels: params.channels,\r\n }),\r\n signal,\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n const streamBody = response.body;\r\n if (!streamBody) {\r\n throw new RagableError(\"Realtime stream has no body\", 502, {\r\n code: \"SDK_REALTIME_NO_BODY\",\r\n });\r\n }\r\n\r\n let heartbeatTimer: ReturnType<typeof setTimeout> | null = null;\r\n const resetHeartbeatTimer = () => {\r\n if (heartbeatTimer) clearTimeout(heartbeatTimer);\r\n heartbeatTimer = setTimeout(() => {\r\n streamReader?.cancel().catch(() => undefined);\r\n }, heartbeatTimeout);\r\n };\r\n\r\n let streamReader: ReadableStreamDefaultReader<Uint8Array> | null = null;\r\n\r\n try {\r\n streamReader = streamBody.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = \"\";\r\n resetHeartbeatTimer();\r\n\r\n const processEvent = (evt: { type: string; [k: string]: unknown }) => {\r\n if (evt.type === \"realtime:heartbeat\") {\r\n resetHeartbeatTimer();\r\n return;\r\n }\r\n resetHeartbeatTimer();\r\n if (evt.type === \"realtime:ready\") {\r\n const ch = evt.channels;\r\n setStatus(\"connected\");\r\n params.onReady?.(\r\n Array.isArray(ch) ? ch.map((c) => String(c)) : [],\r\n );\r\n } else if (evt.type === \"notify\") {\r\n params.onNotify?.({\r\n channel: String(evt.channel ?? \"\"),\r\n payload:\r\n evt.payload === undefined || evt.payload === null\r\n ? null\r\n : String(evt.payload),\r\n processId: Number(evt.processId ?? 0),\r\n });\r\n } else if (evt.type === \"realtime:error\") {\r\n params.onError?.(String(evt.message ?? \"Realtime error\"));\r\n }\r\n };\r\n\r\n while (true) {\r\n const { done, value } = await streamReader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n let boundary = buffer.indexOf(\"\\n\\n\");\r\n while (boundary !== -1) {\r\n const block = buffer.slice(0, boundary);\r\n buffer = buffer.slice(boundary + 2);\r\n for (const line of block.split(\"\\n\")) {\r\n const dataPrefix = \"data: \";\r\n if (!line.startsWith(dataPrefix)) continue;\r\n const json = line.slice(dataPrefix.length).trim();\r\n if (!json || json === \"[DONE]\") continue;\r\n try {\r\n processEvent(JSON.parse(json));\r\n } catch {\r\n /* malformed JSON — skip */\r\n }\r\n }\r\n boundary = buffer.indexOf(\"\\n\\n\");\r\n }\r\n }\r\n\r\n return \"stream_ended\";\r\n } finally {\r\n if (heartbeatTimer) clearTimeout(heartbeatTimer);\r\n streamReader?.releaseLock();\r\n }\r\n }\r\n\r\n void (async () => {\r\n let attempt = 0;\r\n while (!lifecycleAc.signal.aborted) {\r\n const iterAc = new AbortController();\r\n followAbortSignal(lifecycleAc.signal, iterAc);\r\n\r\n try {\r\n const result = await connectOnce(iterAc.signal);\r\n if (lifecycleAc.signal.aborted) break;\r\n if (result === \"stream_ended\") {\r\n attempt++;\r\n }\r\n } catch (e) {\r\n if (lifecycleAc.signal.aborted) break;\r\n if ((e as Error).name === \"AbortError\") break;\r\n\r\n const status = (e as RagableError).status;\r\n if (status === 400 || status === 401 || status === 403 || status === 404) {\r\n params.onError?.((e as Error).message);\r\n break;\r\n }\r\n attempt++;\r\n }\r\n\r\n if (lifecycleAc.signal.aborted) break;\r\n if (attempt > maxAttempts) {\r\n params.onError?.(`Realtime: gave up after ${maxAttempts} reconnect attempts`);\r\n break;\r\n }\r\n\r\n const delay = backoffDelay(attempt, baseDelay, maxDelay);\r\n setStatus(\"reconnecting\");\r\n params.onDisconnect?.({ attempt, retryInMs: delay });\r\n\r\n await new Promise<void>((r) => {\r\n const timer = setTimeout(r, delay);\r\n const onAbort = () => {\r\n clearTimeout(timer);\r\n r();\r\n };\r\n lifecycleAc.signal.addEventListener(\"abort\", onAbort, { once: true });\r\n });\r\n\r\n if (lifecycleAc.signal.aborted) break;\r\n setStatus(\"connecting\");\r\n params.onReconnect?.({ attempt });\r\n }\r\n\r\n setStatus(\"disconnected\");\r\n })();\r\n\r\n return subscription;\r\n}\r\n\r\n// ─── Storage client ──────────────────────────────────────────────────────────\r\n\r\nexport interface BrowserStorageItem {\r\n type: \"file\" | \"folder\";\r\n path: string;\r\n name: string;\r\n size?: string | null;\r\n contentType?: string | null;\r\n updated?: string | null;\r\n}\r\n\r\nexport interface BrowserStorageListResult {\r\n bucket: string;\r\n prefix: string;\r\n items: BrowserStorageItem[];\r\n nextPageToken: string | null;\r\n}\r\n\r\nexport interface BrowserStorageUploadResult {\r\n success: true;\r\n path: string;\r\n size: string | null;\r\n contentType: string | null;\r\n updated: string | null;\r\n}\r\n\r\nexport interface BrowserStorageDownloadResult {\r\n path: string;\r\n size: string | null;\r\n contentType: string | null;\r\n updated: string | null;\r\n encoding: string;\r\n contentsBase64: string;\r\n text: string | null;\r\n textIncluded: boolean;\r\n}\r\n\r\nexport interface BrowserStorageSignedUrlResult {\r\n url: string;\r\n method: string;\r\n expiresInSeconds: number;\r\n objectPath: string;\r\n}\r\n\r\nexport interface BrowserStorageBulkDeleteResult {\r\n success: boolean;\r\n totalRequested: number;\r\n uniquePaths: number;\r\n deleted: string[];\r\n errors: Array<{ path: string; error: string }>;\r\n}\r\n\r\nexport class BrowserStorageBucketClient {\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly fetchImpl: typeof fetch,\r\n private readonly bucketId: string,\r\n private readonly ragableAuth: RagableAuth | null = null,\r\n ) {}\r\n\r\n private get authGroupId(): string {\r\n const id = this.options.authGroupId?.trim();\r\n if (!id) throw new RagableError(\"authGroupId is required for storage\", 400, { code: \"SDK_MISSING_AUTH_GROUP_ID\" });\r\n return id;\r\n }\r\n\r\n private base(): string {\r\n return `${normalizeBrowserApiBase()}/auth-groups/${this.authGroupId}/storage/buckets/${encodeURIComponent(this.bucketId)}`;\r\n }\r\n\r\n /**\r\n * Same credential resolution as the database client (see resolveDatabaseAuthBearer):\r\n * in the generated-site default (`auto`), a signed-in user's auto-refreshed JWT\r\n * is used so storage calls carry the user's identity; logged-out visitors fall\r\n * back to the anon key. Previously storage ignored the managed session entirely.\r\n */\r\n private async bearerToken(): Promise<string> {\r\n return resolveDatabaseAuthBearer(this.options, this.ragableAuth);\r\n }\r\n\r\n /**\r\n * The storage backend has historically returned HTTP 200 with an `{ error }`\r\n * body on some failures; without this guard the SDK would resolve those as\r\n * successful uploads/deletes. Treat any 2xx whose body carries a non-empty\r\n * `error` as a failure.\r\n */\r\n private assertNoEmbeddedError(payload: unknown, status: number): void {\r\n if (payload && typeof payload === \"object\" && !Array.isArray(payload)) {\r\n const err = (payload as Record<string, unknown>).error;\r\n if (typeof err === \"string\" && err.trim()) {\r\n throw new RagableError(err, status, payload);\r\n }\r\n }\r\n }\r\n\r\n private async req<T>(method: string, path: string, body?: unknown): Promise<T> {\r\n const token = await this.bearerToken();\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n if (body !== undefined && !(body instanceof FormData)) headers.set(\"Content-Type\", \"application/json\");\r\n const res = await this.fetchImpl(`${this.base()}${path}`, {\r\n method,\r\n headers,\r\n body: body instanceof FormData ? body : body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n const payload = await res.json().catch(() => ({}));\r\n if (!res.ok) throw new RagableError(extractErrorMessage(payload, res.statusText), res.status, payload);\r\n this.assertNoEmbeddedError(payload, res.status);\r\n return payload as T;\r\n }\r\n\r\n list(params: { prefix?: string; delimiter?: string; maxResults?: number; pageToken?: string } = {}): Promise<BrowserStorageListResult> {\r\n const qs = new URLSearchParams();\r\n if (params.prefix) qs.set(\"prefix\", params.prefix);\r\n if (params.delimiter) qs.set(\"delimiter\", params.delimiter);\r\n if (params.maxResults != null) qs.set(\"maxResults\", String(params.maxResults));\r\n if (params.pageToken) qs.set(\"pageToken\", params.pageToken);\r\n const q = qs.toString();\r\n return this.req(\"GET\", `/contents${q ? `?${q}` : \"\"}`);\r\n }\r\n\r\n async upload(params: { objectPath: string; file: Blob | ArrayBuffer | Uint8Array; fileName?: string; contentType?: string; cacheControl?: string }): Promise<BrowserStorageUploadResult> {\r\n const token = await this.bearerToken();\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n const form = new FormData();\r\n const raw = params.file instanceof Blob ? params.file : new Blob([new Uint8Array(params.file instanceof ArrayBuffer ? params.file : (params.file as Uint8Array).buffer as ArrayBuffer)], params.contentType ? { type: params.contentType } : {});\r\n const blob = raw;\r\n form.set(\"file\", blob, params.fileName ?? \"upload\");\r\n form.set(\"objectPath\", params.objectPath);\r\n if (params.cacheControl) form.set(\"cacheControl\", params.cacheControl);\r\n const res = await this.fetchImpl(`${this.base()}/upload`, { method: \"POST\", headers, body: form });\r\n const payload = await res.json().catch(() => ({}));\r\n if (!res.ok) throw new RagableError(extractErrorMessage(payload, res.statusText), res.status, payload);\r\n this.assertNoEmbeddedError(payload, res.status);\r\n return payload as BrowserStorageUploadResult;\r\n }\r\n\r\n download(params: { objectPath: string; asText?: boolean; maxTextBytes?: number }): Promise<BrowserStorageDownloadResult> {\r\n const qs = new URLSearchParams({ objectPath: params.objectPath });\r\n if (params.asText != null) qs.set(\"asText\", String(params.asText));\r\n if (params.maxTextBytes != null) qs.set(\"maxTextBytes\", String(params.maxTextBytes));\r\n return this.req(\"GET\", `/objects/download?${qs}`);\r\n }\r\n\r\n delete(objectPath: string): Promise<{ success: true; path: string }> {\r\n return this.req(\"DELETE\", \"/objects\", { objectPath });\r\n }\r\n\r\n bulkDelete(objectPaths: string[]): Promise<BrowserStorageBulkDeleteResult> {\r\n return this.req(\"POST\", \"/objects/delete-bulk\", { objectPaths });\r\n }\r\n\r\n getSignedUploadUrl(params: { objectPath: string; contentType?: string; expiresInSeconds?: number }): Promise<BrowserStorageSignedUrlResult> {\r\n return this.req(\"POST\", \"/signed-upload-url\", params);\r\n }\r\n\r\n getSignedDownloadUrl(params: { objectPath: string; expiresInSeconds?: number }): Promise<BrowserStorageSignedUrlResult> {\r\n const qs = new URLSearchParams({ objectPath: params.objectPath });\r\n if (params.expiresInSeconds != null) qs.set(\"expiresInSeconds\", String(params.expiresInSeconds));\r\n return this.req(\"GET\", `/signed-download-url?${qs}`);\r\n }\r\n\r\n copy(params: { sourcePath: string; destinationPath: string }): Promise<{ success: true; sourcePath: string; destinationPath: string }> {\r\n return this.req(\"POST\", \"/objects/copy\", params);\r\n }\r\n\r\n move(params: { sourcePath: string; destinationPath: string }): Promise<{ success: true; sourcePath: string; destinationPath: string }> {\r\n return this.req(\"POST\", \"/objects/move\", params);\r\n }\r\n\r\n createFolder(folderPath: string): Promise<{ success: true; folderPath: string }> {\r\n return this.req(\"POST\", \"/folders\", { folderPath });\r\n }\r\n\r\n deleteFolder(folderPath: string): Promise<{ success: true; folderPath: string }> {\r\n return this.req(\"DELETE\", \"/folders\", { folderPath });\r\n }\r\n\r\n getMetadata(objectPath: string): Promise<{ name: string; contentType: string | null; size: string | null; updated: string | null; metadata?: Record<string, string> }> {\r\n const qs = new URLSearchParams({ objectPath });\r\n return this.req(\"GET\", `/objects/metadata?${qs}`);\r\n }\r\n}\r\n\r\nexport class RagableBrowserStorageClient {\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly fetchImpl: typeof fetch,\r\n private readonly ragableAuth: RagableAuth | null = null,\r\n ) {}\r\n\r\n from(bucketId: string): BrowserStorageBucketClient {\r\n return new BrowserStorageBucketClient(\r\n this.options,\r\n this.fetchImpl,\r\n bucketId,\r\n this.ragableAuth,\r\n );\r\n }\r\n}\r\n\r\n// ─── Mail client ─────────────────────────────────────────────────────────────\r\n\r\nexport interface MailSendParams {\r\n to: string[];\r\n cc?: string[];\r\n bcc?: string[];\r\n subject: string;\r\n /** Plain-text body. At least one of `bodyText` / `bodyHtml` is required. */\r\n bodyText?: string;\r\n /** HTML body. If both are set, sent as multipart/alternative. */\r\n bodyHtml?: string;\r\n /** RFC 822 Message-ID of the message you're replying to (enables threading). */\r\n inReplyToMessageId?: string;\r\n /** Existing References header value, chained with In-Reply-To. */\r\n referencesHeader?: string;\r\n}\r\n\r\nexport interface MailSendResult {\r\n sentMailMessageId: string;\r\n gmailMessageId: string;\r\n gmailThreadId: string;\r\n fromAddress: string;\r\n}\r\n\r\nexport interface MailSearchParams {\r\n /** Gmail search syntax, e.g. `from:alice is:unread newer_than:7d`. */\r\n query?: string;\r\n /** 1–50; default 20. */\r\n maxResults?: number;\r\n pageToken?: string;\r\n labelIds?: string[];\r\n}\r\n\r\nexport interface MailMessagePreview {\r\n id: string;\r\n threadId: string;\r\n snippet: string;\r\n labelIds: string[];\r\n}\r\n\r\nexport interface MailMessageDetail {\r\n id: string;\r\n threadId: string;\r\n receivedAt: number;\r\n fromAddress: string;\r\n fromName: string | null;\r\n to: string[];\r\n cc: string[];\r\n subject: string;\r\n snippet: string;\r\n bodyText: string | null;\r\n bodyHtml: string | null;\r\n messageIdHeader: string | null;\r\n referencesHeader: string | null;\r\n labelIds: string[];\r\n}\r\n\r\n/**\r\n * Send and read email through the Gmail account linked to this Ragable\r\n * website (via the IDE Infrastructure → Integrations tab).\r\n *\r\n * All requests require a Bearer token — either an end-user JWT from this\r\n * website's auth group (call `client.auth.signIn(...)` first) or the\r\n * data-admin key (server-side use).\r\n *\r\n * The website MUST have:\r\n * 1. A Gmail account linked under Integrations\r\n * 2. An auth group linked under Auth\r\n *\r\n * Otherwise calls return a 412 with a clear error message.\r\n */\r\nexport class RagableBrowserMailClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly auth: RagableAuth | null,\r\n ) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const websiteId = this.options.websiteId?.trim();\r\n if (!websiteId) {\r\n throw new RagableError(\r\n \"websiteId is required for mail operations. Use createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return websiteId;\r\n }\r\n\r\n private pathTo(p: string): string {\r\n const websiteId = this.requireWebsiteId();\r\n const orgId = this.options.organizationId;\r\n return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/mail${\r\n p.startsWith(\"/\") ? p : `/${p}`\r\n }`;\r\n }\r\n\r\n /**\r\n * Get the Bearer token used to authenticate the call:\r\n * 1. End-user access token (preferred when an auth group is configured\r\n * and the user has signed in)\r\n * 2. `dataStaticKey` from createBrowserClient options\r\n * 3. Caller-supplied `getAccessToken()`\r\n *\r\n * If none is available, throws — server-side use should pass the\r\n * data-admin key as `dataStaticKey`.\r\n */\r\n private async getBearerToken(): Promise<string> {\r\n if (this.auth) {\r\n const token = await this.auth.getValidAccessToken().catch(() => null);\r\n if (token) return token;\r\n }\r\n const callerProvided = await this.options.getAccessToken?.();\r\n if (typeof callerProvided === \"string\" && callerProvided.length > 0) {\r\n return callerProvided;\r\n }\r\n if (this.options.dataStaticKey?.trim()) {\r\n return this.options.dataStaticKey.trim();\r\n }\r\n throw new RagableError(\r\n \"Mail requests need authentication: either sign in via client.auth.signIn(...) or pass dataStaticKey (the auth group data-admin key) when creating the client.\",\r\n 401,\r\n { code: \"SDK_MAIL_NOT_AUTHENTICATED\" },\r\n );\r\n }\r\n\r\n private async request<T>(\r\n path: string,\r\n init: RequestInit & { headers?: HeadersInit } = {},\r\n ): Promise<T> {\r\n const token = await this.getBearerToken();\r\n const headers = new Headers(init.headers ?? this.options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n if (init.body && !headers.has(\"Content-Type\")) {\r\n headers.set(\"Content-Type\", \"application/json\");\r\n }\r\n const response = await this.fetchImpl(this.pathTo(path), {\r\n ...init,\r\n headers,\r\n });\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n }\r\n\r\n /** Send an email from this website's linked Gmail account. */\r\n async send(params: MailSendParams): Promise<MailSendResult> {\r\n if (!params.to?.length) {\r\n throw new RagableError(\r\n \"`to` must contain at least one recipient.\",\r\n 400,\r\n { code: \"SDK_MAIL_NO_RECIPIENTS\" },\r\n );\r\n }\r\n if (!params.bodyText && !params.bodyHtml) {\r\n throw new RagableError(\r\n \"Provide at least one of `bodyText` or `bodyHtml`.\",\r\n 400,\r\n { code: \"SDK_MAIL_NO_BODY\" },\r\n );\r\n }\r\n return this.request<MailSendResult>(\"/send\", {\r\n method: \"POST\",\r\n body: JSON.stringify(params),\r\n });\r\n }\r\n\r\n /** Search messages with Gmail query syntax. */\r\n async search(\r\n params: MailSearchParams = {},\r\n ): Promise<{ messages: MailMessagePreview[]; nextPageToken: string | null }> {\r\n const qs = new URLSearchParams();\r\n if (params.query) qs.set(\"q\", params.query);\r\n if (params.maxResults) qs.set(\"maxResults\", String(params.maxResults));\r\n if (params.pageToken) qs.set(\"pageToken\", params.pageToken);\r\n if (params.labelIds?.length) qs.set(\"labelIds\", params.labelIds.join(\",\"));\r\n const suffix = qs.toString() ? `?${qs.toString()}` : \"\";\r\n return this.request<{\r\n messages: MailMessagePreview[];\r\n nextPageToken: string | null;\r\n }>(`/search${suffix}`, { method: \"GET\" });\r\n }\r\n\r\n /** Fetch a single message in full (headers + decoded text/html body). */\r\n async getMessage(messageId: string): Promise<MailMessageDetail> {\r\n if (!messageId) {\r\n throw new RagableError(\"`messageId` is required.\", 400, {\r\n code: \"SDK_MAIL_NO_MESSAGE_ID\",\r\n });\r\n }\r\n const { message } = await this.request<{ message: MailMessageDetail }>(\r\n `/messages/${encodeURIComponent(messageId)}`,\r\n { method: \"GET\" },\r\n );\r\n return message;\r\n }\r\n}\r\n\r\n// ─── Functions client (backend edge functions) ──────────────────────────────\r\n\r\n/**\r\n * Invokes the project's backend edge functions (handlers in `/functions/<name>.ts`).\r\n *\r\n * Exposed on the client as a typed Proxy — `client.functions.<name>(input)` — so\r\n * each generated function name is a direct callable. Functions run server-side,\r\n * so calls can use secrets and reach any external API without browser CORS limits.\r\n */\r\nexport class RagableBrowserFunctionsClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly auth: RagableAuth | null,\r\n ) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const websiteId = this.options.websiteId?.trim();\r\n if (!websiteId) {\r\n throw new RagableError(\r\n \"websiteId is required for functions. Use createWebsiteRagableClient()/createAppClient() or pass createBrowserClient({ websiteId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return websiteId;\r\n }\r\n\r\n private toUrl(name: string): string {\r\n const orgId = this.options.organizationId;\r\n const websiteId = this.requireWebsiteId();\r\n return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/functions/${encodeURIComponent(\r\n name,\r\n )}/invoke`;\r\n }\r\n\r\n /**\r\n * Best-effort end-user bearer, forwarded to the function as `context.auth.token`.\r\n * Functions are public, so this never throws — anonymous calls send no token.\r\n */\r\n private async getOptionalToken(): Promise<string | null> {\r\n if (this.auth) {\r\n const token = await this.auth.getValidAccessToken().catch(() => null);\r\n if (token) return token;\r\n }\r\n const caller = await Promise.resolve(this.options.getAccessToken?.()).catch(\r\n () => null,\r\n );\r\n if (typeof caller === \"string\" && caller.trim()) return caller.trim();\r\n const staticKey = this.options.dataStaticKey?.trim();\r\n if (staticKey) return staticKey;\r\n return null;\r\n }\r\n\r\n /**\r\n * Invoke a function by name. Prefer the typed `client.functions.<name>(input)`\r\n * accessors; use this when the name is dynamic.\r\n */\r\n async invoke<Result = unknown>(\r\n name: string,\r\n input?: unknown,\r\n options?: RagableFunctionInvokeOptions,\r\n ): Promise<Result> {\r\n const fnName = String(name ?? \"\").trim();\r\n if (!fnName) {\r\n throw new RagableError(\r\n \"functions.invoke requires a function name\",\r\n 400,\r\n { code: \"SDK_MISSING_FUNCTION_NAME\" },\r\n );\r\n }\r\n const headers = new Headers(options?.headers ?? this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n const token = await this.getOptionalToken();\r\n if (token) headers.set(\"Authorization\", `Bearer ${token}`);\r\n\r\n const response = await this.fetchImpl(this.toUrl(fnName), {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({ input: input ?? null }),\r\n ...(options?.signal ? { signal: options.signal } : {}),\r\n });\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n // The route wraps handler output as `{ result }`. Fall back to the raw body\r\n // for forward-compat if that envelope ever changes.\r\n if (\r\n payload &&\r\n typeof payload === \"object\" &&\r\n !Array.isArray(payload) &&\r\n \"result\" in (payload as Record<string, unknown>)\r\n ) {\r\n return (payload as { result: Result }).result;\r\n }\r\n return payload as Result;\r\n }\r\n\r\n /** Build the typed Proxy exposed as `client.functions`. */\r\n asInvoker<F extends RagableFunctions = DefaultRagableFunctions>(): FunctionInvoker<F> {\r\n const invoke = this.invoke.bind(this);\r\n return new Proxy(\r\n {},\r\n {\r\n get: (_target, prop) => {\r\n if (typeof prop !== \"string\") return undefined;\r\n // Don't masquerade as a thenable when awaited/inspected.\r\n if (prop === \"then\") return undefined;\r\n if (prop === \"invoke\") {\r\n return (\r\n name: string,\r\n input?: unknown,\r\n options?: RagableFunctionInvokeOptions,\r\n ) => invoke(name, input, options);\r\n }\r\n return (input?: unknown, options?: RagableFunctionInvokeOptions) =>\r\n invoke(prop, input, options);\r\n },\r\n },\r\n ) as FunctionInvoker<F>;\r\n }\r\n}\r\n\r\n// ─── Agents client ───────────────────────────────────────────────────────────\r\n\r\nexport interface AgentConversationMessage {\r\n role: \"user\" | \"assistant\";\r\n content: string;\r\n file_urls?: string[];\r\n}\r\n\r\nexport interface AgentConversation {\r\n id: string;\r\n agent_name: string;\r\n agentName: string;\r\n title: string | null;\r\n metadata: unknown;\r\n messages: AgentConversationMessage[];\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\nexport interface AgentConversationSubscription {\r\n unsubscribe: () => void;\r\n}\r\n\r\nexport class RagableBrowserAgentsClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(private readonly options: RagableBrowserClientOptions) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private toUrl(path: string): string {\r\n return `${normalizeBrowserApiBase()}${path.startsWith(\"/\") ? path : `/${path}`}`;\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const websiteId = this.options.websiteId?.trim();\r\n if (!websiteId) {\r\n throw new RagableError(\r\n \"websiteId is required for project agent conversation APIs. Use the generated createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return websiteId;\r\n }\r\n\r\n private websiteAgentPath(path: string): string {\r\n const websiteId = this.requireWebsiteId();\r\n return `/public/organizations/${this.options.organizationId}/websites/${websiteId}${path}`;\r\n }\r\n\r\n private async requestJson<T>(path: string, init: RequestInit = {}): Promise<T> {\r\n const response = await this.fetchImpl(this.toUrl(path), init);\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n }\r\n\r\n /** @deprecated Prefer `chatStreamByName(agentName, params)` for project-local `/agents/*.json` agents. */\r\n async *chatStream(\r\n agentId: string,\r\n params: AgentPublicChatParams,\r\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\r\n const orgId = this.options.organizationId;\r\n const body: Record<string, unknown> = {\r\n message: params.message,\r\n ...(params.history !== undefined ? { history: params.history } : {}),\r\n ...(params.triggerSubtype !== undefined\r\n ? { triggerSubtype: params.triggerSubtype }\r\n : {}),\r\n ...(params.triggerNodeId !== undefined\r\n ? { triggerNodeId: params.triggerNodeId }\r\n : {}),\r\n };\r\n\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n\r\n const response = await this.fetchImpl(\r\n this.toUrl(`/public/organizations/${orgId}/agents/${agentId}/chat/stream`),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(body),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n const streamBody = response.body;\r\n if (!streamBody) {\r\n return;\r\n }\r\n\r\n yield* readSseStream(streamBody);\r\n }\r\n\r\n /**\r\n * Stream a project agent defined in `agents/*.json` using the same result\r\n * shape as `client.ai.streamText`. Preferred over {@link chatStreamByName}\r\n * and {@link runChatStreamByName} — those remain for back-compat only.\r\n *\r\n * ```ts\r\n * const { textStream, text } = client.agents.run(\"support\", {\r\n * messages: [{ role: \"user\", content: \"I can't log in\" }],\r\n * });\r\n * for await (const delta of textStream) process.stdout.write(delta);\r\n * console.log(await text);\r\n * ```\r\n */\r\n run(\r\n agentName: string,\r\n params: { messages: Message[]; signal?: AbortSignal },\r\n ): StreamTextResult {\r\n const source = this.runStreamParts(agentName, params);\r\n return createStreamResultFromParts(source);\r\n }\r\n\r\n /**\r\n * Same agent, same tools/instructions/RAG — but constrain the final output\r\n * to a JSON Schema. Matches `client.ai.streamObject` exactly so callers can\r\n * swap between raw inference and an agent without changing call shape.\r\n *\r\n * Tool calling and structured output are **compatible**: the model may call\r\n * the agent's tools as usual; the final assistant message is the schema-\r\n * conformant JSON. The agent's `agents/<name>.json` is unchanged — whether\r\n * the run is conversational or structured is decided by the call site.\r\n *\r\n * ```ts\r\n * const { partialObjectStream, object } = client.agents.runObject<Plan>(\r\n * \"planner\",\r\n * {\r\n * messages: [{ role: \"user\", content: \"Plan a 3-day trip to Kyoto.\" }],\r\n * schema: {\r\n * type: \"object\",\r\n * properties: {\r\n * days: {\r\n * type: \"array\",\r\n * items: { type: \"object\", properties: { date: { type: \"string\" }, activities: { type: \"array\", items: { type: \"string\" } } } },\r\n * },\r\n * },\r\n * required: [\"days\"],\r\n * },\r\n * },\r\n * );\r\n * for await (const p of partialObjectStream) renderPreview(p);\r\n * console.log(await object);\r\n * ```\r\n */\r\n runObject<T = unknown>(\r\n agentName: string,\r\n params: {\r\n messages: Message[];\r\n schema: JsonSchema;\r\n schemaName?: string;\r\n schemaDescription?: string;\r\n signal?: AbortSignal;\r\n },\r\n ): StreamObjectResult<T> {\r\n const responseFormat = buildResponseFormat({\r\n schema: params.schema,\r\n ...(params.schemaName !== undefined ? { name: params.schemaName } : {}),\r\n ...(params.schemaDescription !== undefined\r\n ? { description: params.schemaDescription }\r\n : {}),\r\n });\r\n const sourceParts = this.runStreamParts(agentName, {\r\n messages: params.messages,\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n responseFormat,\r\n });\r\n const inner = createStreamResultFromParts(sourceParts);\r\n return wrapStreamTextAsObject<T>(inner);\r\n }\r\n\r\n /** Non-streaming variant of {@link runObject}. */\r\n async generateObject<T = unknown>(\r\n agentName: string,\r\n params: {\r\n messages: Message[];\r\n schema: JsonSchema;\r\n schemaName?: string;\r\n schemaDescription?: string;\r\n signal?: AbortSignal;\r\n },\r\n ): Promise<GenerateObjectResult<T>> {\r\n const result = this.runObject<T>(agentName, params);\r\n for await (const _ of result.partialObjectStream) void _;\r\n const [object, usage, finishReason, toolCalls] = await Promise.all([\r\n result.object,\r\n result.usage,\r\n result.finishReason,\r\n result.toolCalls,\r\n ]);\r\n return { object, usage, finishReason, toolCalls };\r\n }\r\n\r\n private async *runStreamParts(\r\n agentName: string,\r\n params: {\r\n messages: Message[];\r\n signal?: AbortSignal;\r\n /** Optional per-call response_format (Fireworks json_schema shape). */\r\n responseFormat?: Record<string, unknown>;\r\n },\r\n ): AsyncGenerator<StreamPart, void, undefined> {\r\n const { messages } = params;\r\n if (!Array.isArray(messages) || messages.length === 0) {\r\n throw new RagableError(\r\n \"agents.run requires at least one message\",\r\n 400,\r\n { code: \"SDK_AGENTS_RUN_EMPTY_MESSAGES\" },\r\n );\r\n }\r\n const last = messages[messages.length - 1];\r\n if (!last || last.role !== \"user\") {\r\n throw new RagableError(\r\n 'agents.run: the final message must have role \"user\"',\r\n 400,\r\n { code: \"SDK_AGENTS_RUN_INVALID_LAST_MESSAGE\" },\r\n );\r\n }\r\n const history = messages\r\n .slice(0, -1)\r\n .filter((m) => m.role === \"user\" || m.role === \"assistant\")\r\n .map((m) => ({\r\n role: m.role as \"user\" | \"assistant\",\r\n content: m.content,\r\n }));\r\n\r\n // Inlined SSE fetch (bypasses chatStreamByName) so we can carry\r\n // response_format on the wire without changing the deprecated method.\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n const body: Record<string, unknown> = {\r\n message: last.content,\r\n ...(history.length > 0 ? { history } : {}),\r\n ...(params.responseFormat\r\n ? { response_format: params.responseFormat }\r\n : {}),\r\n };\r\n const response = await this.fetchImpl(\r\n this.toUrl(\r\n this.websiteAgentPath(\r\n `/agents/${encodeURIComponent(agentName)}/chat/stream`,\r\n ),\r\n ),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(body),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n },\r\n );\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n if (!response.body) return;\r\n for await (const event of readSseStream(response.body)) {\r\n const mapped = mapAgentEvent(event);\r\n if (mapped) yield mapped;\r\n }\r\n }\r\n\r\n /**\r\n * @deprecated Use {@link run} for new code. This method is kept for\r\n * back-compat with the original chat-stream DX.\r\n */\r\n async *chatStreamByName(\r\n agentName: string,\r\n params: AgentChatParams,\r\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n const response = await this.fetchImpl(\r\n this.toUrl(\r\n this.websiteAgentPath(\r\n `/agents/${encodeURIComponent(agentName)}/chat/stream`,\r\n ),\r\n ),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({\r\n message: params.message,\r\n ...(params.history !== undefined ? { history: params.history } : {}),\r\n }),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n if (!response.body) return;\r\n yield* readSseStream(response.body);\r\n }\r\n\r\n /**\r\n * @deprecated Use {@link run} for new code. Returns the legacy callback-based\r\n * result type leaking server internals; the new Vercel-style API exposes\r\n * `textStream` / `fullStream` / promises for `text`, `usage`, `finishReason`.\r\n */\r\n async runChatStreamByName(\r\n agentName: string,\r\n params: AgentChatParams,\r\n handlers: AgentChatStreamHandlers = {},\r\n ): Promise<AgentChatStreamResult> {\r\n return runAgentChatStream(this.chatStreamByName(agentName, params), handlers, {\r\n signal: params.signal,\r\n });\r\n }\r\n\r\n /**\r\n * Same as {@link runChatStreamByName} but folds events into `AgentChat`-style segments\r\n * (`onSegments` / `onStreamingText`) and returns a history-ready assistant message.\r\n */\r\n async runChatUiByName(\r\n agentName: string,\r\n params: AgentChatParams,\r\n handlers: AgentChatStreamUiHandlers = {},\r\n ): Promise<AgentChatUiStreamResult> {\r\n return runAgentChatStreamForUi(\r\n this.chatStreamByName(agentName, params),\r\n handlers,\r\n { signal: params.signal },\r\n );\r\n }\r\n\r\n createConversation(params: {\r\n agent_name?: string;\r\n agentName?: string;\r\n title?: string | null;\r\n metadata?: unknown;\r\n }): Promise<AgentConversation> {\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\"/agent-conversations\"),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(params),\r\n },\r\n );\r\n }\r\n\r\n listConversations(params: {\r\n agent_name?: string;\r\n agentName?: string;\r\n } = {}): Promise<AgentConversation[]> {\r\n const agentName = params.agent_name ?? params.agentName;\r\n const qs = agentName\r\n ? `?agentName=${encodeURIComponent(agentName)}`\r\n : \"\";\r\n return this.requestJson<AgentConversation[]>(\r\n this.websiteAgentPath(`/agent-conversations${qs}`),\r\n );\r\n }\r\n\r\n getConversation(conversationId: string): Promise<AgentConversation> {\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\r\n `/agent-conversations/${encodeURIComponent(conversationId)}`,\r\n ),\r\n );\r\n }\r\n\r\n updateConversation(\r\n conversationId: string,\r\n data: { title?: string | null; metadata?: unknown },\r\n ): Promise<AgentConversation> {\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\r\n `/agent-conversations/${encodeURIComponent(conversationId)}`,\r\n ),\r\n {\r\n method: \"PATCH\",\r\n headers,\r\n body: JSON.stringify(data),\r\n },\r\n );\r\n }\r\n\r\n addMessage(\r\n conversationOrId: AgentConversation | string,\r\n message: AgentConversationMessage,\r\n ): Promise<AgentConversation> {\r\n const conversationId =\r\n typeof conversationOrId === \"string\" ? conversationOrId : conversationOrId.id;\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\r\n `/agent-conversations/${encodeURIComponent(conversationId)}/messages`,\r\n ),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(message),\r\n },\r\n );\r\n }\r\n\r\n subscribeToConversation(\r\n conversationId: string,\r\n callback: (conversation: AgentConversation) => void,\r\n options: { intervalMs?: number } = {},\r\n ): AgentConversationSubscription {\r\n let stopped = false;\r\n let timer: ReturnType<typeof setTimeout> | null = null;\r\n const intervalMs = Math.max(500, options.intervalMs ?? 1500);\r\n const tick = async () => {\r\n if (stopped) return;\r\n try {\r\n callback(await this.getConversation(conversationId));\r\n } finally {\r\n if (!stopped) timer = setTimeout(tick, intervalMs);\r\n }\r\n };\r\n void tick();\r\n return {\r\n unsubscribe: () => {\r\n stopped = true;\r\n if (timer) clearTimeout(timer);\r\n },\r\n };\r\n }\r\n}\r\n\r\nexport interface AgentPublicChatParams extends AgentChatParams {\r\n triggerSubtype?: string;\r\n triggerNodeId?: string;\r\n}\r\n\r\n// ─── Main browser client ─────────────────────────────────────────────────────\r\n\r\nexport class RagableBrowser<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n AuthUser extends object = DefaultAuthUser,\r\n Functions extends RagableFunctions = DefaultRagableFunctions,\r\n> {\r\n readonly agents: RagableBrowserAgentsClient;\r\n readonly ai: RagableBrowserAiClient;\r\n readonly auth: RagableBrowserAuthClient<AuthUser>;\r\n readonly database: RagableBrowserDatabaseClient<Database>;\r\n readonly db: RagableBrowserDatabaseClient<Database>;\r\n readonly storage: RagableBrowserStorageClient;\r\n readonly mail: RagableBrowserMailClient;\r\n /**\r\n * Backend edge functions — call a `/functions/<name>.ts` handler with\r\n * `client.functions.<name>(input)`. Runs server-side. See {@link FunctionInvoker}.\r\n */\r\n readonly functions: FunctionInvoker<Functions>;\r\n readonly transport: Transport;\r\n private readonly _ragableAuth: RagableAuth<AuthUser> | null;\r\n\r\n constructor(options: RagableBrowserClientOptions) {\r\n this.transport = new Transport({\r\n fetch: options.fetch,\r\n headers: options.headers,\r\n ...options.transport,\r\n });\r\n\r\n if (options.authGroupId) {\r\n this._ragableAuth = new RagableAuth<AuthUser>({\r\n authGroupId: options.authGroupId,\r\n fetch: options.fetch,\r\n headers: options.headers,\r\n auth: options.auth,\r\n });\r\n\r\n // On a 401, force a single-flight refresh and retry — covers token\r\n // rotation, clock skew, and early revocation that the proactive\r\n // skew-based refresh would miss. Returns null (no retry) when there is no\r\n // user session, e.g. anonymous `publicAnon` traffic.\r\n this.transport.setRefreshHandler(async () => {\r\n const mode = effectiveDataAuth(options);\r\n if (mode !== \"user\" && mode !== \"auto\") return null;\r\n return this._ragableAuth!.getValidAccessToken(true).catch(() => null);\r\n });\r\n\r\n // Eagerly restore the persisted session so the first render and any\r\n // `onAuthStateChange` subscriber see it. Idempotent + memoized in\r\n // RagableAuth; safe to call whenever an auth group is configured.\r\n this._ragableAuth.initialize().catch(() => {});\r\n } else {\r\n this._ragableAuth = null;\r\n }\r\n\r\n this.agents = new RagableBrowserAgentsClient(options);\r\n this.ai = new RagableBrowserAiClient({\r\n organizationId: options.organizationId,\r\n ...(options.websiteId !== undefined ? { websiteId: options.websiteId } : {}),\r\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\r\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\r\n apiBase: normalizeBrowserApiBase(),\r\n });\r\n this.auth = new RagableBrowserAuthClient<AuthUser>(options, this._ragableAuth);\r\n this.database = new RagableBrowserDatabaseClient<Database>(\r\n options,\r\n this._ragableAuth as RagableAuth | null,\r\n );\r\n this.database._setTransport(this.transport);\r\n this.db = this.database;\r\n this.storage = new RagableBrowserStorageClient(\r\n options,\r\n bindFetch(options.fetch),\r\n this._ragableAuth as RagableAuth | null,\r\n );\r\n this.mail = new RagableBrowserMailClient(options, this._ragableAuth as RagableAuth | null);\r\n this.functions = new RagableBrowserFunctionsClient(\r\n options,\r\n this._ragableAuth as RagableAuth | null,\r\n ).asInvoker<Functions>();\r\n }\r\n\r\n /** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */\r\n from = <TableName extends RagableTableNames<Database>>(\r\n table: TableName,\r\n databaseInstanceId?: string,\r\n ): PostgrestTableApi<Database, TableName> => {\r\n return this.database.from(table, databaseInstanceId);\r\n };\r\n\r\n /**\r\n * Resolves once the persisted session has been restored (and refreshed if it\r\n * was expired). Await this before reading auth state at startup to avoid a\r\n * logged-out flash, e.g. `const session = await client.ready()`. Resolves\r\n * `null` when no auth group is configured or no session is stored.\r\n */\r\n ready(): Promise<AuthSession<AuthUser> | null> {\r\n return this._ragableAuth\r\n ? this._ragableAuth.initialize()\r\n : Promise.resolve(null);\r\n }\r\n\r\n destroy(): void {\r\n this._ragableAuth?.destroy();\r\n }\r\n}\r\n\r\nexport function createBrowserClient<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n AuthUser extends object = DefaultAuthUser,\r\n Functions extends RagableFunctions = DefaultRagableFunctions,\r\n>(\r\n options: RagableBrowserClientOptions,\r\n): RagableBrowser<Database, AuthUser, Functions> {\r\n return new RagableBrowser<Database, AuthUser, Functions>(options);\r\n}\r\n\r\nexport const createRagableBrowserClient = createBrowserClient;\r\n","export type {\r\n ColumnName,\r\n ColumnValue,\r\n DefaultRagableDatabase,\r\n Json,\r\n RagableDatabase,\r\n RagableTableDefinition,\r\n RagableTableNames,\r\n TableInsertRow,\r\n TableRow,\r\n TableUpdatePatch,\r\n Tables,\r\n TablesInsert,\r\n TablesUpdate,\r\n} from \"./database-schema\";\r\n\r\nexport type { RequestOptions } from \"./request-client\";\r\nexport {\r\n bindFetch,\r\n DEFAULT_RAGABLE_API_BASE,\r\n extractErrorMessage,\r\n formatSdkError,\r\n formatPostgrestError,\r\n RagableAbortError,\r\n RagableError,\r\n RagableNetworkError,\r\n RagableSdkError,\r\n RagableTimeoutError,\r\n} from \"./request-client\";\r\n\r\nexport type {\r\n AgentChatMessage,\r\n AgentChatParams,\r\n AgentChatStreamDonePayload,\r\n AgentChatStreamHandlers,\r\n AgentChatStreamResult,\r\n AgentStreamAgentInfoEvent,\r\n AgentStreamEvent,\r\n RunAgentChatStreamOptions,\r\n} from \"./agent-stream\";\r\nexport {\r\n isIncompleteAgentStreamError,\r\n parseAgentStreamAgentInfo,\r\n parseAgentStreamDone,\r\n runAgentChatStream,\r\n runAgentChatStreamLenient,\r\n} from \"./agent-stream\";\r\n\r\nexport type {\r\n AgentChatStreamUiHandlers,\r\n AgentChatUiAssistantMessage,\r\n AgentChatUiSegment,\r\n AgentChatUiStreamResult,\r\n} from \"./agent-chat-ui\";\r\nexport {\r\n collectAssistantTextFromUiSegments,\r\n finalizeAgentChatUiTurn,\r\n foldAgentStreamIntoUiSegments,\r\n runAgentChatStreamForUi,\r\n} from \"./agent-chat-ui\";\r\n\r\nexport type {\r\n AgentConversation,\r\n AgentConversationMessage,\r\n AgentConversationSubscription,\r\n AgentPublicChatParams,\r\n BrowserAuthSession,\r\n BrowserAuthTokens,\r\n BrowserCollectionApi,\r\n BrowserCollectionDefinition,\r\n BrowserCollectionFactory,\r\n BrowserCollectionFindParams,\r\n BrowserCollectionRecord,\r\n BrowserCollections,\r\n CollectionReturnMode,\r\n CollectionRowData,\r\n CollectionRowWithMeta,\r\n CollectionWhere,\r\n BrowserDataAuthMode,\r\n BrowserRealtimeNotification,\r\n BrowserRealtimeStatus,\r\n BrowserRealtimeSubscribeParams,\r\n BrowserRealtimeSubscription,\r\n BrowserSqlQueryParams,\r\n BrowserSqlQueryResult,\r\n BrowserStorageBulkDeleteResult,\r\n BrowserStorageDownloadResult,\r\n BrowserStorageItem,\r\n BrowserStorageListResult,\r\n BrowserStorageSignedUrlResult,\r\n BrowserStorageUploadResult,\r\n PostgrestResult,\r\n RagableBrowserClientOptions,\r\n SupabaseCompatSession,\r\n WhereInput,\r\n WhereOperatorObject,\r\n} from \"./browser\";\r\nexport {\r\n assertPostgrestSuccess,\r\n BrowserStorageBucketClient,\r\n collectionRecordToRowWithMeta,\r\n collectionRecordsToRowWithMeta,\r\n createBrowserClient,\r\n createRagableBrowserClient,\r\n effectiveDataAuth,\r\n normalizeBrowserApiBase,\r\n RagableBrowser,\r\n RagableBrowserAgentsClient,\r\n RagableBrowserAuthClient,\r\n RagableBrowserDatabaseClient,\r\n RagableBrowserMailClient,\r\n RagableBrowserStorageClient,\r\n toRagableResult,\r\n unwrapPostgrest,\r\n} from \"./browser\";\r\nexport type {\r\n MailMessageDetail,\r\n MailMessagePreview,\r\n MailSearchParams,\r\n MailSendParams,\r\n MailSendResult,\r\n} from \"./browser\";\r\n\r\nexport type {\r\n BrowserSqlExecParams,\r\n BrowserSqlExecResult,\r\n PostgRESTFetch,\r\n PostgRESTFetchParams,\r\n PostgrestUpsertOptions,\r\n RunQuery,\r\n} from \"./browser-postgrest\";\r\nexport type { RagableResult } from \"./browser-postgrest\";\r\nexport {\r\n asPostgrestResponse,\r\n PostgrestDeleteReturningBuilder,\r\n PostgrestDeleteRootBuilder,\r\n PostgrestInsertReturningBuilder,\r\n PostgrestInsertRootBuilder,\r\n PostgrestInsertSdkErrorReturning,\r\n PostgrestInsertSdkErrorRoot,\r\n PostgrestSelectBuilder,\r\n PostgrestTableApi,\r\n PostgrestUpdateReturningBuilder,\r\n PostgrestUpdateRootBuilder,\r\n PostgrestUpsertReturningBuilder,\r\n PostgrestUpsertRootBuilder,\r\n} from \"./browser-postgrest\";\r\n\r\nexport type { SseJsonEvent } from \"./sse\";\r\nexport { parseSseDataLine, readSseStream } from \"./sse\";\r\n\r\nexport type {\r\n FinishReason,\r\n Message,\r\n StreamPart,\r\n TokenUsage,\r\n} from \"./stream-parts\";\r\nexport { mapAgentEvent, mapFireworksChunk } from \"./stream-parts\";\r\n\r\nexport type {\r\n GenerateObjectResult,\r\n GenerateTextResult,\r\n JsonSchema,\r\n StreamObjectParams,\r\n StreamObjectResult,\r\n StreamTextParams,\r\n StreamTextResult,\r\n ToolCallRecord,\r\n} from \"./ai\";\r\nexport {\r\n buildInferenceRequestBody,\r\n buildResponseFormat,\r\n createStreamResultFromParts,\r\n RagableBrowserAiClient,\r\n streamObjectFromContext,\r\n wrapStreamTextAsObject,\r\n} from \"./ai\";\r\n\r\nexport { tryParsePartialJson } from \"./partial-json\";\r\n\r\nexport type {\r\n HttpMethod,\r\n RetryOptions,\r\n TransportOptions,\r\n TransportRequest,\r\n} from \"./transport\";\r\nexport { generateIdempotencyKey, Transport, parseTransportResponse } from \"./transport\";\r\n\r\nexport type {\r\n SessionStorage,\r\n AuthBroadcastMessage,\r\n} from \"./auth-storage\";\r\nexport {\r\n AuthBroadcastChannel,\r\n CookieStorageAdapter,\r\n detectStorage,\r\n LocalStorageAdapter,\r\n MemoryStorageAdapter,\r\n SessionStorageAdapter,\r\n} from \"./auth-storage\";\r\n\r\nexport type {\r\n AuthChangeEvent,\r\n AuthSignUpCredentials,\r\n AuthOptions,\r\n AuthSession,\r\n AuthUpdateUserAttributes,\r\n AuthUserMetadata,\r\n DefaultAuthUser,\r\n RagableAuthConfig,\r\n} from \"./auth\";\r\nexport { RagableAuth } from \"./auth\";\r\n\r\nexport type {\r\n DefaultRagableFunctions,\r\n FunctionInvoker,\r\n RagableFunctionCall,\r\n RagableFunctionContext,\r\n RagableFunctionHandler,\r\n RagableFunctionInvokeOptions,\r\n RagableFunctions,\r\n} from \"./functions\";\r\nexport { RagableBrowserFunctionsClient } from \"./browser\";\r\n\r\n// ─── Top-level client factory ────────────────────────────────────────────────\r\n\r\nimport {\r\n createBrowserClient,\r\n RagableBrowser,\r\n type RagableBrowserClientOptions,\r\n} from \"./browser\";\r\nimport type { DefaultAuthUser } from \"./auth\";\r\nimport type { DefaultRagableDatabase, RagableDatabase } from \"./database-schema\";\r\nimport type { DefaultRagableFunctions, RagableFunctions } from \"./functions\";\r\n\r\nexport function createClient<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n AuthUser extends object = DefaultAuthUser,\r\n Functions extends RagableFunctions = DefaultRagableFunctions,\r\n>(\r\n options: RagableBrowserClientOptions,\r\n): RagableBrowser<Database, AuthUser, Functions> {\r\n return createBrowserClient<Database, AuthUser, Functions>(options);\r\n}\r\n"],"mappings":"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","names":["asString","asNumber","assertAborted","asNum","key"]}
|
|
1
|
+
{"version":3,"sources":["../src/request-client.ts","../src/agent-stream.ts","../src/agent-chat-ui.ts","../src/sse.ts","../src/transport.ts","../src/browser-postgrest.ts","../src/auth-storage.ts","../src/auth.ts","../src/partial-json.ts","../src/stream-parts.ts","../src/ai.ts","../src/browser.ts","../src/server.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Native `fetch` must not be called as a detached reference (`const f = fetch; f(url)`),\r\n * or the browser throws **Illegal invocation**. Use this for defaults and for `options.fetch`.\r\n */\r\nexport function bindFetch(custom?: typeof fetch): typeof fetch {\r\n return (input, init) => {\r\n const f = custom ?? globalThis.fetch;\r\n return f.call(globalThis, input as RequestInfo, init);\r\n };\r\n}\r\n\r\n/** Hosted Ragable HTTP API base (`…/api`) — used by all SDK clients (not configurable). */\r\nexport const DEFAULT_RAGABLE_API_BASE =\r\n \"https://ragable-341305259977.asia-southeast1.run.app/api\";\r\n\r\nexport interface RagableClientOptions {\r\n apiKey: string;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n}\r\n\r\nexport type RequestOptions = Omit<RequestInit, \"body\"> & {\r\n body?: unknown;\r\n};\r\n\r\nexport abstract class RagableSdkError extends Error {\r\n abstract readonly __type: string;\r\n constructor(message: string) {\r\n super(message);\r\n this.name = this.constructor.name;\r\n // Native `Error.message` is non-enumerable — `{...err}`, `JSON.stringify({...err})`, and some\r\n // loggers show `{}`. Redefine so spreads and plain serialization keep `message`.\r\n Object.defineProperty(this, \"message\", {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value: message,\r\n });\r\n }\r\n\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n __type: this.__type,\r\n };\r\n }\r\n}\r\n\r\nexport class RagableError extends RagableSdkError {\r\n readonly __type = \"RagableError\" as const;\r\n readonly status: number;\r\n readonly body: unknown;\r\n readonly code: string | undefined;\r\n readonly details: string | undefined;\r\n\r\n constructor(message: string, status: number, body: unknown) {\r\n super(message);\r\n this.status = status;\r\n this.body = body;\r\n this.code =\r\n body && typeof body === \"object\"\r\n ? typeof (body as Record<string, unknown>).code === \"string\"\r\n ? ((body as Record<string, unknown>).code as string)\r\n : typeof (body as Record<string, unknown>).code === \"number\"\r\n ? String((body as Record<string, unknown>).code)\r\n : undefined\r\n : undefined;\r\n this.details =\r\n body && typeof body === \"object\"\r\n ? typeof (body as Record<string, unknown>).details === \"string\"\r\n ? ((body as Record<string, unknown>).details as string)\r\n : undefined\r\n : undefined;\r\n }\r\n\r\n override toJSON(): Record<string, unknown> {\r\n return {\r\n ...super.toJSON(),\r\n status: this.status,\r\n body: this.body,\r\n code: this.code,\r\n details: this.details,\r\n };\r\n }\r\n\r\n /** Stable string for logs — avoids `{}` when coercing or stringifying. */\r\n override toString(): string {\r\n const bits = [`${this.name}: ${this.message}`];\r\n if (this.status) bits.push(`status=${this.status}`);\r\n if (this.code) bits.push(`code=${this.code}`);\r\n return bits.join(\" · \");\r\n }\r\n}\r\n\r\n/** Safe one-line log for any thrown value (catch blocks, TanStack Query). */\r\nexport function formatSdkError(err: unknown): string {\r\n if (err instanceof RagableError) {\r\n return `${err.message} (HTTP ${err.status}${err.code ? `, ${err.code}` : \"\"})`;\r\n }\r\n if (err instanceof RagableSdkError) {\r\n return err.message;\r\n }\r\n if (err instanceof Error) {\r\n return err.message || err.name;\r\n }\r\n if (typeof err === \"string\") return err;\r\n if (err && typeof err === \"object\") {\r\n try {\r\n const s = JSON.stringify(err);\r\n if (s !== \"{}\") return s;\r\n return \"Unknown error (empty object — avoid `{...error}` spread; use error.message or formatSdkError)\";\r\n } catch {\r\n /* fall through */\r\n }\r\n }\r\n return String(err);\r\n}\r\n\r\n/**\r\n * Human-readable line for a PostgREST `{ data, error }` error (or any thrown value).\r\n * Use in UI instead of `JSON.stringify(error)` or template strings on unknown errors.\r\n */\r\nexport function formatPostgrestError(error: unknown): string {\r\n return formatSdkError(error);\r\n}\r\n\r\nexport class RagableNetworkError extends RagableSdkError {\r\n readonly __type = \"RagableNetworkError\" as const;\r\n readonly cause: unknown;\r\n constructor(message: string, cause?: unknown) {\r\n super(message);\r\n this.cause = cause;\r\n }\r\n\r\n override toJSON(): Record<string, unknown> {\r\n return {\r\n ...super.toJSON(),\r\n cause: this.cause instanceof Error ? this.cause.message : this.cause,\r\n };\r\n }\r\n}\r\n\r\nexport class RagableAbortError extends RagableSdkError {\r\n readonly __type = \"RagableAbortError\" as const;\r\n constructor(message = \"Request aborted\") {\r\n super(message);\r\n }\r\n}\r\n\r\nexport class RagableTimeoutError extends RagableSdkError {\r\n readonly __type = \"RagableTimeoutError\" as const;\r\n readonly timeoutMs: number;\r\n constructor(timeoutMs: number) {\r\n super(`Request timed out after ${timeoutMs}ms`);\r\n this.timeoutMs = timeoutMs;\r\n }\r\n\r\n override toJSON(): Record<string, unknown> {\r\n return {\r\n ...super.toJSON(),\r\n timeoutMs: this.timeoutMs,\r\n };\r\n }\r\n}\r\n\r\nexport function extractErrorMessage(payload: unknown, fallback: string) {\r\n if (payload && typeof payload === \"object\") {\r\n if (\"error\" in payload && typeof payload.error === \"string\") {\r\n return payload.error;\r\n }\r\n if (\"message\" in payload && typeof payload.message === \"string\") {\r\n return payload.message;\r\n }\r\n }\r\n\r\n if (typeof payload === \"string\" && payload.length > 0) {\r\n return payload;\r\n }\r\n\r\n return fallback || \"Request failed\";\r\n}\r\n\r\nexport class RagableRequestClient {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: string;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultHeaders: HeadersInit | undefined;\r\n\r\n constructor(options: RagableClientOptions) {\r\n this.apiKey = options.apiKey;\r\n this.baseUrl = DEFAULT_RAGABLE_API_BASE.replace(/\\/+$/, \"\");\r\n this.fetchImpl = bindFetch(options.fetch);\r\n this.defaultHeaders = options.headers;\r\n }\r\n\r\n toUrl(path: string) {\r\n const normalizedBase = this.baseUrl.replace(/\\/+$/, \"\");\r\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n return `${normalizedBase}${normalizedPath}`;\r\n }\r\n\r\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\r\n const response = await this.rawFetch(path, options);\r\n const payload = await this.parseResponseBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n return payload as T;\r\n }\r\n\r\n /**\r\n * Low-level fetch with API key and JSON body encoding. Caller handles status and body.\r\n */\r\n async rawFetch(path: string, options: RequestOptions = {}): Promise<Response> {\r\n const headers = new Headers(this.defaultHeaders);\r\n headers.set(\"Authorization\", `Bearer ${this.apiKey}`);\r\n\r\n let body = options.body;\r\n if (body !== undefined && !isBodyInit(body)) {\r\n headers.set(\"Content-Type\", \"application/json\");\r\n body = JSON.stringify(body);\r\n }\r\n\r\n return this.fetchImpl(this.toUrl(path), {\r\n ...options,\r\n headers,\r\n body: body as BodyInit | undefined,\r\n });\r\n }\r\n\r\n private async parseResponseBody(response: Response): Promise<unknown> {\r\n if (response.status === 204) {\r\n return null;\r\n }\r\n\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n if (contentType.includes(\"application/json\")) {\r\n return response.json();\r\n }\r\n\r\n return response.text();\r\n }\r\n}\r\n\r\nexport function isBodyInit(value: unknown): value is BodyInit {\r\n return (\r\n typeof value === \"string\" ||\r\n value instanceof Blob ||\r\n value instanceof FormData ||\r\n value instanceof URLSearchParams ||\r\n value instanceof ArrayBuffer ||\r\n ArrayBuffer.isView(value)\r\n );\r\n}\r\n","import { RagableAbortError, RagableError } from \"./request-client\";\n\nexport interface AgentChatMessage {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface AgentChatParams {\n message: string;\n history?: AgentChatMessage[];\n /** Passed to `fetch` — aborts the HTTP request and SSE body. */\n signal?: AbortSignal;\n}\n\nexport type AgentStreamEvent = Record<string, unknown> & { type: string };\n\n/**\n * First SSE frame for website project agents (`POST …/agents/:name/chat/stream`).\n */\nexport interface AgentStreamAgentInfoEvent {\n type: \"agent:info\";\n name: string;\n agent_name: string;\n}\n\n/** Payload on the terminal `done` event (matches backend {@link AgentChatResult} + usage fields). */\nexport interface AgentChatStreamDonePayload {\n response: string;\n traces: unknown[];\n totalDurationMs: number;\n httpResponse?: unknown;\n inputTokens?: number;\n outputTokens?: number;\n cachedPromptTokens?: number;\n cacheCreationInputTokens?: number;\n completionProviders?: string[];\n creditsCharged?: number;\n agentSteps?: number;\n finishReason?: string | null;\n stopReason?: string | null;\n turnMessages?: unknown;\n promptTokensEstimated?: number;\n contextWindow?: number;\n}\n\n/**\n * Resolved outcome after the stream finishes. `assistantText` is the concatenation of\n * all `token` deltas; `response` is the server’s final string from `done` (authoritative).\n */\nexport interface AgentChatStreamResult extends AgentChatStreamDonePayload {\n assistantText: string;\n reasoningText: string;\n}\n\nexport interface AgentChatStreamHandlers {\n /** Every parsed SSE object (including `ping`, `node:*`, etc.). */\n onEvent?: (event: AgentStreamEvent) => void;\n onAgentInfo?: (info: AgentStreamAgentInfoEvent) => void;\n onToken?: (token: string, ctx: { nodeId: string }) => void;\n onReasoningToken?: (token: string, ctx: { nodeId: string }) => void;\n onToolCall?: (ctx: {\n nodeId: string;\n toolName: string;\n args: unknown;\n }) => void;\n onToolArgsUpdate?: (ctx: {\n nodeId: string;\n args: Record<string, unknown>;\n }) => void;\n onToolResult?: (ctx: {\n nodeId: string;\n toolName: string;\n durationMs: number;\n result?: string;\n }) => void;\n onNodeStart?: (ctx: {\n nodeId: string;\n nodeType: string;\n label: string;\n }) => void;\n onNodeComplete?: (ctx: {\n nodeId: string;\n output: unknown;\n durationMs: number;\n }) => void;\n onNodeError?: (ctx: { nodeId: string; error: string }) => void;\n /** Backend heartbeat — safe to ignore in UI. */\n onPing?: () => void;\n /** Fired when the server emits `done` (before {@link onComplete}). */\n onDone?: (payload: AgentChatStreamDonePayload) => void;\n /**\n * Always called on successful completion (after `done`). Not called if the stream\n * errors or ends without `done`.\n */\n onComplete?: (result: AgentChatStreamResult) => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface RunAgentChatStreamOptions {\n /**\n * Abort while consuming events (in addition to any `signal` on the HTTP request).\n * Stops reading and throws {@link RagableAbortError}.\n */\n signal?: AbortSignal;\n}\n\nfunction assertAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new RagableAbortError();\n }\n}\n\nfunction asString(v: unknown, fallback = \"\"): string {\n return typeof v === \"string\" ? v : fallback;\n}\n\nfunction asNumber(v: unknown, fallback = 0): number {\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\n\nfunction asUnknownArray(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\n/** Narrow `done` events from a loose {@link AgentStreamEvent}. */\nexport function parseAgentStreamDone(\n e: AgentStreamEvent,\n): AgentChatStreamDonePayload | null {\n if (e.type !== \"done\") return null;\n return {\n response: asString(e[\"response\"]),\n traces: asUnknownArray(e[\"traces\"]),\n totalDurationMs: asNumber(e[\"totalDurationMs\"]),\n ...(e[\"httpResponse\"] !== undefined\n ? { httpResponse: e[\"httpResponse\"] }\n : {}),\n ...(typeof e[\"inputTokens\"] === \"number\"\n ? { inputTokens: e[\"inputTokens\"] }\n : {}),\n ...(typeof e[\"outputTokens\"] === \"number\"\n ? { outputTokens: e[\"outputTokens\"] }\n : {}),\n ...(typeof e[\"cachedPromptTokens\"] === \"number\"\n ? { cachedPromptTokens: e[\"cachedPromptTokens\"] }\n : {}),\n ...(typeof e[\"cacheCreationInputTokens\"] === \"number\"\n ? { cacheCreationInputTokens: e[\"cacheCreationInputTokens\"] }\n : {}),\n ...(Array.isArray(e[\"completionProviders\"])\n ? {\n completionProviders: e[\"completionProviders\"].map((x: unknown) => String(x)),\n }\n : {}),\n ...(typeof e[\"creditsCharged\"] === \"number\"\n ? { creditsCharged: e[\"creditsCharged\"] }\n : {}),\n ...(typeof e[\"agentSteps\"] === \"number\"\n ? { agentSteps: e[\"agentSteps\"] }\n : {}),\n ...(e[\"finishReason\"] !== undefined\n ? { finishReason: e[\"finishReason\"] as string | null }\n : {}),\n ...(e[\"stopReason\"] !== undefined\n ? { stopReason: e[\"stopReason\"] as string | null }\n : {}),\n ...(e[\"turnMessages\"] !== undefined\n ? { turnMessages: e[\"turnMessages\"] }\n : {}),\n ...(typeof e[\"promptTokensEstimated\"] === \"number\"\n ? { promptTokensEstimated: e[\"promptTokensEstimated\"] }\n : {}),\n ...(typeof e[\"contextWindow\"] === \"number\"\n ? { contextWindow: e[\"contextWindow\"] }\n : {}),\n };\n}\n\n/** @public Parse the initial `agent:info` SSE frame (website project agents). */\nexport function parseAgentStreamAgentInfo(\n e: AgentStreamEvent,\n): AgentStreamAgentInfoEvent | null {\n if (e.type !== \"agent:info\") return null;\n return {\n type: \"agent:info\",\n name: asString(e[\"name\"]),\n agent_name: asString(e[\"agent_name\"]),\n };\n}\n\nfunction parseAgentInfo(\n e: AgentStreamEvent,\n): AgentStreamAgentInfoEvent | null {\n return parseAgentStreamAgentInfo(e);\n}\n\n/**\n * Consume a Ragable agent SSE stream with callbacks and return the final result.\n *\n * For the same segment model as dashboard `AgentChat` (`streamingSegments` /\n * `streamingContent`), use {@link runAgentChatStreamForUi} or\n * `client.agents.runChatUiByName` instead.\n *\n * Typical low-level chat (string accumulation only):\n *\n * ```ts\n * const result = await client.agents.runChatStreamByName(\"support\", {\n * message: input,\n * history,\n * signal: ac.signal,\n * }, {\n * onToken: (t) => setReply((s) => s + t),\n * });\n * ```\n *\n * Lower-level (same client, manual iterator):\n *\n * ```ts\n * const result = await runAgentChatStream(\n * client.agents.chatStreamByName(\"support\", { message, signal }),\n * { onToken: (t) => append(t) },\n * { signal },\n * );\n * ```\n */\nexport async function runAgentChatStream(\n source: AsyncIterable<AgentStreamEvent>,\n handlers: AgentChatStreamHandlers = {},\n options: RunAgentChatStreamOptions = {},\n): Promise<AgentChatStreamResult> {\n const { signal } = options;\n let assistantText = \"\";\n let reasoningText = \"\";\n let donePayload: AgentChatStreamDonePayload | null = null;\n\n try {\n for await (const event of source) {\n assertAborted(signal);\n handlers.onEvent?.(event);\n\n const info = parseAgentInfo(event);\n if (info) {\n handlers.onAgentInfo?.(info);\n continue;\n }\n\n switch (event.type) {\n case \"ping\":\n handlers.onPing?.();\n break;\n case \"token\": {\n const nodeId = asString(event[\"nodeId\"], \"__self__\");\n const token = asString(event[\"token\"]);\n assistantText += token;\n handlers.onToken?.(token, { nodeId });\n break;\n }\n case \"reasoning_token\": {\n const nodeId = asString(event[\"nodeId\"], \"__self__\");\n const token = asString(event[\"token\"]);\n reasoningText += token;\n handlers.onReasoningToken?.(token, { nodeId });\n break;\n }\n case \"tool:call\":\n handlers.onToolCall?.({\n nodeId: asString(event[\"nodeId\"]),\n toolName: asString(event[\"toolName\"]),\n args: event[\"args\"],\n });\n break;\n case \"tool:args_update\": {\n const raw = event[\"args\"];\n const args =\n raw !== null && typeof raw === \"object\" && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : {};\n handlers.onToolArgsUpdate?.({\n nodeId: asString(event[\"nodeId\"]),\n args,\n });\n break;\n }\n case \"tool:result\":\n handlers.onToolResult?.({\n nodeId: asString(event[\"nodeId\"]),\n toolName: asString(event[\"toolName\"]),\n durationMs: asNumber(event[\"durationMs\"]),\n ...(typeof event[\"result\"] === \"string\"\n ? { result: event[\"result\"] }\n : {}),\n });\n break;\n case \"node:start\":\n handlers.onNodeStart?.({\n nodeId: asString(event[\"nodeId\"]),\n nodeType: asString(event[\"nodeType\"]),\n label: asString(event[\"label\"]),\n });\n break;\n case \"node:complete\":\n handlers.onNodeComplete?.({\n nodeId: asString(event[\"nodeId\"]),\n output: event[\"output\"],\n durationMs: asNumber(event[\"durationMs\"]),\n });\n break;\n case \"node:error\":\n handlers.onNodeError?.({\n nodeId: asString(event[\"nodeId\"]),\n error: asString(event[\"error\"]),\n });\n break;\n case \"done\": {\n const parsed = parseAgentStreamDone(event);\n if (parsed) {\n donePayload = parsed;\n handlers.onDone?.(parsed);\n }\n break;\n }\n default:\n break;\n }\n }\n } catch (err) {\n handlers.onError?.(err);\n throw err;\n }\n\n if (!donePayload) {\n const err = new RagableError(\n \"Agent stream ended without a done event\",\n 502,\n { code: \"SDK_AGENT_STREAM_INCOMPLETE\" },\n );\n handlers.onError?.(err);\n throw err;\n }\n\n const result: AgentChatStreamResult = {\n ...donePayload,\n assistantText,\n reasoningText,\n };\n handlers.onComplete?.(result);\n return result;\n}\n\n/**\n * Like {@link runAgentChatStream} but resolves with `null` if the stream ends without `done`\n * instead of throwing. Errors other than incomplete stream are still thrown.\n */\nexport async function runAgentChatStreamLenient(\n source: AsyncIterable<AgentStreamEvent>,\n handlers: AgentChatStreamHandlers = {},\n options: RunAgentChatStreamOptions = {},\n): Promise<AgentChatStreamResult | null> {\n try {\n return await runAgentChatStream(source, handlers, options);\n } catch (e) {\n if (\n e instanceof RagableError &&\n e.code === \"SDK_AGENT_STREAM_INCOMPLETE\"\n ) {\n return null;\n }\n throw e;\n }\n}\n\n/** True when {@link runAgentChatStream} stopped because no `done` event arrived. */\nexport function isIncompleteAgentStreamError(e: unknown): boolean {\n return e instanceof RagableError && e.code === \"SDK_AGENT_STREAM_INCOMPLETE\";\n}\n","/**\n * UI-oriented agent streaming — folds wire events into the same segment model as\n * `app/web/src/components/AgentChat.tsx` (`StreamSegment`), matching the reducers in\n * `useEngineIDEAgent` / `useIDEAgent` (tool gating, coalesced text/reasoning, etc.).\n */\n\nimport type { AgentStreamEvent } from \"./agent-stream\";\nimport type {\n AgentChatStreamDonePayload,\n AgentStreamAgentInfoEvent,\n RunAgentChatStreamOptions,\n} from \"./agent-stream\";\nimport {\n parseAgentStreamAgentInfo,\n parseAgentStreamDone,\n} from \"./agent-stream\";\nimport { RagableAbortError, RagableError } from \"./request-client\";\n\n/**\n * Chat UI segments — structural parity with `StreamSegment` in dashboard `AgentChat`.\n */\nexport type AgentChatUiSegment =\n | { type: \"text\"; content: string }\n | { type: \"reasoning\"; content: string }\n | {\n type: \"tool\";\n id: string;\n toolName: string;\n status: \"started\" | \"completed\";\n durationMs?: number;\n args?: Record<string, unknown>;\n result?: string;\n }\n | {\n type: \"context_summarized\";\n step: number;\n mode?: \"llm\" | \"heuristic\" | \"llm+heuristic\" | \"aggressive\";\n reason?: \"soft_limit\" | \"forced\";\n tokensRemovedEstimate?: number;\n estimatedTokensAfter?: number;\n }\n | {\n type: \"llm_step\";\n step: number;\n inputTokens: number;\n outputTokens: number;\n cachedPromptTokens?: number;\n cacheCreationInputTokens?: number;\n creditsEstimated: number;\n apiCostUsd?: number;\n provider?: string;\n }\n | { type: \"stop_reason\"; content: string; finishReason: string };\n\n/** Assistant row to append to chat history (add your own `id`). */\nexport interface AgentChatUiAssistantMessage {\n role: \"ai\";\n content: string;\n segments?: AgentChatUiSegment[];\n usage?: {\n inputTokens: number;\n outputTokens: number;\n creditsCharged: number;\n cachedPromptTokens?: number;\n cacheCreationInputTokens?: number;\n };\n durationMs?: number;\n finishReason?: string | null;\n completionProviders?: string[];\n agentSteps?: number;\n}\n\nexport interface AgentChatUiStreamResult {\n /** Segments immediately before `done` (no trailing `stop_reason`). */\n segmentsMidTurn: AgentChatUiSegment[];\n /** Final segments including optional `stop_reason` from `done`. */\n segments: AgentChatUiSegment[];\n /** Persisted assistant message — matches dashboard `ChatMessageData` for `ai` (except `id`). */\n message: AgentChatUiAssistantMessage;\n done: AgentChatStreamDonePayload;\n}\n\nexport interface AgentChatStreamUiHandlers {\n /**\n * Live segment list — pass to `AgentChat` as `streamingSegments` (or your own renderer).\n */\n onSegments?: (segments: AgentChatUiSegment[]) => void;\n /**\n * Plain assistant text — mirrors dashboard `streamingContent` (text channel only).\n */\n onStreamingText?: (text: string) => void;\n onAgentInfo?: (info: AgentStreamAgentInfoEvent) => void;\n onEvent?: (event: AgentStreamEvent) => void;\n onDone?: (payload: AgentChatStreamDonePayload) => void;\n onComplete?: (result: AgentChatUiStreamResult) => void;\n onError?: (error: unknown) => void;\n}\n\nfunction asString(v: unknown, fallback = \"\"): string {\n return typeof v === \"string\" ? v : fallback;\n}\n\nfunction asNumber(v: unknown, fallback = 0): number {\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\n\nfunction assertAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new RagableAbortError();\n }\n}\n\nfunction recordFromUnknown(v: unknown): Record<string, unknown> {\n if (v !== null && typeof v === \"object\" && !Array.isArray(v)) {\n return { ...(v as Record<string, unknown>) };\n }\n return {};\n}\n\nfunction lastToolBlocksStream(\n last: AgentChatUiSegment | undefined,\n): boolean {\n return last?.type === \"tool\" && last.status === \"started\";\n}\n\nfunction toolSegmentId(event: AgentStreamEvent): string {\n const nid = event[\"nodeId\"];\n if (typeof nid === \"string\" && nid.length > 0) return nid;\n const tn = event[\"toolName\"];\n if (typeof tn === \"string\" && tn.length > 0) return tn;\n return \"__tool__\";\n}\n\nfunction normalizeContextSummarizedMode(\n m: unknown,\n): \"llm\" | \"heuristic\" | \"llm+heuristic\" | \"aggressive\" | undefined {\n if (\n m === \"llm\" ||\n m === \"heuristic\" ||\n m === \"llm+heuristic\" ||\n m === \"aggressive\"\n ) {\n return m;\n }\n return undefined;\n}\n\nfunction normalizeContextSummarizedReason(\n r: unknown,\n): \"soft_limit\" | \"forced\" | undefined {\n if (r === \"soft_limit\" || r === \"forced\") return r;\n return undefined;\n}\n\nfunction foldContextSummarized(\n prev: AgentChatUiSegment[],\n event: AgentStreamEvent,\n): AgentChatUiSegment[] {\n const step = asNumber(event[\"step\"], 0);\n const mode = normalizeContextSummarizedMode(event[\"mode\"]);\n const reason = normalizeContextSummarizedReason(event[\"reason\"]);\n const tro = event[\"tokensRemovedEstimate\"];\n const eta = event[\"estimatedTokensAfter\"];\n return [\n ...prev,\n {\n type: \"context_summarized\",\n step,\n ...(mode ? { mode } : {}),\n ...(reason ? { reason } : {}),\n ...(typeof tro === \"number\" && tro > 0\n ? { tokensRemovedEstimate: tro }\n : {}),\n ...(typeof eta === \"number\" && eta > 0\n ? { estimatedTokensAfter: eta }\n : {}),\n },\n ];\n}\n\n/** Concatenate `text` segments (ignores reasoning/tools). */\nexport function collectAssistantTextFromUiSegments(\n segments: AgentChatUiSegment[],\n): string {\n return segments\n .filter((s): s is { type: \"text\"; content: string } => s.type === \"text\")\n .map((s) => s.content)\n .join(\"\");\n}\n\n/**\n * Pure fold: one SSE event → next segment list. Matches `useEngineIDEAgent` / `useIDEAgent`\n * behavior for token gating while a tool is in the `started` state.\n */\nexport function foldAgentStreamIntoUiSegments(\n prev: AgentChatUiSegment[],\n event: AgentStreamEvent,\n): AgentChatUiSegment[] {\n switch (event.type) {\n case \"token\": {\n const last = prev[prev.length - 1];\n if (lastToolBlocksStream(last)) return prev;\n const token = asString(event[\"token\"]);\n if (!token) return prev;\n if (last?.type === \"text\") {\n return [\n ...prev.slice(0, -1),\n { type: \"text\", content: last.content + token },\n ];\n }\n return [...prev, { type: \"text\", content: token }];\n }\n case \"reasoning_token\": {\n const last = prev[prev.length - 1];\n if (lastToolBlocksStream(last)) return prev;\n const token = asString(event[\"token\"]);\n if (!token) return prev;\n if (last?.type === \"reasoning\") {\n return [\n ...prev.slice(0, -1),\n { type: \"reasoning\", content: last.content + token },\n ];\n }\n return [...prev, { type: \"reasoning\", content: token }];\n }\n case \"tool:call\": {\n const id = toolSegmentId(event);\n const toolName = asString(event[\"toolName\"], \"tool\");\n const argsRaw = event[\"args\"];\n const args =\n argsRaw !== null &&\n typeof argsRaw === \"object\" &&\n !Array.isArray(argsRaw)\n ? (argsRaw as Record<string, unknown>)\n : undefined;\n return [\n ...prev,\n {\n type: \"tool\",\n id,\n toolName,\n status: \"started\",\n ...(args !== undefined ? { args } : {}),\n },\n ];\n }\n case \"tool:args_update\": {\n const nodeId = asString(event[\"nodeId\"]);\n const patch = recordFromUnknown(event[\"args\"]);\n return prev.map((seg) => {\n if (seg.type !== \"tool\" || seg.id !== nodeId) return seg;\n const merged = { ...recordFromUnknown(seg.args), ...patch };\n return {\n ...seg,\n args: merged,\n };\n });\n }\n case \"tool:result\": {\n const nodeId = asString(event[\"nodeId\"]);\n const toolName =\n asString(event[\"toolName\"]) || asString(event[\"nodeId\"]);\n const durationMs =\n typeof event[\"durationMs\"] === \"number\" ? event[\"durationMs\"] : undefined;\n const resultStr =\n typeof event[\"result\"] === \"string\" ? event[\"result\"] : undefined;\n\n let idx = -1;\n if (nodeId) {\n for (let i = prev.length - 1; i >= 0; i--) {\n const s = prev[i]!;\n if (\n s.type === \"tool\" &&\n s.status === \"started\" &&\n s.id === nodeId\n ) {\n idx = i;\n break;\n }\n }\n }\n if (idx < 0 && toolName) {\n for (let i = prev.length - 1; i >= 0; i--) {\n const s = prev[i]!;\n if (\n s.type === \"tool\" &&\n s.status === \"started\" &&\n s.toolName === toolName\n ) {\n idx = i;\n break;\n }\n }\n }\n if (idx < 0) return prev;\n const next = [...prev];\n const seg = next[idx]!;\n if (seg.type !== \"tool\") return prev;\n next[idx] = {\n ...seg,\n status: \"completed\",\n ...(durationMs !== undefined ? { durationMs } : {}),\n ...(resultStr !== undefined ? { result: resultStr } : {}),\n };\n return next;\n }\n case \"context_summarized\":\n return foldContextSummarized(prev, event);\n case \"llm_step\": {\n return [\n ...prev,\n {\n type: \"llm_step\",\n step: Number(event[\"step\"]),\n inputTokens: Number(event[\"inputTokens\"] ?? 0),\n outputTokens: Number(event[\"outputTokens\"] ?? 0),\n ...(typeof event[\"cachedPromptTokens\"] === \"number\"\n ? { cachedPromptTokens: event[\"cachedPromptTokens\"] }\n : {}),\n ...(typeof event[\"cacheCreationInputTokens\"] === \"number\"\n ? { cacheCreationInputTokens: event[\"cacheCreationInputTokens\"] }\n : {}),\n creditsEstimated: Number(event[\"creditsEstimated\"] ?? 0),\n ...(typeof event[\"apiCostUsd\"] === \"number\" &&\n Number.isFinite(event[\"apiCostUsd\"])\n ? { apiCostUsd: event[\"apiCostUsd\"] }\n : {}),\n ...(typeof event[\"provider\"] === \"string\" && event[\"provider\"]\n ? { provider: event[\"provider\"] }\n : {}),\n },\n ];\n }\n default:\n return prev;\n }\n}\n\n/**\n * Merge live segments with the terminal `done` payload (optional `stop_reason` segment),\n * and build the persisted assistant message — same shape as dashboard `ChatMessageData` for `ai`.\n */\nexport function finalizeAgentChatUiTurn(\n segments: AgentChatUiSegment[],\n done: AgentChatStreamDonePayload,\n): {\n segments: AgentChatUiSegment[];\n message: AgentChatUiAssistantMessage;\n} {\n let segs: AgentChatUiSegment[] | undefined =\n segments.length > 0 ? [...segments] : undefined;\n if (done.stopReason) {\n const stopSeg: AgentChatUiSegment = {\n type: \"stop_reason\",\n content: done.stopReason,\n finishReason: done.finishReason ?? \"error\",\n };\n segs = segs ? [...segs, stopSeg] : [stopSeg];\n }\n const fromText = segs\n ? collectAssistantTextFromUiSegments(segs)\n : \"\";\n const content =\n done.response ||\n fromText ||\n \"No response.\";\n\n const message: AgentChatUiAssistantMessage = {\n role: \"ai\",\n content,\n ...(segs && segs.length > 0 ? { segments: segs } : {}),\n finishReason: done.finishReason ?? null,\n ...(Array.isArray(done.completionProviders) &&\n done.completionProviders.length > 0\n ? { completionProviders: done.completionProviders }\n : {}),\n ...(typeof done.agentSteps === \"number\" &&\n Number.isFinite(done.agentSteps) &&\n done.agentSteps > 0\n ? { agentSteps: Math.floor(done.agentSteps) }\n : {}),\n usage: {\n inputTokens: done.inputTokens ?? 0,\n outputTokens: done.outputTokens ?? 0,\n creditsCharged: done.creditsCharged ?? 0,\n ...(typeof done.cachedPromptTokens === \"number\" &&\n done.cachedPromptTokens > 0\n ? { cachedPromptTokens: done.cachedPromptTokens }\n : {}),\n ...(typeof done.cacheCreationInputTokens === \"number\" &&\n done.cacheCreationInputTokens > 0\n ? { cacheCreationInputTokens: done.cacheCreationInputTokens }\n : {}),\n },\n ...(typeof done.totalDurationMs === \"number\" && done.totalDurationMs > 0\n ? { durationMs: done.totalDurationMs }\n : {}),\n };\n\n return { segments: segs ?? [], message };\n}\n\n/**\n * Consume a stream and drive dashboard-style UI state: {@link AgentChatStreamUiHandlers.onSegments}\n * / {@link AgentChatStreamUiHandlers.onStreamingText} mirror `AgentChat`’s `streamingSegments` /\n * `streamingContent`; the returned {@link AgentChatUiStreamResult.message} is ready to append\n * to history like `useEngineIDEAgent` does on `done`.\n */\nexport async function runAgentChatStreamForUi(\n source: AsyncIterable<AgentStreamEvent>,\n handlers: AgentChatStreamUiHandlers = {},\n options: RunAgentChatStreamOptions = {},\n): Promise<AgentChatUiStreamResult> {\n const { signal } = options;\n let segments: AgentChatUiSegment[] = [];\n let donePayload: AgentChatStreamDonePayload | null = null;\n\n try {\n for await (const event of source) {\n assertAborted(signal);\n handlers.onEvent?.(event);\n\n const info = parseAgentStreamAgentInfo(event);\n if (info) {\n handlers.onAgentInfo?.(info);\n continue;\n }\n\n if (event.type === \"ping\") continue;\n\n if (event.type === \"done\") {\n const parsed = parseAgentStreamDone(event);\n if (parsed) {\n donePayload = parsed;\n handlers.onDone?.(parsed);\n }\n break;\n }\n\n const next = foldAgentStreamIntoUiSegments(segments, event);\n if (next !== segments) {\n segments = next;\n handlers.onSegments?.(segments);\n if (event.type === \"token\") {\n handlers.onStreamingText?.(\n collectAssistantTextFromUiSegments(segments),\n );\n }\n }\n }\n } catch (err) {\n handlers.onError?.(err);\n throw err;\n }\n\n if (!donePayload) {\n const err = new RagableError(\n \"Agent stream ended without a done event\",\n 502,\n { code: \"SDK_AGENT_STREAM_INCOMPLETE\" },\n );\n handlers.onError?.(err);\n throw err;\n }\n\n const segmentsMidTurn = [...segments];\n const { segments: finalSegs, message } = finalizeAgentChatUiTurn(\n segments,\n donePayload,\n );\n\n const result: AgentChatUiStreamResult = {\n segmentsMidTurn,\n segments: finalSegs,\n message,\n done: donePayload,\n };\n handlers.onComplete?.(result);\n return result;\n}\n","/**\n * Shared SSE parsing for `data: {json}` lines (Ragable agent streams).\n */\nexport type SseJsonEvent = Record<string, unknown> & { type: string };\n\nexport async function parseMaybeJsonBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n return await response.json();\n } catch {\n return null;\n }\n }\n try {\n return await response.text();\n } catch {\n return null;\n }\n}\n\nexport function parseSseDataLine(line: string): SseJsonEvent | null {\n const dataPrefix = \"data: \";\n if (!line.startsWith(dataPrefix)) {\n return null;\n }\n const json = line.slice(dataPrefix.length).trim();\n if (json.length === 0 || json === \"[DONE]\") {\n return null;\n }\n try {\n return JSON.parse(json) as SseJsonEvent;\n } catch {\n return null;\n }\n}\n\n/**\n * Read an SSE body and yield parsed `data:` JSON objects (double-newline framed).\n */\nexport async function* readSseStream(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<SseJsonEvent, void, undefined> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n\n let boundary = buffer.indexOf(\"\\n\\n\");\n while (boundary !== -1) {\n const block = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n for (const line of block.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n boundary = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n if (buffer.trim().length > 0) {\n for (const line of buffer.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import {\r\n bindFetch,\r\n RagableAbortError,\r\n RagableError,\r\n RagableNetworkError,\r\n RagableTimeoutError,\r\n extractErrorMessage,\r\n} from \"./request-client\";\r\n\r\n// ─── Types ───────────────────────────────────────────────────────────────────\r\n\r\nexport type HttpMethod = \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\" | \"HEAD\";\r\n\r\nexport interface RetryOptions {\r\n maxRetries: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n retryOn: number[];\r\n respectRetryAfter: boolean;\r\n}\r\n\r\nexport interface TransportOptions {\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n retry?: Partial<RetryOptions>;\r\n timeoutMs?: number;\r\n onRequest?: (req: TransportRequest) => void;\r\n onResponse?: (req: TransportRequest, res: Response, durationMs: number) => void;\r\n onRetry?: (req: TransportRequest, attempt: number, delayMs: number, reason: string) => void;\r\n}\r\n\r\nexport interface TransportRequest {\r\n url: string;\r\n method: HttpMethod;\r\n headers: Headers;\r\n body?: BodyInit;\r\n signal?: AbortSignal;\r\n idempotencyKey?: string;\r\n retry?: Partial<RetryOptions>;\r\n timeoutMs?: number;\r\n}\r\n\r\n// ─── Defaults ────────────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_RETRY: RetryOptions = {\r\n maxRetries: 3,\r\n baseDelayMs: 200,\r\n maxDelayMs: 5_000,\r\n retryOn: [408, 425, 429, 502, 503, 504],\r\n respectRetryAfter: true,\r\n};\r\n\r\nconst DEFAULT_TIMEOUT_MS = 30_000;\r\n\r\n// ─── Helpers ─────────────────────────────────────────────────────────────────\r\n\r\nfunction jitteredDelay(base: number, attempt: number, max: number): number {\r\n const exp = Math.min(base * 2 ** attempt, max);\r\n return Math.round(exp * (0.5 + Math.random() * 0.5));\r\n}\r\n\r\nfunction parseRetryAfter(header: string | null): number | null {\r\n if (!header) return null;\r\n const seconds = Number(header);\r\n if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1000;\r\n const date = Date.parse(header);\r\n if (Number.isFinite(date)) return Math.max(0, date - Date.now());\r\n return null;\r\n}\r\n\r\nlet _uuidCounter = 0;\r\nexport function generateIdempotencyKey(): string {\r\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\r\n return crypto.randomUUID();\r\n }\r\n _uuidCounter++;\r\n return `idk-${Date.now()}-${_uuidCounter}-${Math.random().toString(36).slice(2, 10)}`;\r\n}\r\n\r\nfunction requestCacheKey(req: TransportRequest): string {\r\n // Scope in-flight dedupe by principal AND target database instance: two\r\n // concurrent same-URL GETs issued under different bearer tokens (a sign-out /\r\n // sign-in race) or against different instances must NOT collapse into one\r\n // shared response, or a caller could receive data authorized as another\r\n // principal or from the wrong instance.\r\n const auth = req.headers.get(\"authorization\") ?? \"\";\r\n const dbInstance = req.headers.get(\"x-database-instance-id\") ?? \"\";\r\n return `${req.method}:${req.url}\\n${auth}\\n${dbInstance}`;\r\n}\r\n\r\n// ─── Transport ───────────────────────────────────────────────────────────────\r\n\r\nexport class Transport {\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultHeaders: HeadersInit | undefined;\r\n private readonly defaultRetry: RetryOptions;\r\n private readonly defaultTimeoutMs: number;\r\n private readonly onRequest?: TransportOptions[\"onRequest\"];\r\n private readonly onResponse?: TransportOptions[\"onResponse\"];\r\n private readonly onRetry?: TransportOptions[\"onRetry\"];\r\n\r\n private readonly inflightGets = new Map<string, Promise<Response>>();\r\n\r\n private _refreshHandler: (() => Promise<string | null>) | null = null;\r\n\r\n constructor(options: TransportOptions = {}) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n this.defaultHeaders = options.headers;\r\n this.defaultRetry = { ...DEFAULT_RETRY, ...options.retry };\r\n this.defaultTimeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\r\n this.onRequest = options.onRequest;\r\n this.onResponse = options.onResponse;\r\n this.onRetry = options.onRetry;\r\n }\r\n\r\n setRefreshHandler(handler: (() => Promise<string | null>) | null): void {\r\n this._refreshHandler = handler;\r\n }\r\n\r\n async execute(req: TransportRequest): Promise<Response> {\r\n if (req.method === \"GET\") {\r\n const key = requestCacheKey(req);\r\n let base = this.inflightGets.get(key);\r\n if (!base) {\r\n base = this._executeWithRetry(req);\r\n this.inflightGets.set(key, base);\r\n const clear = () => {\r\n if (this.inflightGets.get(key) === base) this.inflightGets.delete(key);\r\n };\r\n base.then(clear, clear);\r\n }\r\n // Hand every awaiter (including the first) an independent clone. A Response\r\n // body is single-read; returning the same Response to concurrent callers\r\n // makes the second `.text()`/`.json()` throw \"body stream already read\"\r\n // (guaranteed under React 18 StrictMode double-effects). The cached `base`\r\n // Response is never read directly, so cloning it stays valid.\r\n return base.then((r) => r.clone());\r\n }\r\n return this._executeWithRetry(req);\r\n }\r\n\r\n private async _executeWithRetry(req: TransportRequest): Promise<Response> {\r\n const retryOpts: RetryOptions = {\r\n ...this.defaultRetry,\r\n ...req.retry,\r\n };\r\n const timeoutMs = req.timeoutMs ?? this.defaultTimeoutMs;\r\n\r\n const headers = new Headers(this.defaultHeaders);\r\n req.headers.forEach((v, k) => headers.set(k, v));\r\n if (req.idempotencyKey) {\r\n headers.set(\"Idempotency-Key\", req.idempotencyKey);\r\n }\r\n\r\n const finalReq: TransportRequest = { ...req, headers };\r\n\r\n this.onRequest?.(finalReq);\r\n\r\n let lastError: unknown;\r\n const maxAttempts = 1 + retryOpts.maxRetries;\r\n let did401Refresh = false;\r\n\r\n // Only auto-retry methods that are safe to repeat. The backend does not yet\r\n // honor Idempotency-Key on data writes, so retrying a POST/PATCH/PUT/DELETE\r\n // that may have already been applied (a 502/504 after the gateway committed\r\n // it, or a lost response) would double-apply the write. Writes retry only\r\n // when the caller explicitly opts in via `req.retry` (e.g. a known-idempotent\r\n // endpoint). The 401-refresh path below is exempt: a 401 means the request\r\n // was rejected, not applied, so re-authing and retrying once is always safe.\r\n const isIdempotent = req.method === \"GET\" || req.method === \"HEAD\";\r\n const retryEnabled = retryOpts.maxRetries > 0 && (isIdempotent || req.retry !== undefined);\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n try {\r\n const response = await this._singleFetch(finalReq, timeoutMs);\r\n\r\n if (response.status === 401 && this._refreshHandler && !did401Refresh) {\r\n did401Refresh = true;\r\n const newToken = await this._refreshHandler();\r\n if (newToken) {\r\n finalReq.headers.set(\"Authorization\", `Bearer ${newToken}`);\r\n attempt--;\r\n continue;\r\n }\r\n }\r\n\r\n if (retryEnabled && !response.ok && retryOpts.retryOn.includes(response.status) && attempt < maxAttempts - 1) {\r\n let delayMs = jitteredDelay(retryOpts.baseDelayMs, attempt, retryOpts.maxDelayMs);\r\n if (retryOpts.respectRetryAfter) {\r\n const ra = parseRetryAfter(response.headers.get(\"retry-after\"));\r\n if (ra !== null) delayMs = Math.min(ra, retryOpts.maxDelayMs);\r\n }\r\n this.onRetry?.(finalReq, attempt + 1, delayMs, `HTTP ${response.status}`);\r\n await sleep(delayMs);\r\n continue;\r\n }\r\n\r\n return response;\r\n } catch (e) {\r\n if (e instanceof RagableAbortError || e instanceof RagableTimeoutError) {\r\n throw e;\r\n }\r\n lastError = e;\r\n if (retryEnabled && attempt < maxAttempts - 1) {\r\n const delayMs = jitteredDelay(retryOpts.baseDelayMs, attempt, retryOpts.maxDelayMs);\r\n this.onRetry?.(finalReq, attempt + 1, delayMs, (e as Error).message);\r\n await sleep(delayMs);\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n throw lastError instanceof RagableNetworkError\r\n ? lastError\r\n : new RagableNetworkError(\r\n (lastError as Error)?.message ?? \"Network request failed\",\r\n lastError,\r\n );\r\n }\r\n\r\n private async _singleFetch(req: TransportRequest, timeoutMs: number): Promise<Response> {\r\n const controller = new AbortController();\r\n const signals: AbortSignal[] = [controller.signal];\r\n if (req.signal) signals.push(req.signal);\r\n\r\n const combinedSignal = signals.length === 1\r\n ? controller.signal\r\n : AbortSignal.any\r\n ? AbortSignal.any(signals)\r\n : controller.signal;\r\n\r\n if (req.signal?.aborted) {\r\n throw new RagableAbortError();\r\n }\r\n\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n const externalAbortHandler = req.signal\r\n ? () => controller.abort()\r\n : null;\r\n if (externalAbortHandler && req.signal) {\r\n req.signal.addEventListener(\"abort\", externalAbortHandler, { once: true });\r\n }\r\n\r\n const start = Date.now();\r\n try {\r\n const response = await this.fetchImpl(req.url, {\r\n method: req.method,\r\n headers: req.headers,\r\n body: req.body,\r\n signal: combinedSignal,\r\n });\r\n this.onResponse?.(req, response, Date.now() - start);\r\n return response;\r\n } catch (e) {\r\n if ((e as Error).name === \"AbortError\") {\r\n if (req.signal?.aborted) throw new RagableAbortError();\r\n throw new RagableTimeoutError(timeoutMs);\r\n }\r\n throw new RagableNetworkError((e as Error).message, e);\r\n } finally {\r\n clearTimeout(timer);\r\n if (externalAbortHandler && req.signal) {\r\n req.signal.removeEventListener(\"abort\", externalAbortHandler);\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function parseTransportResponse<T>(response: Response): Promise<T> {\r\n if (response.status === 204) return null as T;\r\n const text = await response.text();\r\n if (!text) return null as T;\r\n let payload: unknown;\r\n try {\r\n payload = JSON.parse(text);\r\n } catch {\r\n if (!response.ok) {\r\n throw new RagableError(text.slice(0, 200), response.status, null);\r\n }\r\n return text as T;\r\n }\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n}\r\n","import { RagableError, RagableSdkError } from \"./request-client\";\r\nimport type {\r\n ColumnName,\r\n ColumnValue,\r\n DefaultRagableDatabase,\r\n RagableDatabase,\r\n RagableTableNames,\r\n TableInsertRow,\r\n TableRow,\r\n TableUpdatePatch,\r\n} from \"./database-schema\";\r\nimport { generateIdempotencyKey } from \"./transport\";\r\n\r\n// ─── Legacy types kept for backward compat (raw SQL path) ────────────────────\r\n\r\n/** @deprecated Kept for backward compat with `database.query()`. Not used by PostgREST path. */\r\nexport interface BrowserSqlExecParams {\r\n databaseInstanceId: string;\r\n sql: string;\r\n params?: unknown[];\r\n readOnly?: boolean;\r\n timeoutMs?: number;\r\n rowLimit?: number;\r\n}\r\n\r\n/** @deprecated Kept for backward compat with `database.query()`. Not used by PostgREST path. */\r\nexport interface BrowserSqlExecResult<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> {\r\n command: string;\r\n rowCount: number;\r\n truncated: boolean;\r\n rows: Row[];\r\n}\r\n\r\n/** @deprecated Use PostgRESTFetch instead. Kept for `database.query()` backward compat. */\r\nexport type RunQuery = <\r\n R extends Record<string, unknown> = Record<string, unknown>,\r\n>(\r\n p: BrowserSqlExecParams,\r\n) => Promise<BrowserSqlExecResult<R>>;\r\n\r\n// ─── PostgREST HTTP transport ────────────────────────────────────────────────\r\n\r\nexport interface PostgRESTFetchParams {\r\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\r\n table: string;\r\n searchParams: URLSearchParams;\r\n body?: unknown;\r\n headers?: Record<string, string>;\r\n databaseInstanceId: string;\r\n signal?: AbortSignal;\r\n idempotencyKey?: string;\r\n}\r\n\r\nexport type PostgRESTFetch = (\r\n params: PostgRESTFetchParams,\r\n) => Promise<Response>;\r\n\r\n// ─── Result types ────────────────────────────────────────────────────────────\r\n\r\nexport type PostgrestResult<T> =\r\n | {\r\n data: T;\r\n error: null;\r\n }\r\n | {\r\n data: null;\r\n error: RagableError;\r\n };\r\n\r\n/** Discriminated result for easier TypeScript narrowing than `{ data, error }` after destructuring. */\r\nexport type RagableResult<T, E = RagableError> =\r\n | { ok: true; value: T }\r\n | { ok: false; error: E };\r\n\r\nexport function toRagableResult<T>(r: PostgrestResult<T>): RagableResult<T> {\r\n if (r.error) return { ok: false, error: r.error };\r\n return { ok: true, value: r.data };\r\n}\r\n\r\n/**\r\n * Narrows a {@link PostgrestResult} after an `if (result.error)` guard.\r\n * Prefer checking `result.error` on the result object (not destructured `{ data, error }`)\r\n * so TypeScript narrows `data` automatically; use this when you need a throw or assertion.\r\n */\r\nexport function assertPostgrestSuccess<T>(\r\n r: PostgrestResult<T>,\r\n): asserts r is { data: T; error: null } {\r\n if (r.error) throw r.error;\r\n}\r\n\r\n/** Returns `data` or throws `RagableError` / the failure case. */\r\nexport function unwrapPostgrest<T>(r: PostgrestResult<T>): T {\r\n if (r.error) throw r.error;\r\n return r.data;\r\n}\r\n\r\nexport async function asPostgrestResponse<T>(\r\n fn: () => Promise<T>,\r\n): Promise<PostgrestResult<T>> {\r\n try {\r\n const data = await fn();\r\n return { data, error: null };\r\n } catch (e) {\r\n let err: RagableError;\r\n if (e instanceof RagableError) {\r\n err = e;\r\n } else if (e instanceof RagableSdkError) {\r\n err = new RagableError(e.message, 0, { originalError: e.__type, cause: e.message });\r\n } else {\r\n const message =\r\n e instanceof Error ? e.message : typeof e === \"string\" ? e : \"Unknown error\";\r\n err = new RagableError(message, 0, null);\r\n }\r\n return { data: null, error: err };\r\n }\r\n}\r\n\r\n// ─── PostgREST filter operators ──────────────────────────────────────────────\r\n\r\ntype FilterOp = \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"like\" | \"ilike\" | \"is\" | \"in\";\r\n\r\ninterface Filter {\r\n op: FilterOp;\r\n column: string;\r\n value: unknown;\r\n}\r\n\r\nfunction encodeFilterValue(op: FilterOp, value: unknown): string {\r\n if (op === \"is\") return `is.${value}`;\r\n if (op === \"in\") {\r\n const vals = value as unknown[];\r\n return `in.(${vals.map(String).join(\",\")})`;\r\n }\r\n return `${op}.${value}`;\r\n}\r\n\r\n// ─── Response parsing helpers ────────────────────────────────────────────────\r\n\r\nfunction extractPostgRESTErrorMessage(\r\n payload: unknown,\r\n status: number,\r\n statusText: string,\r\n): string {\r\n const st = (statusText ?? \"\").trim();\r\n if (typeof payload !== \"object\" || payload === null) {\r\n return st || `HTTP ${status}`;\r\n }\r\n const p = payload as Record<string, unknown>;\r\n const raw = p.message ?? p.error ?? p.hint;\r\n let msg: string;\r\n if (typeof raw === \"string\") {\r\n msg = raw;\r\n } else if (typeof raw === \"number\" || typeof raw === \"boolean\") {\r\n msg = String(raw);\r\n } else if (raw !== null && raw !== undefined && typeof raw === \"object\") {\r\n msg = JSON.stringify(raw);\r\n } else {\r\n msg = st || `HTTP ${status}`;\r\n }\r\n msg = msg.trim();\r\n if (!msg) return st || `HTTP ${status}`;\r\n return msg;\r\n}\r\n\r\nasync function parsePostgRESTResponse<T>(response: Response): Promise<T> {\r\n if (response.status === 204 && response.ok) return null as T;\r\n\r\n const text = await response.text();\r\n\r\n // An error response with an EMPTY body (e.g. a bare 401/403/500/502 from an\r\n // upstream proxy) must still throw — otherwise it would resolve to\r\n // `{ data: null, error: null }`, indistinguishable from \"no rows\", and the\r\n // app would silently render empty data on an auth failure.\r\n if (!text) {\r\n if (!response.ok) {\r\n throw new RagableError(\r\n response.statusText || `HTTP ${response.status}`,\r\n response.status,\r\n null,\r\n );\r\n }\r\n return null as T;\r\n }\r\n\r\n let payload: unknown;\r\n try {\r\n payload = JSON.parse(text);\r\n } catch {\r\n if (!response.ok) {\r\n throw new RagableError(\r\n extractPostgRESTErrorMessage(text, response.status, response.statusText),\r\n response.status,\r\n null,\r\n );\r\n }\r\n throw new RagableError(\r\n `PostgREST response parse error: ${text.slice(0, 200)}`,\r\n response.status,\r\n null,\r\n );\r\n }\r\n\r\n if (!response.ok) {\r\n const msg = extractPostgRESTErrorMessage(payload, response.status, response.statusText);\r\n throw new RagableError(msg, response.status, payload);\r\n }\r\n\r\n return payload as T;\r\n}\r\n\r\n// ─── Shared filter mixin ─────────────────────────────────────────────────────\r\n\r\ntype FilterableBuilder<\r\n D extends RagableDatabase,\r\n T extends RagableTableNames<D>,\r\n Self,\r\n> = {\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): Self;\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): Self;\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): Self;\r\n match(query: Partial<TableRow<D, T>>): Self;\r\n};\r\n\r\nfunction addFilterMethods<\r\n D extends RagableDatabase,\r\n T extends RagableTableNames<D>,\r\n B extends { filters: Filter[] },\r\n>(builder: B): B & FilterableBuilder<D, T, B> {\r\n const b = builder as B & FilterableBuilder<D, T, B>;\r\n for (const op of [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\", \"like\", \"ilike\"] as const) {\r\n (b as Record<string, unknown>)[op] = function (column: string, value: unknown) {\r\n b.filters.push({ op, column, value });\r\n return b;\r\n };\r\n }\r\n (b as Record<string, unknown>).is = function (column: string, value: null | boolean) {\r\n b.filters.push({ op: \"is\", column, value });\r\n return b;\r\n };\r\n (b as Record<string, unknown>).in = function (column: string, values: unknown[]) {\r\n b.filters.push({ op: \"in\", column, value: values });\r\n return b;\r\n };\r\n (b as Record<string, unknown>).match = function (query: Record<string, unknown>) {\r\n for (const [col, val] of Object.entries(query)) {\r\n if (val === null) {\r\n b.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n b.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return b;\r\n };\r\n return b;\r\n}\r\n\r\n// ─── SELECT builder ──────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Chainable SELECT (PostgREST / Supabase-style). Filters and modifiers apply to the **base**\r\n * table of the query (the table passed to `client.from(...)`); the `select` string controls columns\r\n * and **resource embedding** (joins).\r\n *\r\n * **Joins** use the same embedded `select` syntax as\r\n * [Supabase `.select()`](https://supabase.com/docs/reference/javascript/select) / PostgREST, for example:\r\n * - `*,related_table(*)` — include related rows\r\n * - `related_table!inner(*)` — inner-style embed\r\n * - `related_table!fkey_column_or_constraint(*)` — disambiguate when multiple FKs exist\r\n * - `alias:related_table(*)` — rename the JSON key for the nested object/array\r\n *\r\n * **Ragable limits** (server-side): only **one level** of embedding is supported — no nested\r\n * `relation(nested(...))`. Prefer embed aliases above; top-level column rename forms like\r\n * `alias:column` may not be accepted for scalar columns.\r\n *\r\n * **API note:** Supabase’s second `select(columns, options?)` argument (`count`, `head`, etc.) is\r\n * not supported in Ragable yet; joins use the **first** argument only.\r\n *\r\n * For nested result shapes, pass a type argument on {@link PostgrestTableApi.select}:\r\n * `from('orders').select<OrderWithLines>(\\`*, lines (*)\\`)`.\r\n */\r\nexport class PostgrestSelectBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n D extends RagableDatabase = DefaultRagableDatabase,\r\n T extends RagableTableNames<D> = RagableTableNames<D>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n filters: Filter[] = [];\r\n private _limit?: number;\r\n private _offset?: number;\r\n private _order?: { column: string; ascending: boolean; nullsFirst?: boolean };\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly columns: string,\r\n ) {\r\n addFilterMethods<D, T, this>(this);\r\n }\r\n\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"eq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"neq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"like\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"ilike\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): this {\r\n this.filters.push({ op: \"is\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): this {\r\n this.filters.push({ op: \"in\", column: column as string, value: values });\r\n return this;\r\n }\r\n\r\n match(query: Partial<TableRow<D, T>>): this {\r\n for (const [col, val] of Object.entries(query as Record<string, unknown>)) {\r\n if (val === null) {\r\n this.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n this.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n limit(n: number): this {\r\n this._limit = n;\r\n return this;\r\n }\r\n\r\n offset(n: number): this {\r\n this._offset = n;\r\n return this;\r\n }\r\n\r\n range(from: number, to: number): this {\r\n this._offset = from;\r\n this._limit = to - from + 1;\r\n return this;\r\n }\r\n\r\n order(\r\n column: ColumnName<D, T>,\r\n options?: { ascending?: boolean; nullsFirst?: boolean },\r\n ): this {\r\n this._order = {\r\n column: column as string,\r\n ascending: options?.ascending !== false,\r\n nullsFirst: options?.nullsFirst,\r\n };\r\n return this;\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n private buildSearchParams(): URLSearchParams {\r\n const sp = new URLSearchParams();\r\n if (this.columns && this.columns !== \"*\") {\r\n sp.set(\"select\", this.columns);\r\n }\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n if (this._order) {\r\n let orderStr = `${this._order.column}.${this._order.ascending ? \"asc\" : \"desc\"}`;\r\n if (this._order.nullsFirst === true) orderStr += \".nullsfirst\";\r\n else if (this._order.nullsFirst === false) orderStr += \".nullslast\";\r\n sp.set(\"order\", orderStr);\r\n }\r\n if (this._limit != null) {\r\n sp.set(\"limit\", String(Math.max(0, Math.floor(this._limit))));\r\n }\r\n if (this._offset != null && this._offset > 0) {\r\n sp.set(\"offset\", String(Math.max(0, Math.floor(this._offset))));\r\n }\r\n return sp;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n const response = await this.pgFetch({\r\n method: \"GET\",\r\n table: this.table,\r\n searchParams: this.buildSearchParams(),\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n return asPostgrestResponse(async () => {\r\n const sp = this.buildSearchParams();\r\n const response = await this.pgFetch({\r\n method: \"GET\",\r\n table: this.table,\r\n searchParams: sp,\r\n headers: { Accept: \"application/vnd.pgrst.object+json\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n });\r\n return parsePostgRESTResponse<Row>(response);\r\n });\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── INSERT builders ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Awaitable `{ data: null, error }` chain when `.insert()` is called with invalid extra\r\n * arguments — matches Supabase-style result shapes without throwing.\r\n */\r\nexport class PostgrestInsertSdkErrorRoot<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n constructor(private readonly error: RagableError) {}\r\n\r\n select(_columns = \"*\"): PostgrestInsertSdkErrorReturning<Row> {\r\n return new PostgrestInsertSdkErrorReturning(this.error);\r\n }\r\n\r\n abortSignal(_signal: AbortSignal): this {\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return Promise.resolve({ data: null, error: this.error }).then(onfulfilled, onrejected);\r\n }\r\n}\r\n\r\nexport class PostgrestInsertSdkErrorReturning<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(private readonly error: RagableError) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return Promise.resolve({ data: null, error: this.error }).then(onfulfilled, onrejected);\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n return { data: null, error: this.error };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n return { data: null, error: this.error };\r\n }\r\n}\r\n\r\nexport class PostgrestInsertRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly rows: Record<string, unknown>[],\r\n ) {}\r\n\r\n select(columns = \"*\"): PostgrestInsertReturningBuilder<Row> {\r\n return new PostgrestInsertReturningBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n this.rows,\r\n columns,\r\n this._signal,\r\n );\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n if (this.rows.length === 0) return null;\r\n const body = this.rows.length === 1 ? this.rows[0] : this.rows;\r\n const response = await this.pgFetch({\r\n method: \"POST\",\r\n table: this.table,\r\n searchParams: new URLSearchParams(),\r\n body,\r\n headers: { Prefer: \"return=minimal\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n await parsePostgRESTResponse<null>(response);\r\n return null;\r\n });\r\n }\r\n}\r\n\r\nexport class PostgrestInsertReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly rows: Record<string, unknown>[],\r\n private readonly returning: string,\r\n private readonly _signal?: AbortSignal,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n if (this.rows.length === 0) return [];\r\n const body = this.rows.length === 1 ? this.rows[0] : this.rows;\r\n const sp = new URLSearchParams();\r\n if (this.returning && this.returning !== \"*\") {\r\n sp.set(\"select\", this.returning);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"POST\",\r\n table: this.table,\r\n searchParams: sp,\r\n body,\r\n headers: { Prefer: \"return=representation\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── UPDATE builders ─────────────────────────────────────────────────────────\r\n\r\nexport class PostgrestUpdateRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n D extends RagableDatabase = DefaultRagableDatabase,\r\n T extends RagableTableNames<D> = RagableTableNames<D>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n filters: Filter[] = [];\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly patch: Record<string, unknown>,\r\n ) {}\r\n\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"eq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"neq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"like\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"ilike\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): this {\r\n this.filters.push({ op: \"is\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): this {\r\n this.filters.push({ op: \"in\", column: column as string, value: values });\r\n return this;\r\n }\r\n\r\n match(query: Partial<TableRow<D, T>>): this {\r\n for (const [col, val] of Object.entries(query as Record<string, unknown>)) {\r\n if (val === null) {\r\n this.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n this.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n select(columns = \"*\"): PostgrestUpdateReturningBuilder<Row> {\r\n return new PostgrestUpdateReturningBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n this.patch,\r\n this.filters,\r\n columns,\r\n this._signal,\r\n );\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private buildSearchParams(): URLSearchParams {\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n return sp;\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n const keys = Object.keys(this.patch);\r\n if (keys.length === 0) {\r\n throw new RagableError(\"Empty update payload\", 400, null);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"PATCH\",\r\n table: this.table,\r\n searchParams: this.buildSearchParams(),\r\n body: this.patch,\r\n headers: { Prefer: \"return=minimal\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n await parsePostgRESTResponse<null>(response);\r\n return null;\r\n });\r\n }\r\n}\r\n\r\nexport class PostgrestUpdateReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly patch: Record<string, unknown>,\r\n private readonly filters: Filter[],\r\n private readonly returning: string,\r\n private readonly _signal?: AbortSignal,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n const keys = Object.keys(this.patch);\r\n if (keys.length === 0) {\r\n throw new RagableError(\"Empty update payload\", 400, null);\r\n }\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n if (this.returning && this.returning !== \"*\") {\r\n sp.set(\"select\", this.returning);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"PATCH\",\r\n table: this.table,\r\n searchParams: sp,\r\n body: this.patch,\r\n headers: { Prefer: \"return=representation\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── DELETE builders ─────────────────────────────────────────────────────────\r\n\r\nexport class PostgrestDeleteRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n D extends RagableDatabase = DefaultRagableDatabase,\r\n T extends RagableTableNames<D> = RagableTableNames<D>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n filters: Filter[] = [];\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n ) {}\r\n\r\n eq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"eq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n neq<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"neq\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n gte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"gte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lt<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lt\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n lte<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"lte\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n like<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"like\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n ilike<C extends ColumnName<D, T>>(column: C, value: ColumnValue<D, T, C>): this {\r\n this.filters.push({ op: \"ilike\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n is<C extends ColumnName<D, T>>(column: C, value: null | boolean): this {\r\n this.filters.push({ op: \"is\", column: column as string, value });\r\n return this;\r\n }\r\n\r\n in<C extends ColumnName<D, T>>(column: C, values: ColumnValue<D, T, C>[]): this {\r\n this.filters.push({ op: \"in\", column: column as string, value: values });\r\n return this;\r\n }\r\n\r\n match(query: Partial<TableRow<D, T>>): this {\r\n for (const [col, val] of Object.entries(query as Record<string, unknown>)) {\r\n if (val === null) {\r\n this.filters.push({ op: \"is\", column: col, value: null });\r\n } else {\r\n this.filters.push({ op: \"eq\", column: col, value: val });\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n select(columns = \"*\"): PostgrestDeleteReturningBuilder<Row> {\r\n return new PostgrestDeleteReturningBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n this.filters,\r\n columns,\r\n this._signal,\r\n );\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n const response = await this.pgFetch({\r\n method: \"DELETE\",\r\n table: this.table,\r\n searchParams: sp,\r\n headers: { Prefer: \"return=minimal\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n await parsePostgRESTResponse<null>(response);\r\n return null;\r\n });\r\n }\r\n}\r\n\r\nexport class PostgrestDeleteReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly filters: Filter[],\r\n private readonly returning: string,\r\n private readonly _signal?: AbortSignal,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n const sp = new URLSearchParams();\r\n for (const f of this.filters) {\r\n sp.append(f.column, encodeFilterValue(f.op, f.value));\r\n }\r\n if (this.returning && this.returning !== \"*\") {\r\n sp.set(\"select\", this.returning);\r\n }\r\n const response = await this.pgFetch({\r\n method: \"DELETE\",\r\n table: this.table,\r\n searchParams: sp,\r\n headers: { Prefer: \"return=representation\" },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n return parsePostgRESTResponse<Row[]>(response);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── UPSERT builders ─────────────────────────────────────────────────────────\r\n\r\nexport interface PostgrestUpsertOptions {\r\n onConflict: string;\r\n ignoreDuplicates?: boolean;\r\n}\r\n\r\nexport class PostgrestUpsertRootBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<null>>\r\n{\r\n private _signal?: AbortSignal;\r\n\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: string,\r\n private readonly rows: Record<string, unknown>[],\r\n private readonly onConflict: string,\r\n private readonly ignoreDuplicates: boolean,\r\n ) {}\r\n\r\n select(columns = \"*\"): PostgrestUpsertReturningBuilder<Row> {\r\n return new PostgrestUpsertReturningBuilder(this, columns);\r\n }\r\n\r\n abortSignal(signal: AbortSignal): this {\r\n this._signal = signal;\r\n return this;\r\n }\r\n\r\n then<TResult1 = PostgrestResult<null>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeNoReturn().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeNoReturn(): Promise<PostgrestResult<null>> {\r\n return asPostgrestResponse(async () => {\r\n await this.runUpsert(\"return=minimal\", null);\r\n return null;\r\n });\r\n }\r\n\r\n async runUpsert(\r\n prefer: string,\r\n selectCols: string | null,\r\n ): Promise<Row[]> {\r\n if (this.rows.length === 0) return [];\r\n\r\n const body = this.rows.length === 1 ? this.rows[0] : this.rows;\r\n const sp = new URLSearchParams();\r\n sp.set(\"on_conflict\", this.onConflict);\r\n if (selectCols && selectCols !== \"*\") {\r\n sp.set(\"select\", selectCols);\r\n }\r\n\r\n const resolution = this.ignoreDuplicates\r\n ? \"resolution=ignore-duplicates\"\r\n : \"resolution=merge-duplicates\";\r\n\r\n const response = await this.pgFetch({\r\n method: \"POST\",\r\n table: this.table,\r\n searchParams: sp,\r\n body,\r\n headers: { Prefer: `${prefer},${resolution}` },\r\n databaseInstanceId: this.databaseInstanceId,\r\n signal: this._signal,\r\n idempotencyKey: generateIdempotencyKey(),\r\n });\r\n\r\n if (prefer.includes(\"return=minimal\")) {\r\n await parsePostgRESTResponse<null>(response);\r\n return [];\r\n }\r\n\r\n return parsePostgRESTResponse<Row[]>(response);\r\n }\r\n}\r\n\r\nexport class PostgrestUpsertReturningBuilder<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> implements PromiseLike<PostgrestResult<Row[]>>\r\n{\r\n constructor(\r\n private readonly root: PostgrestUpsertRootBuilder<Row>,\r\n private readonly returning: string,\r\n ) {}\r\n\r\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\r\n onfulfilled?:\r\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\r\n | null,\r\n onrejected?:\r\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\r\n | null,\r\n ): Promise<TResult1 | TResult2> {\r\n return this.executeMany().then(onfulfilled, onrejected);\r\n }\r\n\r\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\r\n return asPostgrestResponse(async () => {\r\n return this.root.runUpsert(\"return=representation\", this.returning);\r\n });\r\n }\r\n\r\n async single(): Promise<PostgrestResult<Row>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length === 0 || rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0]!, error: null };\r\n }\r\n\r\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\r\n const many = await this.executeMany();\r\n if (many.error) return { data: null, error: many.error };\r\n const rows = many.data ?? [];\r\n if (rows.length > 1) {\r\n return {\r\n data: null,\r\n error: new RagableError(\r\n \"JSON object requested, multiple (or no) rows returned\",\r\n 406,\r\n { code: \"PGRST116\" },\r\n ),\r\n };\r\n }\r\n return { data: rows[0] ?? null, error: null };\r\n }\r\n}\r\n\r\n// ─── Table entry point ───────────────────────────────────────────────────────\r\n\r\nexport class PostgrestTableApi<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n TableName extends RagableTableNames<Database> = RagableTableNames<Database>,\r\n> {\r\n constructor(\r\n private readonly pgFetch: PostgRESTFetch,\r\n private readonly databaseInstanceId: string,\r\n private readonly table: TableName extends string ? string : string,\r\n ) {}\r\n\r\n /**\r\n * Start a SELECT. Pass a PostgREST `select` string; use embedded resources for joins — see\r\n * {@link PostgrestSelectBuilder}.\r\n *\r\n * @param columns Column list and optional embeds (default `\"*\"`). Omitted or `\"*\"` means all base columns.\r\n * @typeParam RowResult Row shape returned by the query; defaults to this table’s `Row`. Override when using joins.\r\n */\r\n select<\r\n RowResult extends Record<string, unknown> = TableRow<Database, TableName>,\r\n >(columns = \"*\"): PostgrestSelectBuilder<RowResult, Database, TableName> {\r\n return new PostgrestSelectBuilder<RowResult, Database, TableName>(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n columns,\r\n );\r\n }\r\n\r\n insert(\r\n values:\r\n | TableInsertRow<Database, TableName>\r\n | TableInsertRow<Database, TableName>[],\r\n ...rest: unknown[]\r\n ): PostgrestInsertRootBuilder<TableRow<Database, TableName>> {\r\n if (rest.length > 0) {\r\n const err = new RagableError(\r\n \".insert() accepts only one argument: the row object or an array of rows. \" +\r\n \"Do not pass readOnly, options, or a second object — those apply only to database.query({ sql, readOnly }). \" +\r\n \"PostgREST inserts are writes by default.\",\r\n 400,\r\n { code: \"SDK_INSERT_EXTRA_ARGS\" },\r\n );\r\n return new PostgrestInsertSdkErrorRoot<TableRow<Database, TableName>>(\r\n err,\r\n ) as unknown as PostgrestInsertRootBuilder<TableRow<Database, TableName>>;\r\n }\r\n const rows = (Array.isArray(values) ? values : [values]) as Record<\r\n string,\r\n unknown\r\n >[];\r\n return new PostgrestInsertRootBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n rows,\r\n );\r\n }\r\n\r\n update(\r\n patch: TableUpdatePatch<Database, TableName>,\r\n ): PostgrestUpdateRootBuilder<TableRow<Database, TableName>, Database, TableName> {\r\n return new PostgrestUpdateRootBuilder<TableRow<Database, TableName>, Database, TableName>(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n patch as Record<string, unknown>,\r\n );\r\n }\r\n\r\n delete(): PostgrestDeleteRootBuilder<TableRow<Database, TableName>, Database, TableName> {\r\n return new PostgrestDeleteRootBuilder<TableRow<Database, TableName>, Database, TableName>(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n );\r\n }\r\n\r\n upsert(\r\n values:\r\n | TableInsertRow<Database, TableName>\r\n | TableInsertRow<Database, TableName>[],\r\n options: PostgrestUpsertOptions,\r\n ): PostgrestUpsertRootBuilder<TableRow<Database, TableName>> {\r\n const rows = (Array.isArray(values) ? values : [values]) as Record<\r\n string,\r\n unknown\r\n >[];\r\n return new PostgrestUpsertRootBuilder(\r\n this.pgFetch,\r\n this.databaseInstanceId,\r\n this.table,\r\n rows,\r\n options.onConflict,\r\n options.ignoreDuplicates === true,\r\n );\r\n }\r\n}\r\n","// ─── SessionStorage interface ────────────────────────────────────────────────\n\nexport interface SessionStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\n// ─── Adapters ────────────────────────────────────────────────────────────────\n\nexport class LocalStorageAdapter implements SessionStorage {\n getItem(key: string): string | null {\n try {\n return globalThis.localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n setItem(key: string, value: string): void {\n try {\n globalThis.localStorage.setItem(key, value);\n } catch { /* quota exceeded or blocked — best effort */ }\n }\n\n removeItem(key: string): void {\n try {\n globalThis.localStorage.removeItem(key);\n } catch { /* noop */ }\n }\n}\n\nexport class SessionStorageAdapter implements SessionStorage {\n getItem(key: string): string | null {\n try {\n return globalThis.sessionStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n setItem(key: string, value: string): void {\n try {\n globalThis.sessionStorage.setItem(key, value);\n } catch { /* noop */ }\n }\n\n removeItem(key: string): void {\n try {\n globalThis.sessionStorage.removeItem(key);\n } catch { /* noop */ }\n }\n}\n\nexport class MemoryStorageAdapter implements SessionStorage {\n private store = new Map<string, string>();\n\n getItem(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n removeItem(key: string): void {\n this.store.delete(key);\n }\n}\n\nexport class CookieStorageAdapter implements SessionStorage {\n constructor(\n private readonly maxAge = 30 * 24 * 60 * 60,\n private readonly path = \"/\",\n private readonly sameSite: \"Lax\" | \"Strict\" | \"None\" = \"Lax\",\n ) {}\n\n getItem(key: string): string | null {\n if (typeof document === \"undefined\") return null;\n const match = document.cookie\n .split(\"; \")\n .find((c) => c.startsWith(`${encodeURIComponent(key)}=`));\n if (!match) return null;\n return decodeURIComponent(match.split(\"=\").slice(1).join(\"=\"));\n }\n\n setItem(key: string, value: string): void {\n if (typeof document === \"undefined\") return;\n const parts = [\n `${encodeURIComponent(key)}=${encodeURIComponent(value)}`,\n `path=${this.path}`,\n `max-age=${this.maxAge}`,\n `SameSite=${this.sameSite}`,\n ];\n if (this.sameSite === \"None\") parts.push(\"Secure\");\n document.cookie = parts.join(\"; \");\n }\n\n removeItem(key: string): void {\n if (typeof document === \"undefined\") return;\n document.cookie = `${encodeURIComponent(key)}=; path=${this.path}; max-age=0`;\n }\n}\n\n// ─── Default storage detection ───────────────────────────────────────────────\n\nexport function detectStorage(): SessionStorage {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.localStorage !== \"undefined\") {\n try {\n const testKey = \"__ragable_test__\";\n globalThis.localStorage.setItem(testKey, \"1\");\n globalThis.localStorage.removeItem(testKey);\n return new LocalStorageAdapter();\n } catch { /* blocked */ }\n }\n return new MemoryStorageAdapter();\n}\n\n// ─── BroadcastChannel helper ─────────────────────────────────────────────────\n\nexport type AuthBroadcastMessage =\n | { type: \"SESSION_UPDATED\"; payload: string }\n | { type: \"SESSION_REMOVED\" };\n\nexport class AuthBroadcastChannel {\n private channel: BroadcastChannel | null = null;\n\n constructor(channelName: string) {\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n this.channel = new BroadcastChannel(channelName);\n } catch { /* unsupported */ }\n }\n }\n\n onMessage(cb: (msg: AuthBroadcastMessage) => void): void {\n if (this.channel) {\n this.channel.onmessage = (e: MessageEvent) => {\n const data = e.data as AuthBroadcastMessage;\n if (data && typeof data.type === \"string\") {\n cb(data);\n }\n };\n }\n }\n\n postSessionUpdated(serialized: string): void {\n this.channel?.postMessage({ type: \"SESSION_UPDATED\", payload: serialized } satisfies AuthBroadcastMessage);\n }\n\n postSessionRemoved(): void {\n this.channel?.postMessage({ type: \"SESSION_REMOVED\" } satisfies AuthBroadcastMessage);\n }\n\n close(): void {\n this.channel?.close();\n this.channel = null;\n }\n}\n","import {\r\n bindFetch,\r\n DEFAULT_RAGABLE_API_BASE,\r\n extractErrorMessage,\r\n RagableError,\r\n} from \"./request-client\";\r\nimport type {\r\n SessionStorage,\r\n} from \"./auth-storage\";\r\nimport {\r\n AuthBroadcastChannel,\r\n detectStorage,\r\n} from \"./auth-storage\";\r\nimport {\r\n asPostgrestResponse,\r\n type PostgrestResult,\r\n} from \"./browser-postgrest\";\r\n\r\n// ─── Types ───────────────────────────────────────────────────────────────────\r\n\r\nexport type AuthChangeEvent =\r\n | \"INITIAL_SESSION\"\r\n | \"SIGNED_IN\"\r\n | \"SIGNED_OUT\"\r\n | \"TOKEN_REFRESHED\"\r\n | \"TOKEN_REFRESH_FAILED\"\r\n | \"USER_UPDATED\";\r\n\r\n/**\r\n * Outcome of a low-level refresh attempt. `terminal` distinguishes a definitively\r\n * rejected refresh token (the server said 400/401/403 — purge the session) from a\r\n * transient failure (offline, 5xx, timeout — keep the session and let a later call\r\n * recover it). Conflating the two is what silently logs users out on a flaky reload.\r\n */\r\ntype RefreshOutcome<U extends object> =\r\n | { ok: true; session: AuthSession<U> }\r\n | { ok: false; terminal: boolean; error: unknown };\r\n\r\n/** setTimeout clamps to a 32-bit signed int of milliseconds (~24.8 days); larger\r\n * delays fire immediately in browsers, which would hammer /refresh. */\r\nconst MAX_TIMEOUT_MS = 2 ** 31 - 1;\r\n\r\nexport type AuthUserMetadata = Record<string, unknown>;\r\n\r\nexport interface DefaultAuthUser<\r\n Metadata extends AuthUserMetadata = AuthUserMetadata,\r\n> {\r\n id: string;\r\n email: string;\r\n name: string | null;\r\n status: \"active\" | \"disabled\" | (string & {});\r\n metadata: Metadata;\r\n createdAt?: string;\r\n updatedAt?: string;\r\n lastSignInAt?: string | null;\r\n}\r\n\r\nexport interface AuthSession<\r\n U extends object = DefaultAuthUser,\r\n> {\r\n access_token: string;\r\n refresh_token: string;\r\n expires_in: number;\r\n expires_at: number;\r\n token_type: \"bearer\";\r\n user: U;\r\n}\r\n\r\nexport interface AuthOptions {\r\n persistSession?: boolean;\r\n autoRefreshToken?: boolean;\r\n storage?: SessionStorage;\r\n storageKey?: string;\r\n refreshSkewSeconds?: number;\r\n debug?: boolean;\r\n}\r\n\r\nexport interface RagableAuthConfig {\r\n authGroupId: string;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n auth?: AuthOptions;\r\n}\r\n\r\nexport type AuthSignUpCredentials<\r\n Metadata extends AuthUserMetadata = AuthUserMetadata,\r\n> = {\r\n email: string;\r\n password: string;\r\n options?: {\r\n data?: Partial<Metadata> & {\r\n name?: string | null;\r\n };\r\n };\r\n};\r\n\r\nexport type AuthUpdateUserAttributes<\r\n Metadata extends AuthUserMetadata = AuthUserMetadata,\r\n> = {\r\n email?: string;\r\n password?: string;\r\n data?: Partial<Metadata> & {\r\n name?: string | null;\r\n };\r\n};\r\n\r\ntype MetadataForUser<U extends object> = U extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Metadata\r\n : AuthUserMetadata\r\n : AuthUserMetadata;\r\n\r\ntype AuthListener<U extends object> = (\r\n event: AuthChangeEvent,\r\n session: AuthSession<U> | null,\r\n) => void;\r\n\r\ninterface Subscription {\r\n id: string;\r\n unsubscribe: () => void;\r\n}\r\n\r\n// ─── Helpers ─────────────────────────────────────────────────────────────────\r\n\r\nfunction parseExpiresInSeconds(raw: string | number): number {\r\n if (typeof raw === \"number\") return raw;\r\n const s = raw.trim().toLowerCase();\r\n const m = /^(\\d+)([smhd])?$/.exec(s);\r\n if (m) {\r\n const n = Number(m[1]);\r\n const u = m[2] ?? \"s\";\r\n const mult =\r\n u === \"s\" ? 1 : u === \"m\" ? 60 : u === \"h\" ? 3600 : u === \"d\" ? 86400 : 1;\r\n return n * mult;\r\n }\r\n const asNum = Number(s);\r\n return Number.isFinite(asNum) ? asNum : 0;\r\n}\r\n\r\nasync function parseJsonOrThrow<T>(response: Response): Promise<T> {\r\n const text = await response.text();\r\n let payload: unknown;\r\n try {\r\n payload = text ? JSON.parse(text) : null;\r\n } catch {\r\n throw new RagableError(`Response parse error: ${text.slice(0, 200)}`, response.status, null);\r\n }\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n}\r\n\r\nlet _subCounter = 0;\r\n\r\n// ─── RagableAuth ─────────────────────────────────────────────────────────────\r\n\r\nexport class RagableAuth<\r\n U extends object = DefaultAuthUser,\r\n> {\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly baseUrl: string;\r\n private readonly authGroupId: string;\r\n private readonly defaultHeaders: HeadersInit | undefined;\r\n private readonly persistSession: boolean;\r\n private readonly autoRefreshToken: boolean;\r\n private readonly storage: SessionStorage;\r\n private readonly storageKey: string;\r\n private readonly refreshSkewSeconds: number;\r\n private readonly debug: boolean;\r\n\r\n private currentSession: AuthSession<U> | null = null;\r\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\r\n private refreshPromise: Promise<AuthSession<U> | null> | null = null;\r\n private listeners = new Map<string, AuthListener<U>>();\r\n private broadcast: AuthBroadcastChannel | null = null;\r\n private visibilityHandler: (() => void) | null = null;\r\n /** Memoizes the one-shot restore so concurrent callers (constructor eager init,\r\n * every `onAuthStateChange` subscriber, `getSession`) share a single result.\r\n * Non-null also means \"restore has started\", replacing the old boolean flag. */\r\n private initializePromise: Promise<AuthSession<U> | null> | null = null;\r\n /** Bumped on every explicit session change (sign-in/out, refresh). The async\r\n * restore captures this and refuses to overwrite a newer session op that\r\n * landed while it was reading storage (e.g. a sign-out during page load). */\r\n private sessionEpoch = 0;\r\n\r\n constructor(config: RagableAuthConfig) {\r\n this.baseUrl = DEFAULT_RAGABLE_API_BASE.replace(/\\/+$/, \"\");\r\n this.authGroupId = config.authGroupId;\r\n this.fetchImpl = bindFetch(config.fetch);\r\n this.defaultHeaders = config.headers;\r\n\r\n const auth = config.auth ?? {};\r\n this.persistSession = auth.persistSession !== false;\r\n this.autoRefreshToken = auth.autoRefreshToken !== false;\r\n this.storage = auth.storage ?? detectStorage();\r\n this.storageKey = auth.storageKey ?? `ragable.session.${this.authGroupId}`;\r\n this.refreshSkewSeconds = auth.refreshSkewSeconds ?? 60;\r\n this.debug = auth.debug ?? false;\r\n\r\n this.broadcast = new AuthBroadcastChannel(`ragable-auth-${this.authGroupId}`);\r\n this.broadcast.onMessage((msg) => {\r\n if (msg.type === \"SESSION_UPDATED\") {\r\n try {\r\n const session = JSON.parse(msg.payload) as AuthSession<U>;\r\n this.currentSession = session;\r\n this.scheduleRefresh(session);\r\n this.emit(\"TOKEN_REFRESHED\", session);\r\n } catch { /* ignore bad data from other tab */ }\r\n } else if (msg.type === \"SESSION_REMOVED\") {\r\n this.currentSession = null;\r\n this.clearRefreshTimer();\r\n this.emit(\"SIGNED_OUT\", null);\r\n }\r\n });\r\n\r\n this.setupVisibilityListener();\r\n }\r\n\r\n private log(...args: unknown[]): void {\r\n if (this.debug) console.debug(\"[RagableAuth]\", ...args);\r\n }\r\n\r\n // ── Lifecycle ──────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Restore a persisted session (once). Memoized: every caller awaits the same\r\n * promise, so the eager constructor init, `getSession`, and each\r\n * `onAuthStateChange` subscriber's INITIAL_SESSION replay never race or\r\n * double-restore. Does NOT emit `INITIAL_SESSION` globally — that event is\r\n * delivered per-subscriber by `onAuthStateChange` (Supabase-parity), so a\r\n * listener attached after restore still sees the existing session.\r\n */\r\n initialize(): Promise<AuthSession<U> | null> {\r\n if (this.initializePromise) return this.initializePromise;\r\n this.initializePromise = this._initialize();\r\n return this.initializePromise;\r\n }\r\n\r\n private async _initialize(): Promise<AuthSession<U> | null> {\r\n if (!this.persistSession) return this.currentSession;\r\n const epoch = this.sessionEpoch;\r\n try {\r\n const raw = await this.storage.getItem(this.storageKey);\r\n if (!raw) return this.currentSession;\r\n // A sign-in/out/refresh landed while we were reading storage — that newer\r\n // state wins; do not clobber it with the just-read (now stale) session.\r\n if (this.sessionEpoch !== epoch) return this.currentSession;\r\n const session = JSON.parse(raw) as AuthSession<U>;\r\n const stillValid = !!session.expires_at && session.expires_at > nowSeconds();\r\n if (stillValid) {\r\n this.currentSession = session;\r\n this.scheduleRefresh(session);\r\n this.log(\"Restored session from storage\");\r\n } else if (session.refresh_token) {\r\n // Hold the stale session as context, then attempt a refresh. On a\r\n // TERMINAL failure (refresh token rejected) `singleFlightRefresh`\r\n // purges storage and emits SIGNED_OUT; on a TRANSIENT failure\r\n // (offline/5xx) it keeps the stored session so a later online call can\r\n // recover — we must NOT delete it here.\r\n this.currentSession = session;\r\n this.log(\"Stored session expired, attempting refresh\");\r\n const refreshed = await this.singleFlightRefresh(session.refresh_token);\r\n if (refreshed) this.currentSession = refreshed;\r\n } else {\r\n // Expired and unrefreshable — drop it.\r\n await this.storage.removeItem(this.storageKey);\r\n }\r\n } catch (e) {\r\n this.log(\"Failed to restore session\", e);\r\n }\r\n return this.currentSession;\r\n }\r\n\r\n // ── Auth methods ───────────────────────────────────────────────────────────\r\n\r\n async signUp(\r\n credentials: AuthSignUpCredentials<MetadataForUser<U>>,\r\n ): Promise<PostgrestResult<{ user: U; session: AuthSession<U> }>> {\r\n return asPostgrestResponse(async () => {\r\n const name =\r\n typeof credentials.options?.data?.name === \"string\"\r\n ? credentials.options.data.name\r\n : undefined;\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/register\", \"POST\", {\r\n email: credentials.email,\r\n password: credentials.password,\r\n ...(name !== undefined ? { name } : {}),\r\n ...(credentials.options?.data !== undefined\r\n ? { data: credentials.options.data }\r\n : {}),\r\n });\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return { user: session.user, session };\r\n });\r\n }\r\n\r\n async signInWithPassword(credentials: {\r\n email: string;\r\n password: string;\r\n }): Promise<PostgrestResult<{ user: U; session: AuthSession<U> }>> {\r\n return asPostgrestResponse(async () => {\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/login\", \"POST\", {\r\n email: credentials.email,\r\n password: credentials.password,\r\n });\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return { user: session.user, session };\r\n });\r\n }\r\n\r\n async signOut(_options?: { scope?: \"global\" | \"local\" }): Promise<{ error: null }> {\r\n this.sessionEpoch++;\r\n this.currentSession = null;\r\n this.clearRefreshTimer();\r\n if (this.persistSession) {\r\n await this.storage.removeItem(this.storageKey);\r\n }\r\n this.broadcast?.postSessionRemoved();\r\n this.emit(\"SIGNED_OUT\", null);\r\n return { error: null };\r\n }\r\n\r\n async refreshSession(\r\n refreshToken?: string,\r\n ): Promise<PostgrestResult<{ session: AuthSession<U>; user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n const token = refreshToken ?? this.currentSession?.refresh_token;\r\n if (!token) throw new RagableError(\"No refresh token available\", 401, null);\r\n const session = await this.singleFlightRefresh(token);\r\n if (!session) throw new RagableError(\"Refresh failed\", 401, null);\r\n return { session, user: session.user };\r\n });\r\n }\r\n\r\n async getSession(): Promise<PostgrestResult<{ session: AuthSession<U> | null }>> {\r\n await this.initialize();\r\n return { data: { session: this.currentSession }, error: null };\r\n }\r\n\r\n async getUser(): Promise<PostgrestResult<{ user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n // Restore a persisted session and refresh if near expiry before reading\r\n // /me, so a freshly-loaded page (or a long-lived tab) doesn't report\r\n // \"Not authenticated\" despite a valid stored session.\r\n const token = await this.getValidAccessToken();\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n return this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", token);\r\n });\r\n }\r\n\r\n async setSession(tokens: {\r\n access_token: string;\r\n refresh_token: string;\r\n }): Promise<PostgrestResult<{ session: AuthSession<U>; user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n const me = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", tokens.access_token);\r\n const decoded = decodeJwtExpiry(tokens.access_token);\r\n const expiresIn = decoded ? decoded - nowSeconds() : 3600;\r\n const session: AuthSession<U> = {\r\n access_token: tokens.access_token,\r\n refresh_token: tokens.refresh_token,\r\n expires_in: expiresIn,\r\n expires_at: nowSeconds() + expiresIn,\r\n token_type: \"bearer\",\r\n user: me.user,\r\n };\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return { session, user: me.user };\r\n });\r\n }\r\n\r\n async updateUser(attributes: {\r\n email?: string;\r\n password?: string;\r\n data?: (Partial<MetadataForUser<U>> & { name?: string | null });\r\n }): Promise<PostgrestResult<{ user: U }>> {\r\n return asPostgrestResponse(async () => {\r\n const token = this.currentSession?.access_token;\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n const result = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"PATCH\", token, {\r\n ...(attributes.email !== undefined ? { email: attributes.email } : {}),\r\n ...(attributes.password !== undefined ? { password: attributes.password } : {}),\r\n ...(attributes.data !== undefined ? { data: attributes.data } : {}),\r\n ...(attributes.data?.name !== undefined ? { name: attributes.data.name } : {}),\r\n });\r\n if (this.currentSession) {\r\n this.currentSession = { ...this.currentSession, user: result.user };\r\n await this.persistCurrentSession();\r\n }\r\n this.emit(\"USER_UPDATED\", this.currentSession);\r\n return result;\r\n });\r\n }\r\n\r\n // ── Event subscription ─────────────────────────────────────────────────────\r\n\r\n onAuthStateChange(\r\n callback: AuthListener<U>,\r\n ): { data: { subscription: Subscription } } {\r\n _subCounter++;\r\n const id = `sub-${_subCounter}`;\r\n this.listeners.set(id, callback);\r\n // Replay the restored session to THIS subscriber as INITIAL_SESSION once\r\n // restore completes (Supabase v2 parity). Without this, a listener attached\r\n // after page load — i.e. every React `useEffect` — never learns about the\r\n // session already sitting in storage, so apps render logged-out on reload.\r\n void this.initialize().then((session) => {\r\n const cb = this.listeners.get(id);\r\n if (!cb) return; // unsubscribed during restore\r\n try {\r\n cb(\"INITIAL_SESSION\", session);\r\n } catch (e) {\r\n this.log(\"Listener threw\", e);\r\n }\r\n });\r\n const unsubscribe = () => {\r\n this.listeners.delete(id);\r\n };\r\n return { data: { subscription: { id, unsubscribe } } };\r\n }\r\n\r\n // ── Accessors ──────────────────────────────────────────────────────────────\r\n\r\n getAccessToken(): string | null {\r\n return this.currentSession?.access_token ?? null;\r\n }\r\n\r\n /**\r\n * Returns an access token guaranteed fresh for at least `refreshSkewSeconds`,\r\n * refreshing (single-flight) if needed. Pass `force: true` to bypass the skew\r\n * check and refresh now — used by the transport's 401 handler so a token the\r\n * server rejected (key rotation, clock skew, early revocation) self-heals on\r\n * retry instead of failing the call.\r\n */\r\n async getValidAccessToken(force = false): Promise<string | null> {\r\n await this.initialize();\r\n const session = this.currentSession;\r\n if (!session) return null;\r\n const secondsUntilExpiry = session.expires_at - nowSeconds();\r\n if (force || secondsUntilExpiry <= this.refreshSkewSeconds) {\r\n const refreshed = await this.singleFlightRefresh(session.refresh_token);\r\n return refreshed?.access_token ?? null;\r\n }\r\n return session.access_token;\r\n }\r\n\r\n getCurrentSession(): AuthSession<U> | null {\r\n return this.currentSession;\r\n }\r\n\r\n // ── Back-compat: raw Ragable auth methods ──────────────────────────────────\r\n\r\n async register(body: {\r\n email: string;\r\n password: string;\r\n name?: string;\r\n data?: Partial<MetadataForUser<U>> & { name?: string | null };\r\n }): Promise<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }> {\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/register\", \"POST\", body);\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return raw;\r\n }\r\n\r\n async login(body: {\r\n email: string;\r\n password: string;\r\n }): Promise<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }> {\r\n const raw = await this.fetchAuth<{\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/login\", \"POST\", body);\r\n const session = this.rawToSession(raw);\r\n await this.setSessionInternal(session, \"SIGNED_IN\");\r\n return raw;\r\n }\r\n\r\n async refresh(body: { refreshToken: string }): Promise<{\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }> {\r\n return this.fetchAuth(\"/refresh\", \"POST\", body);\r\n }\r\n\r\n async getMe(): Promise<{ user: U }> {\r\n const token = this.currentSession?.access_token;\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n return this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", token);\r\n }\r\n\r\n async updateMe(body: {\r\n email?: string;\r\n name?: string | null;\r\n password?: string;\r\n data?: Partial<MetadataForUser<U>> & { name?: string | null };\r\n }): Promise<{ user: U }> {\r\n const token = this.currentSession?.access_token;\r\n if (!token) throw new RagableError(\"Not authenticated\", 401, null);\r\n const result = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"PATCH\", token, body);\r\n if (this.currentSession) {\r\n this.currentSession = { ...this.currentSession, user: result.user };\r\n await this.persistCurrentSession();\r\n }\r\n this.emit(\"USER_UPDATED\", this.currentSession);\r\n return result;\r\n }\r\n\r\n // ── Cleanup ────────────────────────────────────────────────────────────────\r\n\r\n destroy(): void {\r\n this.clearRefreshTimer();\r\n this.broadcast?.close();\r\n this.listeners.clear();\r\n if (this.visibilityHandler && typeof document !== \"undefined\") {\r\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\r\n }\r\n }\r\n\r\n // ─── Internal ──────────────────────────────────────────────────────────────\r\n\r\n private authPrefix(): string {\r\n return `/auth-groups/${this.authGroupId}/auth`;\r\n }\r\n\r\n private toUrl(path: string): string {\r\n return `${this.baseUrl}${this.authPrefix()}${path}`;\r\n }\r\n\r\n private baseHeaders(json: boolean): Headers {\r\n const h = new Headers(this.defaultHeaders);\r\n if (json) h.set(\"Content-Type\", \"application/json\");\r\n return h;\r\n }\r\n\r\n private async fetchAuth<T>(\r\n path: string,\r\n method: \"GET\" | \"POST\" | \"PATCH\",\r\n body?: unknown,\r\n ): Promise<T> {\r\n const headers = this.baseHeaders(body !== undefined);\r\n const response = await this.fetchImpl(this.toUrl(path), {\r\n method,\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n return parseJsonOrThrow<T>(response);\r\n }\r\n\r\n private async fetchAuthWithBearer<T>(\r\n path: string,\r\n method: \"GET\" | \"POST\" | \"PATCH\",\r\n token: string,\r\n body?: unknown,\r\n ): Promise<T> {\r\n const headers = this.baseHeaders(body !== undefined);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n const response = await this.fetchImpl(this.toUrl(path), {\r\n method,\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n return parseJsonOrThrow<T>(response);\r\n }\r\n\r\n private rawToSession(raw: {\r\n user: U;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }): AuthSession<U> {\r\n const expiresIn = parseExpiresInSeconds(raw.expiresIn);\r\n return {\r\n access_token: raw.accessToken,\r\n refresh_token: raw.refreshToken,\r\n expires_in: expiresIn,\r\n expires_at: nowSeconds() + expiresIn,\r\n token_type: \"bearer\",\r\n user: raw.user,\r\n };\r\n }\r\n\r\n private async setSessionInternal(\r\n session: AuthSession<U>,\r\n event: AuthChangeEvent,\r\n ): Promise<void> {\r\n this.sessionEpoch++;\r\n this.currentSession = session;\r\n await this.persistCurrentSession();\r\n this.broadcast?.postSessionUpdated(JSON.stringify(session));\r\n this.scheduleRefresh(session);\r\n this.emit(event, session);\r\n }\r\n\r\n private async persistCurrentSession(): Promise<void> {\r\n if (!this.persistSession || !this.currentSession) return;\r\n try {\r\n await this.storage.setItem(this.storageKey, JSON.stringify(this.currentSession));\r\n } catch (e) {\r\n this.log(\"Failed to persist session\", e);\r\n }\r\n }\r\n\r\n private emit(event: AuthChangeEvent, session: AuthSession<U> | null): void {\r\n this.log(event, session?.user);\r\n for (const cb of this.listeners.values()) {\r\n try {\r\n cb(event, session);\r\n } catch (e) {\r\n this.log(\"Listener threw\", e);\r\n }\r\n }\r\n }\r\n\r\n // ─── Refresh scheduling ────────────────────────────────────────────────────\r\n\r\n private scheduleRefresh(session: AuthSession<U>): void {\r\n this.clearRefreshTimer();\r\n if (!this.autoRefreshToken) return;\r\n const secondsUntilExpiry = session.expires_at - nowSeconds();\r\n const refreshIn = Math.max(0, secondsUntilExpiry - this.refreshSkewSeconds);\r\n // Clamp to setTimeout's 32-bit ceiling. A configured access-token lifetime\r\n // over ~24.8 days would otherwise overflow and fire instantly, looping.\r\n const delayMs = Math.min(refreshIn * 1000, MAX_TIMEOUT_MS);\r\n this.log(`Scheduling refresh in ${Math.round(delayMs / 1000)}s`);\r\n this.refreshTimer = setTimeout(() => {\r\n this.singleFlightRefresh(session.refresh_token).catch((e) => {\r\n this.log(\"Scheduled refresh failed\", e);\r\n });\r\n }, delayMs);\r\n }\r\n\r\n private clearRefreshTimer(): void {\r\n if (this.refreshTimer !== null) {\r\n clearTimeout(this.refreshTimer);\r\n this.refreshTimer = null;\r\n }\r\n }\r\n\r\n /**\r\n * Refresh the session, deduplicating concurrent callers onto one in-flight\r\n * request. Side effects (persisting the new session, or clearing it and\r\n * emitting SIGNED_OUT / TOKEN_REFRESH_FAILED) run exactly once inside the\r\n * shared promise, so two callers can't double-emit. Resolves to the new\r\n * session, or `null` when the refresh failed.\r\n */\r\n async singleFlightRefresh(refreshToken: string): Promise<AuthSession<U> | null> {\r\n if (this.refreshPromise) return this.refreshPromise;\r\n this.refreshPromise = (async () => {\r\n const outcome = await this._doRefresh(refreshToken);\r\n if (outcome.ok) return outcome.session;\r\n if (outcome.terminal) {\r\n // Refresh token is permanently invalid — purge and notify so the app\r\n // can route to sign-in.\r\n await this.handleTerminalRefreshFailure();\r\n } else {\r\n // Transient (offline / 5xx / timeout): keep the persisted session for a\r\n // later recovery, but signal the failure so UIs can surface \"reconnecting\".\r\n this.emit(\"TOKEN_REFRESH_FAILED\", this.currentSession);\r\n }\r\n return null;\r\n })().finally(() => {\r\n this.refreshPromise = null;\r\n });\r\n return this.refreshPromise;\r\n }\r\n\r\n /** Clear the session locally and emit SIGNED_OUT after a definitively-rejected\r\n * refresh, so onAuthStateChange-driven UI redirects to login. */\r\n private async handleTerminalRefreshFailure(): Promise<void> {\r\n this.sessionEpoch++;\r\n this.currentSession = null;\r\n this.clearRefreshTimer();\r\n if (this.persistSession) {\r\n try {\r\n await this.storage.removeItem(this.storageKey);\r\n } catch (e) {\r\n this.log(\"Failed to clear session after terminal refresh failure\", e);\r\n }\r\n }\r\n this.broadcast?.postSessionRemoved();\r\n this.emit(\"TOKEN_REFRESH_FAILED\", null);\r\n this.emit(\"SIGNED_OUT\", null);\r\n }\r\n\r\n private async _doRefresh(refreshToken: string): Promise<RefreshOutcome<U>> {\r\n let raw: { accessToken: string; refreshToken: string; expiresIn: string };\r\n try {\r\n raw = await this.fetchAuth<{\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n }>(\"/refresh\", \"POST\", { refreshToken });\r\n } catch (e) {\r\n // Only a 4xx from /refresh means the token itself is rejected. Network\r\n // errors, timeouts, and 5xx are transient — keep the session.\r\n const status = e instanceof RagableError ? e.status : 0;\r\n const terminal = status === 400 || status === 401 || status === 403;\r\n this.log(\"Refresh request failed\", { status, terminal });\r\n return { ok: false, terminal, error: e };\r\n }\r\n try {\r\n const me = await this.fetchAuthWithBearer<{ user: U }>(\"/me\", \"GET\", raw.accessToken);\r\n const expiresIn = parseExpiresInSeconds(raw.expiresIn);\r\n const session: AuthSession<U> = {\r\n access_token: raw.accessToken,\r\n refresh_token: raw.refreshToken,\r\n expires_in: expiresIn,\r\n expires_at: nowSeconds() + expiresIn,\r\n token_type: \"bearer\",\r\n user: me.user,\r\n };\r\n await this.setSessionInternal(session, \"TOKEN_REFRESHED\");\r\n return { ok: true, session };\r\n } catch (e) {\r\n // We obtained new tokens but the follow-up /me failed. Treat as transient\r\n // (don't purge a freshly-minted session over a hydration hiccup).\r\n this.log(\"Post-refresh /me failed\", e);\r\n return { ok: false, terminal: false, error: e };\r\n }\r\n }\r\n\r\n // ─── Visibility listener ───────────────────────────────────────────────────\r\n\r\n private setupVisibilityListener(): void {\r\n if (typeof document === \"undefined\") return;\r\n this.visibilityHandler = () => {\r\n if (document.visibilityState === \"visible\" && this.currentSession) {\r\n const secondsUntilExpiry = this.currentSession.expires_at - nowSeconds();\r\n if (secondsUntilExpiry <= this.refreshSkewSeconds) {\r\n this.singleFlightRefresh(this.currentSession.refresh_token).catch(() => {});\r\n } else {\r\n this.scheduleRefresh(this.currentSession);\r\n }\r\n } else {\r\n this.clearRefreshTimer();\r\n }\r\n };\r\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\r\n }\r\n}\r\n\r\nfunction nowSeconds(): number {\r\n return Math.floor(Date.now() / 1000);\r\n}\r\n\r\nfunction decodeJwtExpiry(jwt: string): number | null {\r\n try {\r\n const parts = jwt.split(\".\");\r\n if (parts.length !== 3) return null;\r\n const payload = JSON.parse(atob(parts[1]!.replace(/-/g, \"+\").replace(/_/g, \"/\")));\r\n return typeof payload.exp === \"number\" ? payload.exp : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n","/**\n * Best-effort parser for incomplete JSON streamed token-by-token from an LLM.\n *\n * Used by `streamObject` to emit partial objects as the model writes them.\n * Strategy:\n * 1. Try `JSON.parse(text)` — if it works, the JSON is already complete.\n * 2. Otherwise scan the text and close any open `{`, `[`, or string literal\n * so the result is parseable.\n * 3. If a trailing comma is the problem, strip it and retry.\n *\n * Returns `undefined` when no parseable prefix can be recovered.\n *\n * Designed to be allocation-light and dep-free.\n */\nexport function tryParsePartialJson(text: string): unknown | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n\n // Direct parse — fast path when the model already produced complete JSON.\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n // fall through to repair\n }\n\n const repaired = repairOpenStructures(trimmed);\n if (!repaired) return undefined;\n\n try {\n return JSON.parse(repaired) as unknown;\n } catch {\n // Strip a trailing comma inside the last open container and retry.\n const noTrailingComma = stripTrailingCommas(trimmed);\n const repaired2 = repairOpenStructures(noTrailingComma);\n if (!repaired2) return undefined;\n try {\n return JSON.parse(repaired2) as unknown;\n } catch {\n return undefined;\n }\n }\n}\n\n/**\n * Close any open `{`, `[`, or string literal in `text` so the result is\n * syntactically valid JSON. Returns `null` if the input doesn't begin with\n * a JSON-ish character (so we don't pretend \"Hello\" is recoverable).\n */\nfunction repairOpenStructures(text: string): string | null {\n const first = text[0];\n if (first !== \"{\" && first !== \"[\") {\n // Allow primitive top-level values (number, \"string\", true/false/null).\n return text;\n }\n\n const stack: Array<\"}\" | \"]\"> = [];\n let inString = false;\n let escaped = false;\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (ch === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (ch === '\"') {\n inString = !inString;\n continue;\n }\n if (inString) continue;\n if (ch === \"{\") stack.push(\"}\");\n else if (ch === \"[\") stack.push(\"]\");\n else if (ch === \"}\" || ch === \"]\") {\n if (stack.length === 0) return null; // mismatched close\n stack.pop();\n }\n }\n\n // If we're mid-key/value, we usually have a dangling `\"key\":` or `\"key\": <partial>`.\n // Trim back to the last position that's safe to close.\n let safe = text;\n if (inString) {\n safe += '\"'; // close the open string first\n }\n // Drop a dangling colon or trailing comma so the structure parses.\n safe = safe.replace(/,\\s*$/, \"\").replace(/:\\s*$/, ': null');\n\n // Append closing brackets in reverse stack order.\n let suffix = \"\";\n for (let i = stack.length - 1; i >= 0; i--) suffix += stack[i];\n return safe + suffix;\n}\n\nfunction stripTrailingCommas(text: string): string {\n return text.replace(/,(\\s*[}\\]])/g, \"$1\").replace(/,\\s*$/, \"\");\n}\n","/**\r\n * Vercel AI SDK–style stream part types, used by both `client.ai.streamText`\r\n * (Fireworks chunks via the Ragable proxy) and `client.agents.run` (existing\r\n * agent SSE events). Keep this module zero-dep so it can be re-exported from\r\n * the SDK entrypoint without dragging in agent/browser code.\r\n */\r\n\r\nexport type FinishReason =\r\n | \"stop\"\r\n | \"length\"\r\n | \"tool-calls\"\r\n | \"content-filter\"\r\n | \"error\"\r\n | \"unknown\";\r\n\r\nexport interface TokenUsage {\r\n promptTokens: number;\r\n completionTokens: number;\r\n totalTokens: number;\r\n /** Prompt-cache read tokens reported by the upstream provider, when available. */\r\n cachedPromptTokens?: number;\r\n}\r\n\r\nexport type StreamPart =\r\n | { type: \"text-delta\"; textDelta: string }\r\n | { type: \"reasoning\"; textDelta: string }\r\n | {\r\n type: \"tool-call\";\r\n toolCallId: string;\r\n toolName: string;\r\n args: unknown;\r\n }\r\n | {\r\n type: \"tool-result\";\r\n toolCallId: string;\r\n toolName: string;\r\n result: unknown;\r\n durationMs?: number;\r\n }\r\n | { type: \"finish\"; finishReason: FinishReason; usage: TokenUsage }\r\n | { type: \"error\"; error: unknown };\r\n\r\nexport interface Message {\r\n role: \"system\" | \"user\" | \"assistant\";\r\n content: string;\r\n}\r\n\r\n/**\r\n * OpenAI/Fireworks SSE chunk shape, only the fields we actually consume.\r\n * Kept as a local type so we don't depend on backend internals.\r\n */\r\nexport interface OpenAiStreamChunk {\r\n choices?: Array<{\r\n delta?: {\r\n content?: string | null;\r\n reasoning_content?: string | null;\r\n reasoning?: string | null;\r\n tool_calls?: Array<{\r\n index?: number;\r\n id?: string | null;\r\n type?: string;\r\n function?: { name?: string | null; arguments?: string | null };\r\n }>;\r\n };\r\n finish_reason?: string | null;\r\n }>;\r\n usage?: {\r\n prompt_tokens?: number;\r\n completion_tokens?: number;\r\n total_tokens?: number;\r\n prompt_tokens_details?: { cached_tokens?: number };\r\n cache_read_input_tokens?: number;\r\n };\r\n error?: { code?: number; message?: string };\r\n}\r\n\r\nfunction normalizeFinishReason(raw: string | null | undefined): FinishReason {\r\n switch (raw) {\r\n case \"stop\":\r\n case \"length\":\r\n case \"content-filter\":\r\n case \"error\":\r\n return raw;\r\n case \"tool_calls\":\r\n return \"tool-calls\";\r\n case null:\r\n case undefined:\r\n case \"\":\r\n return \"unknown\";\r\n default:\r\n return \"unknown\";\r\n }\r\n}\r\n\r\nfunction chunkUsage(chunk: OpenAiStreamChunk): TokenUsage {\r\n const u = chunk.usage ?? {};\r\n const cached =\r\n u.prompt_tokens_details?.cached_tokens ?? u.cache_read_input_tokens;\r\n return {\r\n promptTokens: typeof u.prompt_tokens === \"number\" ? u.prompt_tokens : 0,\r\n completionTokens:\r\n typeof u.completion_tokens === \"number\" ? u.completion_tokens : 0,\r\n totalTokens: typeof u.total_tokens === \"number\" ? u.total_tokens : 0,\r\n ...(typeof cached === \"number\" ? { cachedPromptTokens: cached } : {}),\r\n };\r\n}\r\n\r\n/**\r\n * Accumulator for partial tool-call function arguments streamed across\r\n * multiple chunks (Fireworks streams the `arguments` JSON token-by-token).\r\n */\r\nexport interface ToolCallAccumulator {\r\n byIndex: Map<\r\n number,\r\n { id: string; name: string; argsBuffer: string; emitted: boolean }\r\n >;\r\n}\r\n\r\nexport function createToolCallAccumulator(): ToolCallAccumulator {\r\n return { byIndex: new Map() };\r\n}\r\n\r\nfunction parseJsonOrRaw(raw: string): unknown {\r\n try {\r\n return JSON.parse(raw);\r\n } catch {\r\n return raw;\r\n }\r\n}\r\n\r\n/**\r\n * Map a single Fireworks/OpenAI chunk into zero or more StreamParts.\r\n * Tool calls are buffered until their `arguments` JSON is parseable, then\r\n * emitted as a single `tool-call` part — same convention as Vercel AI SDK.\r\n */\r\nexport function mapFireworksChunk(\r\n chunk: OpenAiStreamChunk,\r\n acc: ToolCallAccumulator,\r\n): StreamPart[] {\r\n const out: StreamPart[] = [];\r\n\r\n if (chunk.error?.message) {\r\n out.push({ type: \"error\", error: chunk.error.message });\r\n return out;\r\n }\r\n\r\n const choice = chunk.choices?.[0];\r\n const delta = choice?.delta;\r\n\r\n if (delta?.content) {\r\n out.push({ type: \"text-delta\", textDelta: delta.content });\r\n }\r\n\r\n const reasoning = delta?.reasoning_content ?? delta?.reasoning;\r\n if (typeof reasoning === \"string\" && reasoning.length > 0) {\r\n out.push({ type: \"reasoning\", textDelta: reasoning });\r\n }\r\n\r\n if (Array.isArray(delta?.tool_calls)) {\r\n for (const tc of delta.tool_calls) {\r\n const idx = typeof tc.index === \"number\" ? tc.index : 0;\r\n let entry = acc.byIndex.get(idx);\r\n if (!entry) {\r\n entry = { id: \"\", name: \"\", argsBuffer: \"\", emitted: false };\r\n acc.byIndex.set(idx, entry);\r\n }\r\n if (tc.id) entry.id = tc.id;\r\n if (tc.function?.name) entry.name = tc.function.name;\r\n if (typeof tc.function?.arguments === \"string\") {\r\n entry.argsBuffer += tc.function.arguments;\r\n }\r\n }\r\n }\r\n\r\n if (choice?.finish_reason) {\r\n // Flush any remaining tool calls whose args weren't a closing brace mid-stream.\r\n for (const entry of acc.byIndex.values()) {\r\n if (entry.emitted || !entry.name) continue;\r\n entry.emitted = true;\r\n out.push({\r\n type: \"tool-call\",\r\n toolCallId: entry.id || `call_${entry.name}_${Date.now()}`,\r\n toolName: entry.name,\r\n args: entry.argsBuffer ? parseJsonOrRaw(entry.argsBuffer) : {},\r\n });\r\n }\r\n out.push({\r\n type: \"finish\",\r\n finishReason: normalizeFinishReason(choice.finish_reason),\r\n usage: chunkUsage(chunk),\r\n });\r\n } else if (chunk.usage) {\r\n // Some providers emit usage in a trailing chunk without finish_reason.\r\n out.push({\r\n type: \"finish\",\r\n finishReason: \"unknown\",\r\n usage: chunkUsage(chunk),\r\n });\r\n }\r\n\r\n return out;\r\n}\r\n\r\n/**\r\n * Minimal shape of an `AgentStreamEvent` from `agent-stream.ts`. Inlined to\r\n * keep this module zero-import.\r\n */\r\nexport interface AgentStreamLikeEvent {\r\n type: string;\r\n [k: string]: unknown;\r\n}\r\n\r\nfunction asStr(v: unknown, fallback = \"\"): string {\r\n return typeof v === \"string\" ? v : fallback;\r\n}\r\n\r\nfunction asNum(v: unknown, fallback = 0): number {\r\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\r\n}\r\n\r\n/**\r\n * Map an existing agent SSE event (`token`, `reasoning_token`, `tool:call`,\r\n * `tool:result`, `done`) into a StreamPart, or `null` for events that don't\r\n * map (`ping`, `agent:info`, `node:*`).\r\n */\r\nexport function mapAgentEvent(event: AgentStreamLikeEvent): StreamPart | null {\r\n switch (event.type) {\r\n case \"token\":\r\n return { type: \"text-delta\", textDelta: asStr(event.token) };\r\n case \"reasoning_token\":\r\n return { type: \"reasoning\", textDelta: asStr(event.token) };\r\n case \"tool:call\":\r\n return {\r\n type: \"tool-call\",\r\n toolCallId: asStr(event.nodeId),\r\n toolName: asStr(event.toolName),\r\n args: event.args,\r\n };\r\n case \"tool:result\":\r\n return {\r\n type: \"tool-result\",\r\n toolCallId: asStr(event.nodeId),\r\n toolName: asStr(event.toolName),\r\n result: event.result,\r\n ...(typeof event.durationMs === \"number\"\r\n ? { durationMs: event.durationMs }\r\n : {}),\r\n };\r\n case \"done\": {\r\n const usage: TokenUsage = {\r\n promptTokens: asNum(event.inputTokens),\r\n completionTokens: asNum(event.outputTokens),\r\n totalTokens: asNum(event.inputTokens) + asNum(event.outputTokens),\r\n ...(typeof event.cachedPromptTokens === \"number\"\r\n ? { cachedPromptTokens: event.cachedPromptTokens }\r\n : {}),\r\n };\r\n return {\r\n type: \"finish\",\r\n finishReason: normalizeFinishReason(\r\n asStr(event.finishReason) || asStr(event.stopReason) || null,\r\n ),\r\n usage,\r\n };\r\n }\r\n default:\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Vercel AI SDK–style raw inference for `@ragable/sdk`. Routes through the\r\n * Ragable backend's Fireworks proxy\r\n * (`POST /public/organizations/:id/websites/:websiteId/inference/stream`)\r\n * so callers don't need a provider API key and credit usage is tracked\r\n * against the website's organization.\r\n */\r\n\r\nimport { bindFetch, extractErrorMessage, RagableError } from \"./request-client\";\r\nimport { tryParsePartialJson } from \"./partial-json\";\r\nimport { parseMaybeJsonBody, parseSseDataLine } from \"./sse\";\r\nimport {\r\n createToolCallAccumulator,\r\n mapFireworksChunk,\r\n type FinishReason,\r\n type Message,\r\n type OpenAiStreamChunk,\r\n type StreamPart,\r\n type TokenUsage,\r\n type ToolCallAccumulator,\r\n} from \"./stream-parts\";\r\n\r\n/** JSON Schema for a structured response. Plain object — no Zod dep. */\r\nexport type JsonSchema = Record<string, unknown>;\r\n\r\nexport interface StreamTextParams {\r\n model: string;\r\n messages: Message[];\r\n system?: string;\r\n temperature?: number;\r\n maxTokens?: number;\r\n topP?: number;\r\n reasoningEffort?: \"none\" | \"low\" | \"medium\" | \"high\";\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface ToolCallRecord {\r\n toolCallId: string;\r\n toolName: string;\r\n args: unknown;\r\n}\r\n\r\nexport interface StreamTextResult {\r\n /** Stream of text deltas only. Same content as `fullStream.filter(p => p.type === \"text-delta\")`. */\r\n textStream: AsyncIterable<string>;\r\n /** Full event stream — text deltas, reasoning, tool calls, finish, error. */\r\n fullStream: AsyncIterable<StreamPart>;\r\n /** Resolves to the concatenation of all `text-delta` parts once the stream finishes. */\r\n text: Promise<string>;\r\n /** Resolves to the concatenation of all `reasoning` parts. */\r\n reasoning: Promise<string>;\r\n /** Resolves to token usage from the final chunk (zeros if not reported). */\r\n usage: Promise<TokenUsage>;\r\n /** Resolves to the upstream finish reason. */\r\n finishReason: Promise<FinishReason>;\r\n /** Resolves to the list of tool calls extracted from this turn. */\r\n toolCalls: Promise<ToolCallRecord[]>;\r\n}\r\n\r\nexport interface GenerateTextResult {\r\n text: string;\r\n reasoning: string;\r\n usage: TokenUsage;\r\n finishReason: FinishReason;\r\n toolCalls: ToolCallRecord[];\r\n}\r\n\r\nexport interface StreamObjectParams {\r\n model: string;\r\n /**\r\n * JSON Schema describing the expected output. Constrains the model via the\r\n * Fireworks `response_format: { type: \"json_object\", schema }` mode.\r\n */\r\n schema: JsonSchema;\r\n /** Optional name for the schema (passed through to providers that support it). */\r\n schemaName?: string;\r\n /** Optional natural-language description of the schema. */\r\n schemaDescription?: string;\r\n messages: Message[];\r\n system?: string;\r\n temperature?: number;\r\n maxTokens?: number;\r\n topP?: number;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface StreamObjectResult<T = unknown> {\r\n /** Raw text deltas — the JSON string as it streams in. */\r\n textStream: AsyncIterable<string>;\r\n /**\r\n * Async iterable of best-effort parsed partial objects. Emits whenever the\r\n * accumulated JSON parses cleanly under the partial-JSON repair rules.\r\n * Subsequent values are *replacements*, not patches — each is a snapshot.\r\n */\r\n partialObjectStream: AsyncIterable<T>;\r\n /** Resolves to the final parsed object once the stream ends. Rejects if the final JSON is invalid. */\r\n object: Promise<T>;\r\n /** Resolves to the raw JSON string the model produced. */\r\n text: Promise<string>;\r\n usage: Promise<TokenUsage>;\r\n finishReason: Promise<FinishReason>;\r\n /**\r\n * Resolves to tool calls the model made during this turn.\r\n * Empty for `client.ai.streamObject` (no tools exposed on raw inference);\r\n * populated for `client.agents.runObject` when the agent has tools.\r\n */\r\n toolCalls: Promise<ToolCallRecord[]>;\r\n}\r\n\r\nexport interface GenerateObjectResult<T = unknown> {\r\n object: T;\r\n usage: TokenUsage;\r\n finishReason: FinishReason;\r\n toolCalls: ToolCallRecord[];\r\n}\r\n\r\ninterface ResolvedPart {\r\n parts: StreamPart[];\r\n resolved: boolean;\r\n error: unknown;\r\n waiters: Array<() => void>;\r\n}\r\n\r\nclass PartBroadcast {\r\n private state: ResolvedPart = {\r\n parts: [],\r\n resolved: false,\r\n error: null,\r\n waiters: [],\r\n };\r\n\r\n push(part: StreamPart): void {\r\n this.state.parts.push(part);\r\n this.notify();\r\n }\r\n\r\n end(): void {\r\n if (this.state.resolved) return;\r\n this.state.resolved = true;\r\n this.notify();\r\n }\r\n\r\n fail(error: unknown): void {\r\n if (this.state.resolved) return;\r\n this.state.error = error;\r\n this.state.resolved = true;\r\n this.notify();\r\n }\r\n\r\n private notify(): void {\r\n const waiters = this.state.waiters;\r\n this.state.waiters = [];\r\n for (const w of waiters) w();\r\n }\r\n\r\n consume(): AsyncIterable<StreamPart> {\r\n const state = this.state;\r\n return {\r\n [Symbol.asyncIterator]: (): AsyncIterator<StreamPart> => {\r\n let idx = 0;\r\n return {\r\n next: async (): Promise<IteratorResult<StreamPart>> => {\r\n while (true) {\r\n if (idx < state.parts.length) {\r\n return { value: state.parts[idx++]!, done: false };\r\n }\r\n if (state.resolved) {\r\n if (state.error) throw state.error;\r\n return { value: undefined as unknown as StreamPart, done: true };\r\n }\r\n await new Promise<void>((resolve) => {\r\n state.waiters.push(resolve);\r\n });\r\n }\r\n },\r\n };\r\n },\r\n };\r\n }\r\n}\r\n\r\ninterface DeferredPromise<T> {\r\n promise: Promise<T>;\r\n resolve: (value: T) => void;\r\n reject: (reason: unknown) => void;\r\n}\r\n\r\nfunction defer<T>(): DeferredPromise<T> {\r\n let resolve!: (value: T) => void;\r\n let reject!: (reason: unknown) => void;\r\n const promise = new Promise<T>((res, rej) => {\r\n resolve = res;\r\n reject = rej;\r\n });\r\n return { promise, resolve, reject };\r\n}\r\n\r\nconst ZERO_USAGE: TokenUsage = {\r\n promptTokens: 0,\r\n completionTokens: 0,\r\n totalTokens: 0,\r\n};\r\n\r\n/**\r\n * Build the JSON body for the inference proxy. Public so tests can assert it.\r\n * Accepts an optional `responseFormat` so the same builder serves both\r\n * `streamText` and `streamObject`.\r\n */\r\nexport function buildInferenceRequestBody(\r\n params: StreamTextParams,\r\n responseFormat?: Record<string, unknown>,\r\n): Record<string, unknown> {\r\n const body: Record<string, unknown> = {\r\n model: params.model,\r\n messages: params.messages,\r\n };\r\n if (params.system !== undefined) body.system = params.system;\r\n if (typeof params.temperature === \"number\")\r\n body.temperature = params.temperature;\r\n if (typeof params.maxTokens === \"number\") body.max_tokens = params.maxTokens;\r\n if (typeof params.topP === \"number\") body.top_p = params.topP;\r\n if (params.reasoningEffort) body.reasoning_effort = params.reasoningEffort;\r\n if (responseFormat) body.response_format = responseFormat;\r\n return body;\r\n}\r\n\r\n/**\r\n * Build the `response_format` payload for a JSON-Schema-constrained call.\r\n * Emits Fireworks' canonical shape (also accepted by OpenAI):\r\n *\r\n * { type: \"json_schema\",\r\n * json_schema: { name, schema, description?, strict? } }\r\n *\r\n * @see https://docs.fireworks.ai/structured-responses/structured-response-formatting\r\n */\r\nexport function buildResponseFormat(params: {\r\n schema: JsonSchema;\r\n name?: string;\r\n description?: string;\r\n /** Default `true` — providers ignore unknown fields safely. */\r\n strict?: boolean;\r\n}): Record<string, unknown> {\r\n const json_schema: Record<string, unknown> = {\r\n name: params.name ?? \"Output\",\r\n schema: params.schema,\r\n strict: params.strict ?? true,\r\n };\r\n if (params.description) json_schema.description = params.description;\r\n return { type: \"json_schema\", json_schema };\r\n}\r\n\r\n/**\r\n * Consume a Fireworks-shaped SSE body and push StreamParts onto `broadcast`.\r\n * Resolves the deferred result promises when the stream ends or errors.\r\n */\r\nasync function consumeInferenceStream(\r\n body: ReadableStream<Uint8Array>,\r\n broadcast: PartBroadcast,\r\n deferreds: {\r\n text: DeferredPromise<string>;\r\n reasoning: DeferredPromise<string>;\r\n usage: DeferredPromise<TokenUsage>;\r\n finishReason: DeferredPromise<FinishReason>;\r\n toolCalls: DeferredPromise<ToolCallRecord[]>;\r\n },\r\n): Promise<void> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n const acc: ToolCallAccumulator = createToolCallAccumulator();\r\n\r\n let textBuffer = \"\";\r\n let reasoningBuffer = \"\";\r\n let lastUsage: TokenUsage = ZERO_USAGE;\r\n let lastFinish: FinishReason = \"unknown\";\r\n const toolCallsArr: ToolCallRecord[] = [];\r\n let buffer = \"\";\r\n\r\n const dispatch = (rawLine: string): void => {\r\n const parsed = parseSseDataLine(rawLine);\r\n if (!parsed) return;\r\n const chunk = parsed as unknown as OpenAiStreamChunk;\r\n const parts = mapFireworksChunk(chunk, acc);\r\n for (const part of parts) {\r\n if (part.type === \"text-delta\") textBuffer += part.textDelta;\r\n else if (part.type === \"reasoning\") reasoningBuffer += part.textDelta;\r\n else if (part.type === \"tool-call\") {\r\n toolCallsArr.push({\r\n toolCallId: part.toolCallId,\r\n toolName: part.toolName,\r\n args: part.args,\r\n });\r\n } else if (part.type === \"finish\") {\r\n lastFinish = part.finishReason;\r\n lastUsage = part.usage;\r\n }\r\n broadcast.push(part);\r\n }\r\n };\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n let boundary = buffer.indexOf(\"\\n\\n\");\r\n while (boundary !== -1) {\r\n const block = buffer.slice(0, boundary);\r\n buffer = buffer.slice(boundary + 2);\r\n for (const line of block.split(\"\\n\")) dispatch(line);\r\n boundary = buffer.indexOf(\"\\n\\n\");\r\n }\r\n }\r\n if (buffer.trim().length > 0) {\r\n for (const line of buffer.split(\"\\n\")) dispatch(line);\r\n }\r\n\r\n broadcast.end();\r\n deferreds.text.resolve(textBuffer);\r\n deferreds.reasoning.resolve(reasoningBuffer);\r\n deferreds.usage.resolve(lastUsage);\r\n deferreds.finishReason.resolve(lastFinish);\r\n deferreds.toolCalls.resolve(toolCallsArr);\r\n } catch (error) {\r\n broadcast.fail(error);\r\n deferreds.text.reject(error);\r\n deferreds.reasoning.reject(error);\r\n deferreds.usage.reject(error);\r\n deferreds.finishReason.reject(error);\r\n deferreds.toolCalls.reject(error);\r\n } finally {\r\n try {\r\n reader.releaseLock();\r\n } catch {\r\n // already released\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Build a `StreamTextResult` from a pre-existing async iterable of StreamParts.\r\n * Used by `client.agents.run()` to share the same DX as `client.ai.streamText`.\r\n */\r\nexport function createStreamResultFromParts(\r\n source: AsyncIterable<StreamPart>,\r\n): StreamTextResult {\r\n const broadcast = new PartBroadcast();\r\n const text = defer<string>();\r\n const reasoning = defer<string>();\r\n const usage = defer<TokenUsage>();\r\n const finishReason = defer<FinishReason>();\r\n const toolCalls = defer<ToolCallRecord[]>();\r\n\r\n void (async () => {\r\n let textBuffer = \"\";\r\n let reasoningBuffer = \"\";\r\n let lastUsage: TokenUsage = ZERO_USAGE;\r\n let lastFinish: FinishReason = \"unknown\";\r\n const toolCallsArr: ToolCallRecord[] = [];\r\n try {\r\n for await (const part of source) {\r\n if (part.type === \"text-delta\") textBuffer += part.textDelta;\r\n else if (part.type === \"reasoning\")\r\n reasoningBuffer += part.textDelta;\r\n else if (part.type === \"tool-call\") {\r\n toolCallsArr.push({\r\n toolCallId: part.toolCallId,\r\n toolName: part.toolName,\r\n args: part.args,\r\n });\r\n } else if (part.type === \"finish\") {\r\n lastFinish = part.finishReason;\r\n lastUsage = part.usage;\r\n }\r\n broadcast.push(part);\r\n }\r\n broadcast.end();\r\n text.resolve(textBuffer);\r\n reasoning.resolve(reasoningBuffer);\r\n usage.resolve(lastUsage);\r\n finishReason.resolve(lastFinish);\r\n toolCalls.resolve(toolCallsArr);\r\n } catch (error) {\r\n broadcast.fail(error);\r\n text.reject(error);\r\n reasoning.reject(error);\r\n usage.reject(error);\r\n finishReason.reject(error);\r\n toolCalls.reject(error);\r\n }\r\n })();\r\n\r\n return {\r\n fullStream: broadcast.consume(),\r\n textStream: {\r\n [Symbol.asyncIterator]: (): AsyncIterator<string> => {\r\n const inner = broadcast.consume()[Symbol.asyncIterator]();\r\n return {\r\n next: async (): Promise<IteratorResult<string>> => {\r\n while (true) {\r\n const r = await inner.next();\r\n if (r.done)\r\n return { value: undefined as unknown as string, done: true };\r\n if (r.value.type === \"text-delta\") {\r\n return { value: r.value.textDelta, done: false };\r\n }\r\n }\r\n },\r\n };\r\n },\r\n },\r\n text: text.promise,\r\n reasoning: reasoning.promise,\r\n usage: usage.promise,\r\n finishReason: finishReason.promise,\r\n toolCalls: toolCalls.promise,\r\n };\r\n}\r\n\r\nexport interface InferenceRequestContext {\r\n /** Resolved URL of the inference endpoint. */\r\n url: string;\r\n /** Pre-built request headers (`Content-Type` already set). */\r\n headers: Headers;\r\n /** Bound fetch (already wraps user `fetch` option). */\r\n fetch: typeof fetch;\r\n}\r\n\r\n/**\r\n * Open the inference SSE stream and return a `StreamTextResult`. Exposed\r\n * separately so `agents.run` can share the same fan-out plumbing later if\r\n * we ever want a backend-agnostic chunk format.\r\n */\r\nexport function streamInferenceFromContext(\r\n ctx: InferenceRequestContext,\r\n params: StreamTextParams,\r\n): StreamTextResult {\r\n const broadcast = new PartBroadcast();\r\n const text = defer<string>();\r\n const reasoning = defer<string>();\r\n const usage = defer<TokenUsage>();\r\n const finishReason = defer<FinishReason>();\r\n const toolCalls = defer<ToolCallRecord[]>();\r\n\r\n const start = async (): Promise<void> => {\r\n const response = await ctx.fetch(ctx.url, {\r\n method: \"POST\",\r\n headers: ctx.headers,\r\n body: JSON.stringify(buildInferenceRequestBody(params)),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n });\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n if (!response.body) {\r\n throw new RagableError(\"Inference stream has no body\", 502, {\r\n code: \"SDK_INFERENCE_STREAM_NO_BODY\",\r\n });\r\n }\r\n\r\n await consumeInferenceStream(response.body, broadcast, {\r\n text,\r\n reasoning,\r\n usage,\r\n finishReason,\r\n toolCalls,\r\n });\r\n };\r\n\r\n // Kick off in background — the consumer drives it via the iterables / promises.\r\n start().catch((err) => {\r\n broadcast.fail(err);\r\n text.reject(err);\r\n reasoning.reject(err);\r\n usage.reject(err);\r\n finishReason.reject(err);\r\n toolCalls.reject(err);\r\n });\r\n\r\n return {\r\n fullStream: broadcast.consume(),\r\n textStream: {\r\n [Symbol.asyncIterator]: (): AsyncIterator<string> => {\r\n const inner = broadcast.consume()[Symbol.asyncIterator]();\r\n return {\r\n next: async (): Promise<IteratorResult<string>> => {\r\n while (true) {\r\n const r = await inner.next();\r\n if (r.done) return { value: undefined as unknown as string, done: true };\r\n if (r.value.type === \"text-delta\") {\r\n return { value: r.value.textDelta, done: false };\r\n }\r\n }\r\n },\r\n };\r\n },\r\n },\r\n text: text.promise,\r\n reasoning: reasoning.promise,\r\n usage: usage.promise,\r\n finishReason: finishReason.promise,\r\n toolCalls: toolCalls.promise,\r\n };\r\n}\r\n\r\ninterface AiClientOptions {\r\n organizationId: string;\r\n websiteId?: string;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n /** API base override; defaults to the shared SDK base. */\r\n apiBase: string;\r\n}\r\n\r\nexport class RagableBrowserAiClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(private readonly options: AiClientOptions) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const id = this.options.websiteId?.trim();\r\n if (!id) {\r\n throw new RagableError(\r\n \"client.ai.streamText requires websiteId on the client. Pass createBrowserClient({ websiteId, organizationId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return id;\r\n }\r\n\r\n private buildContext(): InferenceRequestContext {\r\n const url = `${this.options.apiBase}/public/organizations/${encodeURIComponent(\r\n this.options.organizationId,\r\n )}/websites/${encodeURIComponent(\r\n this.requireWebsiteId(),\r\n )}/inference/stream`;\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n headers.set(\"Accept\", \"text/event-stream\");\r\n return { url, headers, fetch: this.fetchImpl };\r\n }\r\n\r\n streamText(params: StreamTextParams): StreamTextResult {\r\n return streamInferenceFromContext(this.buildContext(), params);\r\n }\r\n\r\n async generateText(params: StreamTextParams): Promise<GenerateTextResult> {\r\n const result = this.streamText(params);\r\n // Drain the fullStream so promises settle even if the caller never iterates.\r\n for await (const _ of result.fullStream) {\r\n void _;\r\n }\r\n const [text, reasoning, usage, finishReason, toolCalls] = await Promise.all(\r\n [\r\n result.text,\r\n result.reasoning,\r\n result.usage,\r\n result.finishReason,\r\n result.toolCalls,\r\n ],\r\n );\r\n return { text, reasoning, usage, finishReason, toolCalls };\r\n }\r\n\r\n /**\r\n * Stream a JSON-Schema-constrained response. Matches Vercel AI SDK's\r\n * `streamObject` shape — returns a synchronous result with `partialObjectStream`\r\n * (best-effort incremental parses) and `object` (the final parsed JSON).\r\n *\r\n * ```ts\r\n * const { partialObjectStream, object } = client.ai.streamObject({\r\n * model: \"accounts/fireworks/models/kimi-k2p5\",\r\n * schema: {\r\n * type: \"object\",\r\n * properties: {\r\n * title: { type: \"string\" },\r\n * tags: { type: \"array\", items: { type: \"string\" } },\r\n * },\r\n * required: [\"title\", \"tags\"],\r\n * },\r\n * messages: [{ role: \"user\", content: \"Give me a blog post idea about AI.\" }],\r\n * });\r\n * for await (const partial of partialObjectStream) renderPreview(partial);\r\n * const final = await object;\r\n * ```\r\n */\r\n streamObject<T = unknown>(\r\n params: StreamObjectParams,\r\n ): StreamObjectResult<T> {\r\n return streamObjectFromContext<T>(this.buildContext(), params);\r\n }\r\n\r\n /**\r\n * Non-streaming variant of {@link streamObject}. Resolves once the model\r\n * finishes; rejects if the final text isn't valid JSON for the schema.\r\n */\r\n async generateObject<T = unknown>(\r\n params: StreamObjectParams,\r\n ): Promise<GenerateObjectResult<T>> {\r\n const result = this.streamObject<T>(params);\r\n // Drain partials so promises settle even if the caller skips iteration.\r\n for await (const _ of result.partialObjectStream) {\r\n void _;\r\n }\r\n const [object, usage, finishReason, toolCalls] = await Promise.all([\r\n result.object,\r\n result.usage,\r\n result.finishReason,\r\n result.toolCalls,\r\n ]);\r\n return { object, usage, finishReason, toolCalls };\r\n }\r\n}\r\n\r\n/**\r\n * Open a JSON-mode inference stream against the proxy and return a\r\n * `StreamObjectResult`. Exposed for advanced callers; most code should use\r\n * `RagableBrowserAiClient.streamObject`.\r\n */\r\nexport function streamObjectFromContext<T = unknown>(\r\n ctx: InferenceRequestContext,\r\n params: StreamObjectParams,\r\n): StreamObjectResult<T> {\r\n // Reuse streamText's wire path — the response_format is the only diff.\r\n const textParams: StreamTextParams = {\r\n model: params.model,\r\n messages: params.messages,\r\n ...(params.system !== undefined ? { system: params.system } : {}),\r\n ...(typeof params.temperature === \"number\"\r\n ? { temperature: params.temperature }\r\n : {}),\r\n ...(typeof params.maxTokens === \"number\"\r\n ? { maxTokens: params.maxTokens }\r\n : {}),\r\n ...(typeof params.topP === \"number\" ? { topP: params.topP } : {}),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n };\r\n const responseFormat = buildResponseFormat({\r\n schema: params.schema,\r\n ...(params.schemaName !== undefined ? { name: params.schemaName } : {}),\r\n ...(params.schemaDescription !== undefined\r\n ? { description: params.schemaDescription }\r\n : {}),\r\n });\r\n\r\n // Custom request body builder that injects response_format.\r\n const overrideCtx: InferenceRequestContext = {\r\n ...ctx,\r\n // Wrap fetch to substitute the body. We can't change buildInferenceRequestBody\r\n // signature on the call site cleanly, so intercept here.\r\n fetch: ((input, init) => {\r\n if (init && typeof init.body === \"string\") {\r\n const parsed = JSON.parse(init.body) as Record<string, unknown>;\r\n parsed.response_format = responseFormat;\r\n const newInit: RequestInit = { ...init, body: JSON.stringify(parsed) };\r\n return ctx.fetch(input, newInit);\r\n }\r\n return ctx.fetch(input, init);\r\n }) as typeof fetch,\r\n };\r\n\r\n const inner = streamInferenceFromContext(overrideCtx, textParams);\r\n return wrapStreamTextAsObject<T>(inner);\r\n}\r\n\r\n/**\r\n * Wrap a `StreamTextResult` (text-only stream) into a `StreamObjectResult`\r\n * by parsing the accumulated text as JSON. The text path stays the source of\r\n * truth for `text`/`usage`/`finishReason`/`toolCalls`; this helper only adds\r\n * `partialObjectStream` and `object` on top.\r\n *\r\n * Public so `client.agents.runObject` can reuse the parsing logic — agents\r\n * stream text through their own SSE protocol, but the structured-output\r\n * conversion is identical.\r\n */\r\nexport function wrapStreamTextAsObject<T = unknown>(\r\n inner: StreamTextResult,\r\n): StreamObjectResult<T> {\r\n const partialBroadcast = new PartialObjectBroadcast<T>();\r\n const objectDeferred = defer<T>();\r\n\r\n void (async () => {\r\n let acc = \"\";\r\n let lastEmitted: unknown = Symbol(\"none\");\r\n try {\r\n for await (const delta of inner.textStream) {\r\n acc += delta;\r\n const candidate = tryParsePartialJson(acc);\r\n if (candidate !== undefined && !sameSnapshot(candidate, lastEmitted)) {\r\n lastEmitted = candidate;\r\n partialBroadcast.push(candidate as T);\r\n }\r\n }\r\n const finalText = await inner.text;\r\n // Strict parse for the final value — partial-mode repairs are not allowed here.\r\n let finalObj: T;\r\n try {\r\n finalObj = JSON.parse(finalText) as T;\r\n } catch (e) {\r\n const err = new RagableError(\r\n `Model output is not valid JSON: ${(e as Error).message}`,\r\n 502,\r\n {\r\n code: \"SDK_OBJECT_PARSE_FAILED\",\r\n raw: finalText.slice(0, 1000),\r\n },\r\n );\r\n partialBroadcast.fail(err);\r\n objectDeferred.reject(err);\r\n return;\r\n }\r\n if (!sameSnapshot(finalObj, lastEmitted)) {\r\n partialBroadcast.push(finalObj);\r\n }\r\n partialBroadcast.end();\r\n objectDeferred.resolve(finalObj);\r\n } catch (err) {\r\n partialBroadcast.fail(err);\r\n objectDeferred.reject(err);\r\n }\r\n })();\r\n\r\n return {\r\n textStream: inner.textStream,\r\n partialObjectStream: partialBroadcast.consume(),\r\n object: objectDeferred.promise,\r\n text: inner.text,\r\n usage: inner.usage,\r\n finishReason: inner.finishReason,\r\n toolCalls: inner.toolCalls,\r\n };\r\n}\r\n\r\n/** Tiny snapshot comparator — JSON.stringify is fine for the sizes we deal with. */\r\nfunction sameSnapshot(a: unknown, b: unknown): boolean {\r\n if (a === b) return true;\r\n try {\r\n return JSON.stringify(a) === JSON.stringify(b);\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/** Replay-from-start broadcast of partial objects. Mirrors PartBroadcast but typed. */\r\nclass PartialObjectBroadcast<T> {\r\n private items: T[] = [];\r\n private resolved = false;\r\n private error: unknown = null;\r\n private waiters: Array<() => void> = [];\r\n\r\n push(item: T): void {\r\n this.items.push(item);\r\n this.notify();\r\n }\r\n\r\n end(): void {\r\n if (this.resolved) return;\r\n this.resolved = true;\r\n this.notify();\r\n }\r\n\r\n fail(error: unknown): void {\r\n if (this.resolved) return;\r\n this.error = error;\r\n this.resolved = true;\r\n this.notify();\r\n }\r\n\r\n private notify(): void {\r\n const w = this.waiters;\r\n this.waiters = [];\r\n for (const fn of w) fn();\r\n }\r\n\r\n consume(): AsyncIterable<T> {\r\n const self = this;\r\n return {\r\n [Symbol.asyncIterator]: (): AsyncIterator<T> => {\r\n let idx = 0;\r\n return {\r\n next: async (): Promise<IteratorResult<T>> => {\r\n while (true) {\r\n if (idx < self.items.length) {\r\n return { value: self.items[idx++]!, done: false };\r\n }\r\n if (self.resolved) {\r\n if (self.error) throw self.error;\r\n return { value: undefined as unknown as T, done: true };\r\n }\r\n await new Promise<void>((res) => self.waiters.push(res));\r\n }\r\n },\r\n };\r\n },\r\n };\r\n }\r\n}\r\n","import type {\r\n AgentChatStreamUiHandlers,\r\n AgentChatUiStreamResult,\r\n} from \"./agent-chat-ui\";\r\nimport { runAgentChatStreamForUi } from \"./agent-chat-ui\";\r\nimport {\r\n runAgentChatStream,\r\n type AgentChatStreamHandlers,\r\n type AgentChatStreamResult,\r\n type AgentChatParams,\r\n type AgentStreamEvent,\r\n} from \"./agent-stream\";\r\nimport {\r\n bindFetch,\r\n DEFAULT_RAGABLE_API_BASE,\r\n extractErrorMessage,\r\n RagableError,\r\n} from \"./request-client\";\r\nimport type {\r\n DefaultRagableDatabase,\r\n RagableDatabase,\r\n RagableTableNames,\r\n TableInsertRow,\r\n TableRow,\r\n TableUpdatePatch,\r\n} from \"./database-schema\";\r\nimport { parseMaybeJsonBody, readSseStream } from \"./sse\";\r\nimport {\r\n asPostgrestResponse,\r\n PostgrestTableApi,\r\n type PostgRESTFetch,\r\n type PostgRESTFetchParams,\r\n type PostgrestResult,\r\n} from \"./browser-postgrest\";\r\nexport {\r\n assertPostgrestSuccess,\r\n toRagableResult,\r\n unwrapPostgrest,\r\n} from \"./browser-postgrest\";\r\nimport {\r\n RagableAuth,\r\n type AuthSignUpCredentials,\r\n type AuthChangeEvent,\r\n type AuthOptions,\r\n type AuthSession,\r\n type AuthUpdateUserAttributes,\r\n type AuthUserMetadata,\r\n type DefaultAuthUser,\r\n} from \"./auth\";\r\nimport { Transport, type TransportOptions } from \"./transport\";\r\nimport {\r\n RagableBrowserAiClient,\r\n buildResponseFormat,\r\n createStreamResultFromParts,\r\n wrapStreamTextAsObject,\r\n type GenerateObjectResult,\r\n type JsonSchema,\r\n type StreamObjectResult,\r\n type StreamTextResult,\r\n} from \"./ai\";\r\nimport type {\r\n DefaultRagableFunctions,\r\n FunctionInvoker,\r\n RagableFunctionInvokeOptions,\r\n RagableFunctions,\r\n} from \"./functions\";\r\nimport { mapAgentEvent, type StreamPart, type Message } from \"./stream-parts\";\r\n\r\n/** Canonical browser/server API base (`…/api`, no trailing slash). */\r\nexport function normalizeBrowserApiBase(): string {\r\n return DEFAULT_RAGABLE_API_BASE.replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport type BrowserDataAuthMode = \"user\" | \"publicAnon\" | \"admin\" | \"auto\";\r\n\r\n/**\r\n * Resolves how database / storage requests are authorized.\r\n *\r\n * Default (when `dataAuth` is omitted):\r\n * - **`auto`** when BOTH a static data key AND user auth (an `authGroupId` or a\r\n * `getAccessToken` callback) are configured — the generated-site case. This is\r\n * the Supabase model: send the signed-in user's JWT when a session exists, and\r\n * fall back to the public anon key for logged-out visitors. Without this, a\r\n * shipped anon key permanently shadows the user session, so owner/group/claim/\r\n * authenticated collection grants can never match a signed-in user.\r\n * - **`publicAnon`** when only a static key is configured (no auth group) — a\r\n * purely public app.\r\n * - **`user`** when neither — JWT-only.\r\n *\r\n * Set `dataAuth` explicitly to override: `\"user\"` (JWT required), `\"publicAnon\"`\r\n * (anon key only, never upgrade), or `\"admin\"` (the static key is a data-admin key).\r\n */\r\nexport function effectiveDataAuth(\r\n options: RagableBrowserClientOptions,\r\n): BrowserDataAuthMode {\r\n if (options.dataAuth) return options.dataAuth;\r\n const hasStatic =\r\n Boolean(options.dataStaticKey?.trim()) ||\r\n typeof options.getDataStaticKey === \"function\";\r\n const canUserAuth =\r\n Boolean(options.authGroupId?.trim()) ||\r\n typeof options.getAccessToken === \"function\";\r\n if (hasStatic && canUserAuth) return \"auto\";\r\n if (hasStatic) return \"publicAnon\";\r\n return \"user\";\r\n}\r\n\r\nexport interface RagableBrowserClientOptions {\r\n organizationId: string;\r\n websiteId?: string;\r\n authGroupId?: string;\r\n databaseInstanceId?: string;\r\n /** When omitted, inferred from static keys — see {@link effectiveDataAuth}. */\r\n dataAuth?: BrowserDataAuthMode;\r\n /** Public anon or data-admin key from the dashboard (Browser Data API keys). */\r\n dataStaticKey?: string;\r\n getDataStaticKey?: () => string | null | Promise<string | null>;\r\n getAccessToken?: () => string | null | Promise<string | null>;\r\n fetch?: typeof fetch;\r\n headers?: HeadersInit;\r\n auth?: AuthOptions;\r\n transport?: Partial<TransportOptions>;\r\n}\r\n\r\nfunction requireAuthGroupId(options: RagableBrowserClientOptions): string {\r\n const id = options.authGroupId?.trim();\r\n if (!id) {\r\n throw new RagableError(\r\n \"authGroupId is required for auth and database methods on the browser client\",\r\n 400,\r\n { code: \"SDK_MISSING_AUTH_GROUP_ID\" },\r\n );\r\n }\r\n return id;\r\n}\r\n\r\n/**\r\n * Best-effort signed-in user token: the SDK-managed session (auto-refreshed) if\r\n * present, else a caller-supplied `getAccessToken`. Returns null instead of\r\n * throwing, so callers can fall back to an anon key.\r\n */\r\nasync function tryGetUserAccessToken(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n): Promise<string | null> {\r\n if (ragableAuth) {\r\n const token = await ragableAuth.getValidAccessToken().catch(() => null);\r\n if (token?.trim()) return token.trim();\r\n }\r\n const getter = options.getAccessToken;\r\n if (getter) {\r\n const token = await getter();\r\n if (token?.trim()) return token.trim();\r\n }\r\n return null;\r\n}\r\n\r\n/** Resolve the configured static browser-data key (anon or admin), or null. */\r\nasync function resolveStaticDataKey(\r\n options: RagableBrowserClientOptions,\r\n): Promise<string | null> {\r\n const fromGetter = options.getDataStaticKey\r\n ? await options.getDataStaticKey()\r\n : null;\r\n const key = (fromGetter?.trim() || options.dataStaticKey?.trim()) ?? \"\";\r\n return key || null;\r\n}\r\n\r\nasync function requireAccessToken(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n): Promise<string> {\r\n const token = await tryGetUserAccessToken(options, ragableAuth);\r\n if (token) return token;\r\n throw new RagableError(\r\n \"No access token available. Sign in first with auth.signInWithPassword() or provide getAccessToken callback.\",\r\n 401,\r\n { code: \"SDK_NO_ACCESS_TOKEN\" },\r\n );\r\n}\r\n\r\n/**\r\n * Resolve the Bearer used for database / storage requests, per {@link effectiveDataAuth}.\r\n * In `auto` mode a live user session takes precedence over the anon key, so a\r\n * signed-in user's identity reaches the data plane automatically.\r\n */\r\nasync function resolveDatabaseAuthBearer(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n): Promise<string> {\r\n const mode = effectiveDataAuth(options);\r\n if (mode === \"user\") {\r\n return requireAccessToken(options, ragableAuth);\r\n }\r\n if (mode === \"auto\") {\r\n const userTok = await tryGetUserAccessToken(options, ragableAuth);\r\n if (userTok) return userTok;\r\n const key = await resolveStaticDataKey(options);\r\n if (key) return key;\r\n throw new RagableError(\r\n \"No access token or data key available. Sign in with auth.signInWithPassword() or configure dataStaticKey.\",\r\n 401,\r\n { code: \"SDK_NO_ACCESS_TOKEN\" },\r\n );\r\n }\r\n // publicAnon | admin: the static key is the only accepted credential.\r\n const key = await resolveStaticDataKey(options);\r\n if (!key) {\r\n throw new RagableError(\r\n mode === \"publicAnon\"\r\n ? \"dataAuth publicAnon requires getDataStaticKey or dataStaticKey\"\r\n : \"dataAuth admin requires getDataStaticKey or dataStaticKey\",\r\n 400,\r\n { code: \"SDK_MISSING_STATIC_KEY\" },\r\n );\r\n }\r\n return key;\r\n}\r\n\r\n// ─── Session types (kept for back-compat) ────────────────────────────────────\r\n\r\nexport interface BrowserAuthSession<\r\n AuthUser extends object = DefaultAuthUser,\r\n> {\r\n user: AuthUser;\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n}\r\n\r\nexport interface BrowserAuthTokens {\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: string;\r\n}\r\n\r\nexport interface SupabaseCompatSession<\r\n AuthUser extends object = DefaultAuthUser,\r\n> {\r\n access_token: string;\r\n refresh_token: string;\r\n expires_in: number;\r\n token_type: \"bearer\";\r\n user: AuthUser;\r\n}\r\n\r\nexport type { PostgrestResult };\r\nexport type { RagableResult } from \"./browser-postgrest\";\r\n\r\n// ─── RagableBrowserAuthClient (back-compat shim) ─────────────────────────────\r\n\r\nexport class RagableBrowserAuthClient<\r\n AuthUser extends object = DefaultAuthUser,\r\n> {\r\n constructor(\r\n _options: RagableBrowserClientOptions,\r\n private readonly ragableAuth: RagableAuth<AuthUser> | null = null,\r\n ) {}\r\n\r\n private get auth(): RagableAuth<AuthUser> {\r\n if (!this.ragableAuth) {\r\n throw new Error(\"Auth not initialized — provide authGroupId to enable auth\");\r\n }\r\n return this.ragableAuth;\r\n }\r\n\r\n async signUp(\r\n credentials: AuthSignUpCredentials<\r\n AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Metadata\r\n : AuthUserMetadata\r\n : AuthUserMetadata\r\n >,\r\n ): Promise<\r\n PostgrestResult<{\r\n user: AuthUser;\r\n session: SupabaseCompatSession<AuthUser>;\r\n }>\r\n > {\r\n const result = await this.auth.signUp(credentials);\r\n if (result.error) return { data: null, error: result.error };\r\n const session = result.data!.session;\r\n return {\r\n data: {\r\n user: session.user,\r\n session: {\r\n access_token: session.access_token,\r\n refresh_token: session.refresh_token,\r\n expires_in: session.expires_in,\r\n token_type: \"bearer\",\r\n user: session.user,\r\n },\r\n },\r\n error: null,\r\n };\r\n }\r\n\r\n async signInWithPassword(credentials: {\r\n email: string;\r\n password: string;\r\n }): Promise<\r\n PostgrestResult<{\r\n user: AuthUser;\r\n session: SupabaseCompatSession<AuthUser>;\r\n }>\r\n > {\r\n const result = await this.auth.signInWithPassword(credentials);\r\n if (result.error) return { data: null, error: result.error };\r\n const session = result.data!.session;\r\n return {\r\n data: {\r\n user: session.user,\r\n session: {\r\n access_token: session.access_token,\r\n refresh_token: session.refresh_token,\r\n expires_in: session.expires_in,\r\n token_type: \"bearer\",\r\n user: session.user,\r\n },\r\n },\r\n error: null,\r\n };\r\n }\r\n\r\n async refreshSession(refreshToken: string): Promise<\r\n PostgrestResult<{ session: SupabaseCompatSession<AuthUser>; user: AuthUser }>\r\n > {\r\n const result = await this.auth.refreshSession(refreshToken);\r\n if (result.error) return { data: null, error: result.error };\r\n const session = result.data!.session;\r\n return {\r\n data: {\r\n user: session.user,\r\n session: {\r\n access_token: session.access_token,\r\n refresh_token: session.refresh_token,\r\n expires_in: session.expires_in,\r\n token_type: \"bearer\",\r\n user: session.user,\r\n },\r\n },\r\n error: null,\r\n };\r\n }\r\n\r\n async getUser(): Promise<PostgrestResult<{ user: AuthUser }>> {\r\n return this.auth.getUser();\r\n }\r\n\r\n async updateUser(\r\n attributes: AuthUpdateUserAttributes<\r\n AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Metadata\r\n : AuthUserMetadata\r\n : AuthUserMetadata\r\n >,\r\n ): Promise<PostgrestResult<{ user: AuthUser }>> {\r\n return this.auth.updateUser(attributes);\r\n }\r\n\r\n async signOut(_options?: { scope?: \"global\" | \"local\" }): Promise<{\r\n error: null;\r\n }> {\r\n return this.auth.signOut(_options);\r\n }\r\n\r\n async register(body: {\r\n email: string;\r\n password: string;\r\n name?: string;\r\n data?: AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Partial<Metadata> & { name?: string | null }\r\n : Record<string, unknown>\r\n : Record<string, unknown>;\r\n }): Promise<BrowserAuthSession<AuthUser>> {\r\n return this.auth.register(body as Parameters<RagableAuth<AuthUser>[\"register\"]>[0]);\r\n }\r\n\r\n async login(body: {\r\n email: string;\r\n password: string;\r\n }): Promise<BrowserAuthSession<AuthUser>> {\r\n return this.auth.login(body);\r\n }\r\n\r\n async refresh(body: { refreshToken: string }): Promise<BrowserAuthTokens> {\r\n return this.auth.refresh(body);\r\n }\r\n\r\n async getMe(): Promise<{ user: AuthUser }> {\r\n return this.auth.getMe();\r\n }\r\n\r\n async updateMe(body: {\r\n email?: string;\r\n name?: string | null;\r\n password?: string;\r\n data?: AuthUser extends { metadata: infer Metadata }\r\n ? Metadata extends AuthUserMetadata\r\n ? Partial<Metadata> & { name?: string | null }\r\n : Record<string, unknown>\r\n : Record<string, unknown>;\r\n }): Promise<{ user: AuthUser }> {\r\n return this.auth.updateMe(body as Parameters<RagableAuth<AuthUser>[\"updateMe\"]>[0]);\r\n }\r\n\r\n onAuthStateChange(\r\n callback: (event: AuthChangeEvent, session: AuthSession<AuthUser> | null) => void,\r\n ): { data: { subscription: { id: string; unsubscribe: () => void } } } {\r\n return this.auth.onAuthStateChange(callback);\r\n }\r\n\r\n getSession(): Promise<PostgrestResult<{ session: AuthSession<AuthUser> | null }>> {\r\n return this.auth.getSession();\r\n }\r\n\r\n /**\r\n * Returns a valid (auto-refreshed) access token for the current session, or\r\n * `null` if signed out. The sanctioned way to obtain a token for a hand-rolled\r\n * `fetch` to a custom endpoint — never read tokens out of storage yourself.\r\n */\r\n getValidAccessToken(): Promise<string | null> {\r\n return this.ragableAuth\r\n ? this.ragableAuth.getValidAccessToken()\r\n : Promise.resolve(null);\r\n }\r\n}\r\n\r\n// ─── SQL query types ─────────────────────────────────────────────────────────\r\n\r\nexport interface BrowserSqlQueryParams {\r\n databaseInstanceId?: string;\r\n sql: string;\r\n params?: unknown[];\r\n readOnly?: boolean;\r\n timeoutMs?: number;\r\n rowLimit?: number;\r\n}\r\n\r\nexport interface BrowserSqlQueryResult<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> {\r\n command: string;\r\n rowCount: number;\r\n truncated: boolean;\r\n rows: Row[];\r\n}\r\n\r\n// ─── Database client ─────────────────────────────────────────────────────────\r\n\r\nexport interface BrowserCollectionRecord<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> {\r\n [key: string]: unknown;\r\n id: string;\r\n data: Row;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\n/**\r\n * Collection APIs return record envelopes, but user schema `Row` types should be\r\n * the JSON row inside `record.data`. If generated app types accidentally use the\r\n * envelope as `Row`, unwrap it so consumers still get `record.data.<field>`.\r\n */\r\nexport type BrowserCollectionRowData<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = Row extends {\r\n id: string;\r\n data: infer Data;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n ? Data extends Record<string, unknown>\r\n ? Data\r\n : Row\r\n : Row;\r\n\r\ntype BrowserCollectionInsertData<\r\n Row extends Record<string, unknown>,\r\n Insert extends Record<string, unknown>,\r\n> = BrowserCollectionRowData<Row> extends Row\r\n ? Insert\r\n : Insert extends {\r\n data: infer Data;\r\n }\r\n ? Data extends Record<string, unknown>\r\n ? Data\r\n : BrowserCollectionRowData<Row>\r\n : BrowserCollectionRowData<Row>;\r\n\r\ntype BrowserCollectionUpdateData<\r\n Row extends Record<string, unknown>,\r\n Update extends Record<string, unknown>,\r\n> = BrowserCollectionRowData<Row> extends Row\r\n ? Update\r\n : Update extends {\r\n data?: infer Data;\r\n }\r\n ? Data extends Record<string, unknown>\r\n ? Partial<Data>\r\n : Partial<BrowserCollectionRowData<Row>>\r\n : Partial<BrowserCollectionRowData<Row>>;\r\n\r\nexport interface BrowserCollectionDefinition {\r\n id: string;\r\n name: string;\r\n schema: Record<string, unknown> | null;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\n/**\r\n * Prisma-style operator object for a single field (server-supported ops).\r\n * Typed loosely so schema-specific refinements can be added in app code.\r\n */\r\nexport type WhereOperatorObject = {\r\n eq?: unknown;\r\n neq?: unknown;\r\n gt?: number;\r\n gte?: number;\r\n lt?: number;\r\n lte?: number;\r\n in?: unknown;\r\n contains?: unknown;\r\n};\r\n\r\n/**\r\n * `where` filters: equality on values, or per-field operator objects.\r\n * Use `id`, `createdAt`, `updatedAt` to match the record envelope (DB columns), not `data` JSON\r\n * (unless you also have those keys in your JSON — prefer envelope keys for `id`).\r\n */\r\nexport type WhereInput<Row extends Record<string, unknown>> = {\r\n [K in keyof Row]?: Row[K] | WhereOperatorObject | null;\r\n} & {\r\n id?: string | WhereOperatorObject;\r\n createdAt?: string | WhereOperatorObject;\r\n updatedAt?: string | WhereOperatorObject;\r\n};\r\n\r\n/** @deprecated Use {@link WhereInput} — same shape. */\r\nexport type CollectionWhere<Row extends Record<string, unknown>> = WhereInput<Row>;\r\n\r\ntype CollectionFilter<Row extends Record<string, unknown>> = {\r\n [Field in Extract<keyof Row, string>]: {\r\n field: Field;\r\n op?: \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\" | \"contains\";\r\n value: Row[Field];\r\n };\r\n}[Extract<keyof Row, string>];\r\n\r\nexport type CollectionReturnMode = \"envelope\" | \"flat\";\r\n\r\n/**\r\n * One row: JSON fields at the top level, envelope fields under `meta`\r\n * (when using {@link BrowserCollectionApi.findMany} with `return: \"flat\"`).\r\n */\r\nexport type CollectionRowWithMeta<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = Row & {\r\n meta: { id: string; createdAt: string; updatedAt: string };\r\n};\r\n\r\nexport function collectionRecordToRowWithMeta<Row extends Record<string, unknown>>(\r\n record: BrowserCollectionRecord<Row>,\r\n): CollectionRowWithMeta<Row> {\r\n const { data, id, createdAt, updatedAt } = record;\r\n return { ...(data as Row), meta: { id, createdAt, updatedAt } };\r\n}\r\n\r\nexport function collectionRecordsToRowWithMeta<Row extends Record<string, unknown>>(\r\n records: BrowserCollectionRecord<Row>[],\r\n): CollectionRowWithMeta<Row>[] {\r\n return records.map(collectionRecordToRowWithMeta);\r\n}\r\n\r\n/**\r\n * Rows returned by a find: {@link CollectionRowWithMeta} when the params carry\r\n * a literal `return: \"flat\"`, envelope {@link BrowserCollectionRecord}s\r\n * otherwise. Keeps the default (envelope) call sites free of union-narrowing —\r\n * `res.data[0].data` typechecks without a cast.\r\n */\r\nexport type CollectionFindResult<\r\n Row extends Record<string, unknown>,\r\n Params,\r\n> = Params extends { return: \"flat\" }\r\n ? CollectionRowWithMeta<Row>[]\r\n : BrowserCollectionRecord<Row>[];\r\n\r\nconst FIND_QUERY_KEYS = [\r\n \"where\",\r\n \"filters\",\r\n \"limit\",\r\n \"offset\",\r\n \"orderBy\",\r\n \"orderDirection\",\r\n \"return\",\r\n] as const;\r\n\r\nexport type BrowserCollectionFindParams<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = {\r\n where?: WhereInput<Row>;\r\n filters?: Array<{\r\n field: Extract<keyof Row, string> | (string & {});\r\n op?: \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\" | \"contains\";\r\n value: unknown;\r\n } | CollectionFilter<Row>>;\r\n limit?: number;\r\n offset?: number;\r\n orderBy?:\r\n | Extract<keyof Row, string>\r\n | \"id\"\r\n | \"createdAt\"\r\n | \"updatedAt\"\r\n | (string & {});\r\n orderDirection?: \"asc\" | \"desc\";\r\n /**\r\n * - `envelope` (default): `Array<{ id, data, createdAt, updatedAt }>`\r\n * - `flat`: {@link CollectionRowWithMeta} — row fields at top level + `meta` for `id` / timestamps\r\n */\r\n return?: CollectionReturnMode;\r\n};\r\n\r\nexport type CollectionRowData<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n> = BrowserCollectionRowData<Row>;\r\n\r\ntype RowD<Row extends Record<string, unknown>> = BrowserCollectionRowData<Row>;\r\n\r\nexport class BrowserCollectionApi<\r\n Row extends Record<string, unknown> = Record<string, unknown>,\r\n Insert extends Record<string, unknown> = Row,\r\n Update extends Record<string, unknown> = Partial<Row>,\r\n> {\r\n constructor(\r\n private readonly database: RagableBrowserDatabaseClient<any>,\r\n private readonly name: string,\r\n private readonly databaseInstanceId?: string,\r\n ) {}\r\n\r\n private normalizeFindArgs(whereOrParams: unknown): {\r\n returnMode: CollectionReturnMode;\r\n body: Record<string, unknown>;\r\n } {\r\n const hasQueryKeys =\r\n typeof whereOrParams === \"object\" &&\r\n whereOrParams !== null &&\r\n FIND_QUERY_KEYS.some((key) =>\r\n Object.prototype.hasOwnProperty.call(whereOrParams, key),\r\n );\r\n const raw: Record<string, unknown> = hasQueryKeys\r\n ? { ...(whereOrParams as object) }\r\n : { where: whereOrParams };\r\n const returnMode: CollectionReturnMode =\r\n raw[\"return\"] === \"flat\" ? \"flat\" : \"envelope\";\r\n delete raw[\"return\"];\r\n return { returnMode, body: raw };\r\n }\r\n\r\n private requestFind = (\r\n body: Record<string, unknown>,\r\n ): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>> =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>[]>(\r\n \"POST\",\r\n `/${encodeURIComponent(this.name)}/find`,\r\n body,\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Query collection rows. Prefer this over the deprecated `find` alias.\r\n * Use `return: \"flat\"` to get {@link CollectionRowWithMeta} without nested `.data`.\r\n */\r\n findMany = async <\r\n Params extends\r\n | WhereInput<RowD<Row>>\r\n | BrowserCollectionFindParams<RowD<Row>>,\r\n >(\r\n whereOrParams: Params = {} as Params,\r\n ): Promise<PostgrestResult<CollectionFindResult<RowD<Row>, Params>>> => {\r\n const { returnMode, body } = this.normalizeFindArgs(whereOrParams);\r\n const res = await this.requestFind(body);\r\n if (res.error) return res;\r\n const data =\r\n returnMode === \"flat\"\r\n ? collectionRecordsToRowWithMeta<RowD<Row>>(res.data)\r\n : res.data;\r\n return {\r\n data: data as CollectionFindResult<RowD<Row>, Params>,\r\n error: null,\r\n };\r\n };\r\n\r\n /**\r\n * @deprecated Use {@link BrowserCollectionApi.findMany} — same behavior.\r\n */\r\n find = <\r\n Params extends\r\n | WhereInput<RowD<Row>>\r\n | BrowserCollectionFindParams<RowD<Row>>,\r\n >(\r\n whereOrParams: Params = {} as Params,\r\n ): Promise<PostgrestResult<CollectionFindResult<RowD<Row>, Params>>> =>\r\n this.findMany(whereOrParams);\r\n\r\n /**\r\n * At most one row, `data` is the record or `null` if none match (not an error).\r\n */\r\n findFirst = async (\r\n whereOrParams:\r\n | WhereInput<RowD<Row>>\r\n | Omit<BrowserCollectionFindParams<RowD<Row>>, \"return\"> = {},\r\n ): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>> | null>> => {\r\n const { body } = this.normalizeFindArgs(whereOrParams);\r\n const withCap = { ...body, limit: 1, offset: body[\"offset\"] ?? 0 };\r\n const res = await this.requestFind(withCap);\r\n if (res.error) return res;\r\n return { data: res.data[0] ?? null, error: null };\r\n };\r\n\r\n /**\r\n * Lookup by primary key `id` (envelope). Equivalent to\r\n * `findFirst({ where: { id }, limit: 1 })` with a typed `where.id`.\r\n */\r\n findUnique = async (args: {\r\n where: { id: string } & Partial<WhereInput<RowD<Row>>>;\r\n }): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>> | null>> => {\r\n return this.findFirst({ where: args.where });\r\n };\r\n\r\n insert = (\r\n data: BrowserCollectionInsertData<Row, Insert>,\r\n ): Promise<\r\n PostgrestResult<BrowserCollectionRecord<RowD<Row>>>\r\n > =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>>(\r\n \"POST\",\r\n `/${encodeURIComponent(this.name)}/records`,\r\n { data },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Insert multiple rows in one request (server multi-value `INSERT`, single transaction).\r\n * Empty **`items`** resolves to an empty array. Max batch size is enforced on the server (500).\r\n */\r\n insertMany = (\r\n items: BrowserCollectionInsertData<Row, Insert>[],\r\n ): Promise<\r\n PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>\r\n > =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>[]>(\r\n \"POST\",\r\n `/${encodeURIComponent(this.name)}/records/batch`,\r\n { items },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Update rows matching `where` (JSON fields, plus envelope `id` / `createdAt` / `updatedAt`).\r\n */\r\n update = (\r\n where: WhereInput<RowD<Row>>,\r\n patch: BrowserCollectionUpdateData<Row, Update>,\r\n options?: { limit?: number },\r\n ): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>> =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<BrowserCollectionRecord<RowD<Row>>[]>(\r\n \"PATCH\",\r\n `/${encodeURIComponent(this.name)}/records`,\r\n { where, patch, ...(options?.limit ? { limit: options.limit } : {}) },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Like {@link BrowserCollectionApi.update} but the success payload includes\r\n * `meta.count` (number of rows returned from the update, bounded by `limit`).\r\n */\r\n updateMany = async (\r\n where: WhereInput<RowD<Row>>,\r\n patch: BrowserCollectionUpdateData<Row, Update>,\r\n options?: { limit?: number },\r\n ): Promise<\r\n PostgrestResult<{\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n meta: { count: number };\r\n }>\r\n > => {\r\n const r = await this.update(where, patch, options);\r\n if (r.error) return r;\r\n return { data: { records: r.data, meta: { count: r.data.length } }, error: null };\r\n };\r\n\r\n delete = (\r\n where: WhereInput<RowD<Row>>,\r\n options?: { limit?: number },\r\n ): Promise<\r\n PostgrestResult<{\r\n deleted: number;\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n }>\r\n > =>\r\n asPostgrestResponse(() =>\r\n this.database._requestCollection<{\r\n deleted: number;\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n }>(\r\n \"DELETE\",\r\n `/${encodeURIComponent(this.name)}/records`,\r\n { where, ...(options?.limit ? { limit: options.limit } : {}) },\r\n this.databaseInstanceId,\r\n ),\r\n );\r\n\r\n /**\r\n * Like {@link BrowserCollectionApi.delete} but the success payload includes **`meta.count`**\r\n * (number of deleted rows), matching {@link BrowserCollectionApi.updateMany}.\r\n */\r\n deleteMany = async (\r\n where: WhereInput<RowD<Row>>,\r\n options?: { limit?: number },\r\n ): Promise<\r\n PostgrestResult<{\r\n records: BrowserCollectionRecord<RowD<Row>>[];\r\n meta: { count: number };\r\n }>\r\n > => {\r\n const r = await this.delete(where, options);\r\n if (r.error) return r;\r\n return {\r\n data: {\r\n records: r.data.records,\r\n meta: { count: r.data.deleted },\r\n },\r\n error: null,\r\n };\r\n };\r\n}\r\n\r\nexport type BrowserCollections<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n> = [keyof Database[\"public\"][\"Tables\"]] extends [never]\r\n ? Record<string, BrowserCollectionApi<Record<string, unknown>>>\r\n : {\r\n readonly [Name in RagableTableNames<Database>]: BrowserCollectionApi<\r\n TableRow<Database, Name>,\r\n TableInsertRow<Database, Name>,\r\n TableUpdatePatch<Database, Name>\r\n >;\r\n };\r\n\r\nexport type BrowserCollectionFactory<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n> = {\r\n <Name extends RagableTableNames<Database>>(\r\n name: Name,\r\n databaseInstanceId?: string,\r\n ): BrowserCollectionApi<\r\n TableRow<Database, Name>,\r\n TableInsertRow<Database, Name>,\r\n TableUpdatePatch<Database, Name>\r\n >;\r\n <Row extends Record<string, unknown>>(\r\n name: string,\r\n databaseInstanceId?: string,\r\n ): BrowserCollectionApi<Row>;\r\n};\r\n\r\nexport class RagableBrowserDatabaseClient<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n> {\r\n private readonly fetchImpl: typeof fetch;\r\n private _transport: Transport | null = null;\r\n readonly collections: BrowserCollections<Database>;\r\n readonly collection: BrowserCollectionFactory<Database>;\r\n\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly ragableAuth: RagableAuth | null = null,\r\n ) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n this.collections = new Proxy(\r\n {},\r\n {\r\n get: (_target, prop) => {\r\n if (typeof prop !== \"string\") return undefined;\r\n if (prop === \"then\") return undefined;\r\n return this.collection(prop);\r\n },\r\n },\r\n ) as BrowserCollections<Database>;\r\n this.collection = ((name: string, databaseInstanceId?: string) =>\r\n new BrowserCollectionApi(\r\n this,\r\n name,\r\n databaseInstanceId,\r\n )) as BrowserCollectionFactory<Database>;\r\n }\r\n\r\n /** @internal Called by RagableBrowser to share the Transport instance. */\r\n _setTransport(transport: Transport): void {\r\n this._transport = transport;\r\n }\r\n\r\n /**\r\n * PostgREST table access. Instance field so `client.database.from` is always an own,\r\n * enumerable function (avoids rare prototype/bundler issues).\r\n */\r\n from = <TableName extends RagableTableNames<Database>>(\r\n table: TableName,\r\n databaseInstanceId?: string,\r\n ): PostgrestTableApi<Database, TableName> => {\r\n const id =\r\n databaseInstanceId?.trim() || this.options.databaseInstanceId?.trim() || \"\";\r\n const ragableAuth = this.ragableAuth;\r\n const opts = this.options;\r\n const transport = this._transport;\r\n const fetchImpl = this.fetchImpl;\r\n\r\n const pgFetch: PostgRESTFetch = async (params: PostgRESTFetchParams) => {\r\n if (!params.databaseInstanceId?.trim()) {\r\n throw new RagableError(\r\n \"database.from() requires databaseInstanceId in client options or as the second argument\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n const gid = requireAuthGroupId(opts);\r\n const token = await resolveDatabaseAuthBearer(opts, ragableAuth);\r\n const apiBase = normalizeBrowserApiBase();\r\n const qs = params.searchParams.toString();\r\n const url = `${apiBase}/auth-groups/${gid}/data/rest/${params.table}${qs ? `?${qs}` : \"\"}`;\r\n\r\n const headers = new Headers(opts.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"X-Database-Instance-Id\", params.databaseInstanceId);\r\n if (params.body !== undefined) {\r\n headers.set(\"Content-Type\", \"application/json\");\r\n }\r\n if (params.headers) {\r\n for (const [k, v] of Object.entries(params.headers)) {\r\n headers.set(k, v);\r\n }\r\n }\r\n\r\n if (transport) {\r\n return transport.execute({\r\n url,\r\n method: params.method,\r\n headers,\r\n body: params.body !== undefined ? JSON.stringify(params.body) : undefined,\r\n signal: params.signal,\r\n idempotencyKey: params.idempotencyKey,\r\n });\r\n }\r\n\r\n return fetchImpl(url, {\r\n method: params.method,\r\n headers,\r\n body: params.body !== undefined ? JSON.stringify(params.body) : undefined,\r\n signal: params.signal,\r\n });\r\n };\r\n return new PostgrestTableApi<Database, TableName>(pgFetch, id, table);\r\n };\r\n\r\n private toUrl(path: string): string {\r\n return `${normalizeBrowserApiBase()}${path.startsWith(\"/\") ? path : `/${path}`}`;\r\n }\r\n\r\n defineCollection = (\r\n name: string,\r\n schema?: Record<string, unknown>,\r\n databaseInstanceId?: string,\r\n ): Promise<PostgrestResult<BrowserCollectionDefinition>> =>\r\n asPostgrestResponse(() =>\r\n this._requestCollection<BrowserCollectionDefinition>(\r\n \"POST\",\r\n \"/\",\r\n { name, ...(schema ? { schema } : {}) },\r\n databaseInstanceId,\r\n ),\r\n );\r\n\r\n listCollections = (\r\n databaseInstanceId?: string,\r\n ): Promise<PostgrestResult<BrowserCollectionDefinition[]>> =>\r\n asPostgrestResponse(() =>\r\n this._requestCollection<BrowserCollectionDefinition[]>(\r\n \"GET\",\r\n \"/\",\r\n undefined,\r\n databaseInstanceId,\r\n ),\r\n );\r\n\r\n async _requestCollection<T>(\r\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\r\n path: string,\r\n body?: unknown,\r\n databaseInstanceId?: string,\r\n ): Promise<T> {\r\n const gid = requireAuthGroupId(this.options);\r\n const token = await resolveDatabaseAuthBearer(this.options, this.ragableAuth);\r\n const id = databaseInstanceId?.trim() || this.options.databaseInstanceId?.trim();\r\n if (!id) {\r\n throw new RagableError(\r\n \"db.collections requires databaseInstanceId in client options. For dynamic collection() calls, you can also pass databaseInstanceId as the second argument.\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n const headers = this.baseHeaders();\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"X-Database-Instance-Id\", id);\r\n if (body !== undefined) headers.set(\"Content-Type\", \"application/json\");\r\n const response = await this.fetchImpl(\r\n this.toUrl(`/auth-groups/${gid}/data/collections${path}`),\r\n {\r\n method,\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n },\r\n );\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n }\r\n\r\n query = async <Row extends Record<string, unknown> = Record<string, unknown>>(\r\n params: BrowserSqlQueryParams,\r\n ): Promise<PostgrestResult<BrowserSqlQueryResult<Row>>> => {\r\n return asPostgrestResponse(async () => {\r\n const gid = requireAuthGroupId(this.options);\r\n const token = await resolveDatabaseAuthBearer(this.options, this.ragableAuth);\r\n const databaseInstanceId =\r\n params.databaseInstanceId?.trim() ||\r\n this.options.databaseInstanceId?.trim();\r\n if (!databaseInstanceId) {\r\n throw new RagableError(\r\n \"database.query requires databaseInstanceId in the request or on createBrowserClient({ databaseInstanceId })\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n const headers = this.baseHeaders();\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n // Force read-only only when the request actually goes out under the public\r\n // anon key: always in publicAnon mode, and in auto mode ONLY when no user\r\n // session is signed in. A signed-in user (auto → JWT) or an admin key may write.\r\n const dataMode = effectiveDataAuth(this.options);\r\n let readOnly: boolean;\r\n if (dataMode === \"publicAnon\") {\r\n readOnly = true;\r\n } else if (dataMode === \"auto\") {\r\n const userTok = await tryGetUserAccessToken(this.options, this.ragableAuth);\r\n readOnly = userTok ? params.readOnly !== false : true;\r\n } else {\r\n readOnly = params.readOnly !== false;\r\n }\r\n const response = await this.fetchImpl(\r\n this.toUrl(`/auth-groups/${gid}/data/query`),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({\r\n databaseInstanceId,\r\n sql: params.sql,\r\n ...(params.params !== undefined ? { params: params.params } : {}),\r\n readOnly,\r\n ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs } : {}),\r\n ...(params.rowLimit !== undefined ? { rowLimit: params.rowLimit } : {}),\r\n }),\r\n },\r\n );\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as BrowserSqlQueryResult<Row>;\r\n });\r\n };\r\n\r\n private baseHeaders(): Headers {\r\n return new Headers(this.options.headers);\r\n }\r\n\r\n /**\r\n * Postgres `LISTEN` / `NOTIFY` realtime via server-proxied SSE.\r\n * Channels must be lowercase identifiers: `[a-z_][a-z0-9_]*` (max 63 chars).\r\n */\r\n /**\r\n * Postgres `LISTEN` / `NOTIFY` realtime via server-proxied SSE.\r\n *\r\n * Returns a `BrowserRealtimeSubscription` with:\r\n * - `unsubscribe()` — permanently close the subscription (stops reconnects).\r\n * - `status` — current connection state: `\"connecting\"` | `\"connected\"` | `\"reconnecting\"` | `\"disconnected\"`.\r\n *\r\n * The subscription automatically reconnects with exponential backoff when the\r\n * stream drops. Server heartbeats (every 15 s) are monitored — if none arrive\r\n * within `heartbeatTimeoutMs` (default 45 s), the connection is treated as dead\r\n * and a reconnect is triggered. Auth errors (401/403/404) are non-retryable.\r\n *\r\n * Channel names must be lowercase identifiers: `[a-z_][a-z0-9_]*` (max 63 chars).\r\n */\r\n realtime = {\r\n subscribe: (\r\n params: BrowserRealtimeSubscribeParams,\r\n ): Promise<BrowserRealtimeSubscription> =>\r\n subscribeBrowserRealtime(\r\n this.options,\r\n this.ragableAuth,\r\n this.fetchImpl,\r\n params,\r\n ),\r\n };\r\n}\r\n\r\n/**\r\n * A single NOTIFY message received from a Postgres channel.\r\n *\r\n * - `channel` — the lowercase channel name that fired.\r\n * - `payload` — the text payload (may be null if NOTIFY was sent without one).\r\n * - `processId` — the PID of the Postgres backend that called NOTIFY.\r\n */\r\nexport interface BrowserRealtimeNotification {\r\n channel: string;\r\n payload: string | null;\r\n processId: number;\r\n}\r\n\r\n/**\r\n * Connection status of a realtime subscription.\r\n *\r\n * - `\"connecting\"` — establishing or re-establishing the SSE stream.\r\n * - `\"connected\"` — stream is open, heartbeats are arriving, NOTIFY events are flowing.\r\n * - `\"reconnecting\"` — the stream dropped and the SDK is waiting before the next retry.\r\n * - `\"disconnected\"` — permanently stopped (via `unsubscribe()`, `signal` abort, or max retries exceeded).\r\n */\r\nexport type BrowserRealtimeStatus =\r\n | \"connecting\"\r\n | \"connected\"\r\n | \"reconnecting\"\r\n | \"disconnected\";\r\n\r\nexport interface BrowserRealtimeSubscribeParams {\r\n databaseInstanceId?: string;\r\n /** Channel names (normalized to lowercase on the server). */\r\n channels: string[];\r\n /** When aborted, the subscription stops permanently (equivalent to calling `unsubscribe()`). */\r\n signal?: AbortSignal;\r\n\r\n // ── Callbacks ──\r\n\r\n /** Called each time a Postgres NOTIFY message arrives. */\r\n onNotify?: (msg: BrowserRealtimeNotification) => void;\r\n /** Called once per connection attempt when the server confirms LISTEN is active. */\r\n onReady?: (channels: string[]) => void;\r\n /** Called when the stream encounters a non-retryable error or the server sends an error event. */\r\n onError?: (message: string) => void;\r\n /** Called whenever the connection status changes (connecting → connected → reconnecting → …). */\r\n onStatusChange?: (status: BrowserRealtimeStatus) => void;\r\n /** Called when the stream drops and the SDK will attempt to reconnect. `attempt` is 1-indexed. */\r\n onDisconnect?: (info: { attempt: number; retryInMs: number }) => void;\r\n /** Called when a reconnect attempt succeeds (stream is open again). */\r\n onReconnect?: (info: { attempt: number }) => void;\r\n\r\n // ── Reconnect tuning (safe defaults; override for advanced use) ──\r\n\r\n /** Maximum number of reconnect attempts before giving up. Set `0` to disable reconnect. Default: **Infinity** (never stops). */\r\n maxReconnectAttempts?: number;\r\n /** Base delay for exponential backoff (ms). Default: **1000**. */\r\n reconnectBaseDelayMs?: number;\r\n /** Maximum delay between reconnect attempts (ms). Default: **30000**. */\r\n reconnectMaxDelayMs?: number;\r\n /** How long to wait without a heartbeat before considering the connection dead (ms). Default: **45000** (3× the server's 15 s heartbeat interval). */\r\n heartbeatTimeoutMs?: number;\r\n}\r\n\r\n/**\r\n * Handle returned by `database.realtime.subscribe()`.\r\n *\r\n * - Call `unsubscribe()` to permanently close the subscription (no more reconnects).\r\n * - Read `status` to check the current connection state at any time.\r\n */\r\nexport interface BrowserRealtimeSubscription {\r\n unsubscribe: () => void;\r\n readonly status: BrowserRealtimeStatus;\r\n}\r\n\r\nfunction followAbortSignal(\r\n parent: AbortSignal | undefined,\r\n child: AbortController,\r\n): void {\r\n if (!parent) return;\r\n if (parent.aborted) {\r\n child.abort();\r\n return;\r\n }\r\n parent.addEventListener(\"abort\", () => child.abort(), { once: true });\r\n}\r\n\r\nfunction backoffDelay(\r\n attempt: number,\r\n baseMs: number,\r\n maxMs: number,\r\n): number {\r\n const exp = Math.min(baseMs * 2 ** (attempt - 1), maxMs);\r\n const jitter = exp * (0.5 + Math.random() * 0.5);\r\n return Math.round(jitter);\r\n}\r\n\r\nasync function subscribeBrowserRealtime(\r\n options: RagableBrowserClientOptions,\r\n ragableAuth: RagableAuth | null,\r\n fetchImpl: typeof fetch,\r\n params: BrowserRealtimeSubscribeParams,\r\n): Promise<BrowserRealtimeSubscription> {\r\n const gid = requireAuthGroupId(options);\r\n const databaseInstanceId =\r\n params.databaseInstanceId?.trim() || options.databaseInstanceId?.trim();\r\n if (!databaseInstanceId) {\r\n throw new RagableError(\r\n \"realtime.subscribe requires databaseInstanceId in params or on createBrowserClient({ databaseInstanceId })\",\r\n 400,\r\n { code: \"SDK_MISSING_DATABASE_INSTANCE_ID\" },\r\n );\r\n }\r\n if (!Array.isArray(params.channels) || params.channels.length === 0) {\r\n throw new RagableError(\r\n \"realtime.subscribe requires a non-empty channels array\",\r\n 400,\r\n { code: \"SDK_REALTIME_CHANNELS_REQUIRED\" },\r\n );\r\n }\r\n\r\n const maxAttempts = params.maxReconnectAttempts ?? Infinity;\r\n const baseDelay = params.reconnectBaseDelayMs ?? 1_000;\r\n const maxDelay = params.reconnectMaxDelayMs ?? 30_000;\r\n const heartbeatTimeout = params.heartbeatTimeoutMs ?? 45_000;\r\n\r\n const lifecycleAc = new AbortController();\r\n followAbortSignal(params.signal, lifecycleAc);\r\n\r\n let currentStatus: BrowserRealtimeStatus = \"connecting\";\r\n const setStatus = (s: BrowserRealtimeStatus) => {\r\n if (s === currentStatus) return;\r\n currentStatus = s;\r\n params.onStatusChange?.(s);\r\n };\r\n\r\n const subscription: BrowserRealtimeSubscription = {\r\n unsubscribe: () => lifecycleAc.abort(),\r\n get status() {\r\n return currentStatus;\r\n },\r\n };\r\n\r\n setStatus(\"connecting\");\r\n\r\n async function connectOnce(\r\n signal: AbortSignal,\r\n ): Promise<\"stream_ended\" | \"aborted\"> {\r\n const token = await resolveDatabaseAuthBearer(options, ragableAuth);\r\n const headers = new Headers(options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n\r\n const response = await fetchImpl(\r\n `${normalizeBrowserApiBase()}/auth-groups/${gid}/data/realtime/stream`,\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({\r\n databaseInstanceId,\r\n channels: params.channels,\r\n }),\r\n signal,\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n const streamBody = response.body;\r\n if (!streamBody) {\r\n throw new RagableError(\"Realtime stream has no body\", 502, {\r\n code: \"SDK_REALTIME_NO_BODY\",\r\n });\r\n }\r\n\r\n let heartbeatTimer: ReturnType<typeof setTimeout> | null = null;\r\n const resetHeartbeatTimer = () => {\r\n if (heartbeatTimer) clearTimeout(heartbeatTimer);\r\n heartbeatTimer = setTimeout(() => {\r\n streamReader?.cancel().catch(() => undefined);\r\n }, heartbeatTimeout);\r\n };\r\n\r\n let streamReader: ReadableStreamDefaultReader<Uint8Array> | null = null;\r\n\r\n try {\r\n streamReader = streamBody.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = \"\";\r\n resetHeartbeatTimer();\r\n\r\n const processEvent = (evt: { type: string; [k: string]: unknown }) => {\r\n if (evt.type === \"realtime:heartbeat\") {\r\n resetHeartbeatTimer();\r\n return;\r\n }\r\n resetHeartbeatTimer();\r\n if (evt.type === \"realtime:ready\") {\r\n const ch = evt.channels;\r\n setStatus(\"connected\");\r\n params.onReady?.(\r\n Array.isArray(ch) ? ch.map((c) => String(c)) : [],\r\n );\r\n } else if (evt.type === \"notify\") {\r\n params.onNotify?.({\r\n channel: String(evt.channel ?? \"\"),\r\n payload:\r\n evt.payload === undefined || evt.payload === null\r\n ? null\r\n : String(evt.payload),\r\n processId: Number(evt.processId ?? 0),\r\n });\r\n } else if (evt.type === \"realtime:error\") {\r\n params.onError?.(String(evt.message ?? \"Realtime error\"));\r\n }\r\n };\r\n\r\n while (true) {\r\n const { done, value } = await streamReader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n let boundary = buffer.indexOf(\"\\n\\n\");\r\n while (boundary !== -1) {\r\n const block = buffer.slice(0, boundary);\r\n buffer = buffer.slice(boundary + 2);\r\n for (const line of block.split(\"\\n\")) {\r\n const dataPrefix = \"data: \";\r\n if (!line.startsWith(dataPrefix)) continue;\r\n const json = line.slice(dataPrefix.length).trim();\r\n if (!json || json === \"[DONE]\") continue;\r\n try {\r\n processEvent(JSON.parse(json));\r\n } catch {\r\n /* malformed JSON — skip */\r\n }\r\n }\r\n boundary = buffer.indexOf(\"\\n\\n\");\r\n }\r\n }\r\n\r\n return \"stream_ended\";\r\n } finally {\r\n if (heartbeatTimer) clearTimeout(heartbeatTimer);\r\n streamReader?.releaseLock();\r\n }\r\n }\r\n\r\n void (async () => {\r\n let attempt = 0;\r\n while (!lifecycleAc.signal.aborted) {\r\n const iterAc = new AbortController();\r\n followAbortSignal(lifecycleAc.signal, iterAc);\r\n\r\n try {\r\n const result = await connectOnce(iterAc.signal);\r\n if (lifecycleAc.signal.aborted) break;\r\n if (result === \"stream_ended\") {\r\n attempt++;\r\n }\r\n } catch (e) {\r\n if (lifecycleAc.signal.aborted) break;\r\n if ((e as Error).name === \"AbortError\") break;\r\n\r\n const status = (e as RagableError).status;\r\n if (status === 400 || status === 401 || status === 403 || status === 404) {\r\n params.onError?.((e as Error).message);\r\n break;\r\n }\r\n attempt++;\r\n }\r\n\r\n if (lifecycleAc.signal.aborted) break;\r\n if (attempt > maxAttempts) {\r\n params.onError?.(`Realtime: gave up after ${maxAttempts} reconnect attempts`);\r\n break;\r\n }\r\n\r\n const delay = backoffDelay(attempt, baseDelay, maxDelay);\r\n setStatus(\"reconnecting\");\r\n params.onDisconnect?.({ attempt, retryInMs: delay });\r\n\r\n await new Promise<void>((r) => {\r\n const timer = setTimeout(r, delay);\r\n const onAbort = () => {\r\n clearTimeout(timer);\r\n r();\r\n };\r\n lifecycleAc.signal.addEventListener(\"abort\", onAbort, { once: true });\r\n });\r\n\r\n if (lifecycleAc.signal.aborted) break;\r\n setStatus(\"connecting\");\r\n params.onReconnect?.({ attempt });\r\n }\r\n\r\n setStatus(\"disconnected\");\r\n })();\r\n\r\n return subscription;\r\n}\r\n\r\n// ─── Storage client ──────────────────────────────────────────────────────────\r\n\r\nexport interface BrowserStorageItem {\r\n type: \"file\" | \"folder\";\r\n path: string;\r\n name: string;\r\n size?: string | null;\r\n contentType?: string | null;\r\n updated?: string | null;\r\n}\r\n\r\nexport interface BrowserStorageListResult {\r\n bucket: string;\r\n prefix: string;\r\n items: BrowserStorageItem[];\r\n nextPageToken: string | null;\r\n}\r\n\r\nexport interface BrowserStorageUploadResult {\r\n success: true;\r\n path: string;\r\n size: string | null;\r\n contentType: string | null;\r\n updated: string | null;\r\n}\r\n\r\nexport interface BrowserStorageDownloadResult {\r\n path: string;\r\n size: string | null;\r\n contentType: string | null;\r\n updated: string | null;\r\n encoding: string;\r\n contentsBase64: string;\r\n text: string | null;\r\n textIncluded: boolean;\r\n}\r\n\r\nexport interface BrowserStorageSignedUrlResult {\r\n url: string;\r\n method: string;\r\n expiresInSeconds: number;\r\n objectPath: string;\r\n}\r\n\r\nexport interface BrowserStorageBulkDeleteResult {\r\n success: boolean;\r\n totalRequested: number;\r\n uniquePaths: number;\r\n deleted: string[];\r\n errors: Array<{ path: string; error: string }>;\r\n}\r\n\r\nexport class BrowserStorageBucketClient {\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly fetchImpl: typeof fetch,\r\n private readonly bucketId: string,\r\n private readonly ragableAuth: RagableAuth | null = null,\r\n ) {}\r\n\r\n private get authGroupId(): string {\r\n const id = this.options.authGroupId?.trim();\r\n if (!id) throw new RagableError(\"authGroupId is required for storage\", 400, { code: \"SDK_MISSING_AUTH_GROUP_ID\" });\r\n return id;\r\n }\r\n\r\n private base(): string {\r\n return `${normalizeBrowserApiBase()}/auth-groups/${this.authGroupId}/storage/buckets/${encodeURIComponent(this.bucketId)}`;\r\n }\r\n\r\n /**\r\n * Same credential resolution as the database client (see resolveDatabaseAuthBearer):\r\n * in the generated-site default (`auto`), a signed-in user's auto-refreshed JWT\r\n * is used so storage calls carry the user's identity; logged-out visitors fall\r\n * back to the anon key. Previously storage ignored the managed session entirely.\r\n */\r\n private async bearerToken(): Promise<string> {\r\n return resolveDatabaseAuthBearer(this.options, this.ragableAuth);\r\n }\r\n\r\n /**\r\n * The storage backend has historically returned HTTP 200 with an `{ error }`\r\n * body on some failures; without this guard the SDK would resolve those as\r\n * successful uploads/deletes. Treat any 2xx whose body carries a non-empty\r\n * `error` as a failure.\r\n */\r\n private assertNoEmbeddedError(payload: unknown, status: number): void {\r\n if (payload && typeof payload === \"object\" && !Array.isArray(payload)) {\r\n const err = (payload as Record<string, unknown>).error;\r\n if (typeof err === \"string\" && err.trim()) {\r\n throw new RagableError(err, status, payload);\r\n }\r\n }\r\n }\r\n\r\n private async req<T>(method: string, path: string, body?: unknown): Promise<T> {\r\n const token = await this.bearerToken();\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n if (body !== undefined && !(body instanceof FormData)) headers.set(\"Content-Type\", \"application/json\");\r\n const res = await this.fetchImpl(`${this.base()}${path}`, {\r\n method,\r\n headers,\r\n body: body instanceof FormData ? body : body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n const payload = await res.json().catch(() => ({}));\r\n if (!res.ok) throw new RagableError(extractErrorMessage(payload, res.statusText), res.status, payload);\r\n this.assertNoEmbeddedError(payload, res.status);\r\n return payload as T;\r\n }\r\n\r\n list(params: { prefix?: string; delimiter?: string; maxResults?: number; pageToken?: string } = {}): Promise<BrowserStorageListResult> {\r\n const qs = new URLSearchParams();\r\n if (params.prefix) qs.set(\"prefix\", params.prefix);\r\n if (params.delimiter) qs.set(\"delimiter\", params.delimiter);\r\n if (params.maxResults != null) qs.set(\"maxResults\", String(params.maxResults));\r\n if (params.pageToken) qs.set(\"pageToken\", params.pageToken);\r\n const q = qs.toString();\r\n return this.req(\"GET\", `/contents${q ? `?${q}` : \"\"}`);\r\n }\r\n\r\n async upload(params: { objectPath: string; file: Blob | ArrayBuffer | Uint8Array; fileName?: string; contentType?: string; cacheControl?: string }): Promise<BrowserStorageUploadResult> {\r\n const token = await this.bearerToken();\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n const form = new FormData();\r\n const raw = params.file instanceof Blob ? params.file : new Blob([new Uint8Array(params.file instanceof ArrayBuffer ? params.file : (params.file as Uint8Array).buffer as ArrayBuffer)], params.contentType ? { type: params.contentType } : {});\r\n const blob = raw;\r\n form.set(\"file\", blob, params.fileName ?? \"upload\");\r\n form.set(\"objectPath\", params.objectPath);\r\n if (params.cacheControl) form.set(\"cacheControl\", params.cacheControl);\r\n const res = await this.fetchImpl(`${this.base()}/upload`, { method: \"POST\", headers, body: form });\r\n const payload = await res.json().catch(() => ({}));\r\n if (!res.ok) throw new RagableError(extractErrorMessage(payload, res.statusText), res.status, payload);\r\n this.assertNoEmbeddedError(payload, res.status);\r\n return payload as BrowserStorageUploadResult;\r\n }\r\n\r\n download(params: { objectPath: string; asText?: boolean; maxTextBytes?: number }): Promise<BrowserStorageDownloadResult> {\r\n const qs = new URLSearchParams({ objectPath: params.objectPath });\r\n if (params.asText != null) qs.set(\"asText\", String(params.asText));\r\n if (params.maxTextBytes != null) qs.set(\"maxTextBytes\", String(params.maxTextBytes));\r\n return this.req(\"GET\", `/objects/download?${qs}`);\r\n }\r\n\r\n delete(objectPath: string): Promise<{ success: true; path: string }> {\r\n return this.req(\"DELETE\", \"/objects\", { objectPath });\r\n }\r\n\r\n bulkDelete(objectPaths: string[]): Promise<BrowserStorageBulkDeleteResult> {\r\n return this.req(\"POST\", \"/objects/delete-bulk\", { objectPaths });\r\n }\r\n\r\n getSignedUploadUrl(params: { objectPath: string; contentType?: string; expiresInSeconds?: number }): Promise<BrowserStorageSignedUrlResult> {\r\n return this.req(\"POST\", \"/signed-upload-url\", params);\r\n }\r\n\r\n getSignedDownloadUrl(params: { objectPath: string; expiresInSeconds?: number }): Promise<BrowserStorageSignedUrlResult> {\r\n const qs = new URLSearchParams({ objectPath: params.objectPath });\r\n if (params.expiresInSeconds != null) qs.set(\"expiresInSeconds\", String(params.expiresInSeconds));\r\n return this.req(\"GET\", `/signed-download-url?${qs}`);\r\n }\r\n\r\n copy(params: { sourcePath: string; destinationPath: string }): Promise<{ success: true; sourcePath: string; destinationPath: string }> {\r\n return this.req(\"POST\", \"/objects/copy\", params);\r\n }\r\n\r\n move(params: { sourcePath: string; destinationPath: string }): Promise<{ success: true; sourcePath: string; destinationPath: string }> {\r\n return this.req(\"POST\", \"/objects/move\", params);\r\n }\r\n\r\n createFolder(folderPath: string): Promise<{ success: true; folderPath: string }> {\r\n return this.req(\"POST\", \"/folders\", { folderPath });\r\n }\r\n\r\n deleteFolder(folderPath: string): Promise<{ success: true; folderPath: string }> {\r\n return this.req(\"DELETE\", \"/folders\", { folderPath });\r\n }\r\n\r\n getMetadata(objectPath: string): Promise<{ name: string; contentType: string | null; size: string | null; updated: string | null; metadata?: Record<string, string> }> {\r\n const qs = new URLSearchParams({ objectPath });\r\n return this.req(\"GET\", `/objects/metadata?${qs}`);\r\n }\r\n}\r\n\r\nexport class RagableBrowserStorageClient {\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly fetchImpl: typeof fetch,\r\n private readonly ragableAuth: RagableAuth | null = null,\r\n ) {}\r\n\r\n from(bucketId: string): BrowserStorageBucketClient {\r\n return new BrowserStorageBucketClient(\r\n this.options,\r\n this.fetchImpl,\r\n bucketId,\r\n this.ragableAuth,\r\n );\r\n }\r\n}\r\n\r\n// ─── Mail client ─────────────────────────────────────────────────────────────\r\n\r\nexport interface MailSendParams {\r\n to: string[];\r\n cc?: string[];\r\n bcc?: string[];\r\n subject: string;\r\n /** Plain-text body. At least one of `bodyText` / `bodyHtml` is required. */\r\n bodyText?: string;\r\n /** HTML body. If both are set, sent as multipart/alternative. */\r\n bodyHtml?: string;\r\n /** RFC 822 Message-ID of the message you're replying to (enables threading). */\r\n inReplyToMessageId?: string;\r\n /** Existing References header value, chained with In-Reply-To. */\r\n referencesHeader?: string;\r\n}\r\n\r\nexport interface MailSendResult {\r\n sentMailMessageId: string;\r\n gmailMessageId: string;\r\n gmailThreadId: string;\r\n fromAddress: string;\r\n}\r\n\r\nexport interface MailSearchParams {\r\n /** Gmail search syntax, e.g. `from:alice is:unread newer_than:7d`. */\r\n query?: string;\r\n /** 1–50; default 20. */\r\n maxResults?: number;\r\n pageToken?: string;\r\n labelIds?: string[];\r\n}\r\n\r\nexport interface MailMessagePreview {\r\n id: string;\r\n threadId: string;\r\n snippet: string;\r\n labelIds: string[];\r\n}\r\n\r\nexport interface MailMessageDetail {\r\n id: string;\r\n threadId: string;\r\n receivedAt: number;\r\n fromAddress: string;\r\n fromName: string | null;\r\n to: string[];\r\n cc: string[];\r\n subject: string;\r\n snippet: string;\r\n bodyText: string | null;\r\n bodyHtml: string | null;\r\n messageIdHeader: string | null;\r\n referencesHeader: string | null;\r\n labelIds: string[];\r\n}\r\n\r\n/**\r\n * Send and read email through the Gmail account linked to this Ragable\r\n * website (via the IDE Infrastructure → Integrations tab).\r\n *\r\n * All requests require a Bearer token — either an end-user JWT from this\r\n * website's auth group (call `client.auth.signIn(...)` first) or the\r\n * data-admin key (server-side use).\r\n *\r\n * The website MUST have:\r\n * 1. A Gmail account linked under Integrations\r\n * 2. An auth group linked under Auth\r\n *\r\n * Otherwise calls return a 412 with a clear error message.\r\n */\r\nexport class RagableBrowserMailClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly auth: RagableAuth | null,\r\n ) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const websiteId = this.options.websiteId?.trim();\r\n if (!websiteId) {\r\n throw new RagableError(\r\n \"websiteId is required for mail operations. Use createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return websiteId;\r\n }\r\n\r\n private pathTo(p: string): string {\r\n const websiteId = this.requireWebsiteId();\r\n const orgId = this.options.organizationId;\r\n return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/mail${\r\n p.startsWith(\"/\") ? p : `/${p}`\r\n }`;\r\n }\r\n\r\n /**\r\n * Get the Bearer token used to authenticate the call:\r\n * 1. End-user access token (preferred when an auth group is configured\r\n * and the user has signed in)\r\n * 2. `dataStaticKey` from createBrowserClient options\r\n * 3. Caller-supplied `getAccessToken()`\r\n *\r\n * If none is available, throws — server-side use should pass the\r\n * data-admin key as `dataStaticKey`.\r\n */\r\n private async getBearerToken(): Promise<string> {\r\n if (this.auth) {\r\n const token = await this.auth.getValidAccessToken().catch(() => null);\r\n if (token) return token;\r\n }\r\n const callerProvided = await this.options.getAccessToken?.();\r\n if (typeof callerProvided === \"string\" && callerProvided.length > 0) {\r\n return callerProvided;\r\n }\r\n if (this.options.dataStaticKey?.trim()) {\r\n return this.options.dataStaticKey.trim();\r\n }\r\n throw new RagableError(\r\n \"Mail requests need authentication: either sign in via client.auth.signIn(...) or pass dataStaticKey (the auth group data-admin key) when creating the client.\",\r\n 401,\r\n { code: \"SDK_MAIL_NOT_AUTHENTICATED\" },\r\n );\r\n }\r\n\r\n private async request<T>(\r\n path: string,\r\n init: RequestInit & { headers?: HeadersInit } = {},\r\n ): Promise<T> {\r\n const token = await this.getBearerToken();\r\n const headers = new Headers(init.headers ?? this.options.headers);\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n if (init.body && !headers.has(\"Content-Type\")) {\r\n headers.set(\"Content-Type\", \"application/json\");\r\n }\r\n const response = await this.fetchImpl(this.pathTo(path), {\r\n ...init,\r\n headers,\r\n });\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n }\r\n\r\n /** Send an email from this website's linked Gmail account. */\r\n async send(params: MailSendParams): Promise<MailSendResult> {\r\n if (!params.to?.length) {\r\n throw new RagableError(\r\n \"`to` must contain at least one recipient.\",\r\n 400,\r\n { code: \"SDK_MAIL_NO_RECIPIENTS\" },\r\n );\r\n }\r\n if (!params.bodyText && !params.bodyHtml) {\r\n throw new RagableError(\r\n \"Provide at least one of `bodyText` or `bodyHtml`.\",\r\n 400,\r\n { code: \"SDK_MAIL_NO_BODY\" },\r\n );\r\n }\r\n return this.request<MailSendResult>(\"/send\", {\r\n method: \"POST\",\r\n body: JSON.stringify(params),\r\n });\r\n }\r\n\r\n /** Search messages with Gmail query syntax. */\r\n async search(\r\n params: MailSearchParams = {},\r\n ): Promise<{ messages: MailMessagePreview[]; nextPageToken: string | null }> {\r\n const qs = new URLSearchParams();\r\n if (params.query) qs.set(\"q\", params.query);\r\n if (params.maxResults) qs.set(\"maxResults\", String(params.maxResults));\r\n if (params.pageToken) qs.set(\"pageToken\", params.pageToken);\r\n if (params.labelIds?.length) qs.set(\"labelIds\", params.labelIds.join(\",\"));\r\n const suffix = qs.toString() ? `?${qs.toString()}` : \"\";\r\n return this.request<{\r\n messages: MailMessagePreview[];\r\n nextPageToken: string | null;\r\n }>(`/search${suffix}`, { method: \"GET\" });\r\n }\r\n\r\n /** Fetch a single message in full (headers + decoded text/html body). */\r\n async getMessage(messageId: string): Promise<MailMessageDetail> {\r\n if (!messageId) {\r\n throw new RagableError(\"`messageId` is required.\", 400, {\r\n code: \"SDK_MAIL_NO_MESSAGE_ID\",\r\n });\r\n }\r\n const { message } = await this.request<{ message: MailMessageDetail }>(\r\n `/messages/${encodeURIComponent(messageId)}`,\r\n { method: \"GET\" },\r\n );\r\n return message;\r\n }\r\n}\r\n\r\n// ─── Functions client (backend edge functions) ──────────────────────────────\r\n\r\n/**\r\n * Invokes the project's backend edge functions (handlers in `/functions/<name>.ts`).\r\n *\r\n * Exposed on the client as a typed Proxy — `client.functions.<name>(input)` — so\r\n * each generated function name is a direct callable. Functions run server-side,\r\n * so calls can use secrets and reach any external API without browser CORS limits.\r\n */\r\nexport class RagableBrowserFunctionsClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(\r\n private readonly options: RagableBrowserClientOptions,\r\n private readonly auth: RagableAuth | null,\r\n ) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const websiteId = this.options.websiteId?.trim();\r\n if (!websiteId) {\r\n throw new RagableError(\r\n \"websiteId is required for functions. Use createWebsiteRagableClient()/createAppClient() or pass createBrowserClient({ websiteId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return websiteId;\r\n }\r\n\r\n private toUrl(name: string): string {\r\n const orgId = this.options.organizationId;\r\n const websiteId = this.requireWebsiteId();\r\n return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/functions/${encodeURIComponent(\r\n name,\r\n )}/invoke`;\r\n }\r\n\r\n /**\r\n * Best-effort end-user bearer, forwarded to the function as `context.auth.token`.\r\n * Functions are public, so this never throws — anonymous calls send no token.\r\n */\r\n private async getOptionalToken(): Promise<string | null> {\r\n if (this.auth) {\r\n const token = await this.auth.getValidAccessToken().catch(() => null);\r\n if (token) return token;\r\n }\r\n const caller = await Promise.resolve(this.options.getAccessToken?.()).catch(\r\n () => null,\r\n );\r\n if (typeof caller === \"string\" && caller.trim()) return caller.trim();\r\n const staticKey = this.options.dataStaticKey?.trim();\r\n if (staticKey) return staticKey;\r\n return null;\r\n }\r\n\r\n /**\r\n * Invoke a function by name. Prefer the typed `client.functions.<name>(input)`\r\n * accessors; use this when the name is dynamic.\r\n */\r\n async invoke<Result = unknown>(\r\n name: string,\r\n input?: unknown,\r\n options?: RagableFunctionInvokeOptions,\r\n ): Promise<Result> {\r\n const fnName = String(name ?? \"\").trim();\r\n if (!fnName) {\r\n throw new RagableError(\r\n \"functions.invoke requires a function name\",\r\n 400,\r\n { code: \"SDK_MISSING_FUNCTION_NAME\" },\r\n );\r\n }\r\n const headers = new Headers(options?.headers ?? this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n const token = await this.getOptionalToken();\r\n if (token) headers.set(\"Authorization\", `Bearer ${token}`);\r\n\r\n const response = await this.fetchImpl(this.toUrl(fnName), {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({ input: input ?? null }),\r\n ...(options?.signal ? { signal: options.signal } : {}),\r\n });\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n // The route wraps handler output as `{ result }`. Fall back to the raw body\r\n // for forward-compat if that envelope ever changes.\r\n if (\r\n payload &&\r\n typeof payload === \"object\" &&\r\n !Array.isArray(payload) &&\r\n \"result\" in (payload as Record<string, unknown>)\r\n ) {\r\n return (payload as { result: Result }).result;\r\n }\r\n return payload as Result;\r\n }\r\n\r\n /** Build the typed Proxy exposed as `client.functions`. */\r\n asInvoker<F extends RagableFunctions = DefaultRagableFunctions>(): FunctionInvoker<F> {\r\n const invoke = this.invoke.bind(this);\r\n return new Proxy(\r\n {},\r\n {\r\n get: (_target, prop) => {\r\n if (typeof prop !== \"string\") return undefined;\r\n // Don't masquerade as a thenable when awaited/inspected.\r\n if (prop === \"then\") return undefined;\r\n if (prop === \"invoke\") {\r\n return (\r\n name: string,\r\n input?: unknown,\r\n options?: RagableFunctionInvokeOptions,\r\n ) => invoke(name, input, options);\r\n }\r\n return (input?: unknown, options?: RagableFunctionInvokeOptions) =>\r\n invoke(prop, input, options);\r\n },\r\n },\r\n ) as FunctionInvoker<F>;\r\n }\r\n}\r\n\r\n// ─── Agents client ───────────────────────────────────────────────────────────\r\n\r\nexport interface AgentConversationMessage {\r\n role: \"user\" | \"assistant\";\r\n content: string;\r\n file_urls?: string[];\r\n}\r\n\r\nexport interface AgentConversation {\r\n id: string;\r\n agent_name: string;\r\n agentName: string;\r\n title: string | null;\r\n metadata: unknown;\r\n messages: AgentConversationMessage[];\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\nexport interface AgentConversationSubscription {\r\n unsubscribe: () => void;\r\n}\r\n\r\nexport class RagableBrowserAgentsClient {\r\n private readonly fetchImpl: typeof fetch;\r\n\r\n constructor(private readonly options: RagableBrowserClientOptions) {\r\n this.fetchImpl = bindFetch(options.fetch);\r\n }\r\n\r\n private toUrl(path: string): string {\r\n return `${normalizeBrowserApiBase()}${path.startsWith(\"/\") ? path : `/${path}`}`;\r\n }\r\n\r\n private requireWebsiteId(): string {\r\n const websiteId = this.options.websiteId?.trim();\r\n if (!websiteId) {\r\n throw new RagableError(\r\n \"websiteId is required for project agent conversation APIs. Use the generated createWebsiteRagableClient() or pass createBrowserClient({ websiteId, ... }).\",\r\n 400,\r\n { code: \"SDK_MISSING_WEBSITE_ID\" },\r\n );\r\n }\r\n return websiteId;\r\n }\r\n\r\n private websiteAgentPath(path: string): string {\r\n const websiteId = this.requireWebsiteId();\r\n return `/public/organizations/${this.options.organizationId}/websites/${websiteId}${path}`;\r\n }\r\n\r\n private async requestJson<T>(path: string, init: RequestInit = {}): Promise<T> {\r\n const response = await this.fetchImpl(this.toUrl(path), init);\r\n const payload = await parseMaybeJsonBody(response);\r\n if (!response.ok) {\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n return payload as T;\r\n }\r\n\r\n /** @deprecated Prefer `chatStreamByName(agentName, params)` for project-local `/agents/*.json` agents. */\r\n async *chatStream(\r\n agentId: string,\r\n params: AgentPublicChatParams,\r\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\r\n const orgId = this.options.organizationId;\r\n const body: Record<string, unknown> = {\r\n message: params.message,\r\n ...(params.history !== undefined ? { history: params.history } : {}),\r\n ...(params.triggerSubtype !== undefined\r\n ? { triggerSubtype: params.triggerSubtype }\r\n : {}),\r\n ...(params.triggerNodeId !== undefined\r\n ? { triggerNodeId: params.triggerNodeId }\r\n : {}),\r\n };\r\n\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n\r\n const response = await this.fetchImpl(\r\n this.toUrl(`/public/organizations/${orgId}/agents/${agentId}/chat/stream`),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(body),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n const streamBody = response.body;\r\n if (!streamBody) {\r\n return;\r\n }\r\n\r\n yield* readSseStream(streamBody);\r\n }\r\n\r\n /**\r\n * Stream a project agent defined in `agents/*.json` using the same result\r\n * shape as `client.ai.streamText`. Preferred over {@link chatStreamByName}\r\n * and {@link runChatStreamByName} — those remain for back-compat only.\r\n *\r\n * ```ts\r\n * const { textStream, text } = client.agents.run(\"support\", {\r\n * messages: [{ role: \"user\", content: \"I can't log in\" }],\r\n * });\r\n * for await (const delta of textStream) process.stdout.write(delta);\r\n * console.log(await text);\r\n * ```\r\n */\r\n run(\r\n agentName: string,\r\n params: { messages: Message[]; signal?: AbortSignal },\r\n ): StreamTextResult {\r\n const source = this.runStreamParts(agentName, params);\r\n return createStreamResultFromParts(source);\r\n }\r\n\r\n /**\r\n * Same agent, same tools/instructions/RAG — but constrain the final output\r\n * to a JSON Schema. Matches `client.ai.streamObject` exactly so callers can\r\n * swap between raw inference and an agent without changing call shape.\r\n *\r\n * Tool calling and structured output are **compatible**: the model may call\r\n * the agent's tools as usual; the final assistant message is the schema-\r\n * conformant JSON. The agent's `agents/<name>.json` is unchanged — whether\r\n * the run is conversational or structured is decided by the call site.\r\n *\r\n * ```ts\r\n * const { partialObjectStream, object } = client.agents.runObject<Plan>(\r\n * \"planner\",\r\n * {\r\n * messages: [{ role: \"user\", content: \"Plan a 3-day trip to Kyoto.\" }],\r\n * schema: {\r\n * type: \"object\",\r\n * properties: {\r\n * days: {\r\n * type: \"array\",\r\n * items: { type: \"object\", properties: { date: { type: \"string\" }, activities: { type: \"array\", items: { type: \"string\" } } } },\r\n * },\r\n * },\r\n * required: [\"days\"],\r\n * },\r\n * },\r\n * );\r\n * for await (const p of partialObjectStream) renderPreview(p);\r\n * console.log(await object);\r\n * ```\r\n */\r\n runObject<T = unknown>(\r\n agentName: string,\r\n params: {\r\n messages: Message[];\r\n schema: JsonSchema;\r\n schemaName?: string;\r\n schemaDescription?: string;\r\n signal?: AbortSignal;\r\n },\r\n ): StreamObjectResult<T> {\r\n const responseFormat = buildResponseFormat({\r\n schema: params.schema,\r\n ...(params.schemaName !== undefined ? { name: params.schemaName } : {}),\r\n ...(params.schemaDescription !== undefined\r\n ? { description: params.schemaDescription }\r\n : {}),\r\n });\r\n const sourceParts = this.runStreamParts(agentName, {\r\n messages: params.messages,\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n responseFormat,\r\n });\r\n const inner = createStreamResultFromParts(sourceParts);\r\n return wrapStreamTextAsObject<T>(inner);\r\n }\r\n\r\n /** Non-streaming variant of {@link runObject}. */\r\n async generateObject<T = unknown>(\r\n agentName: string,\r\n params: {\r\n messages: Message[];\r\n schema: JsonSchema;\r\n schemaName?: string;\r\n schemaDescription?: string;\r\n signal?: AbortSignal;\r\n },\r\n ): Promise<GenerateObjectResult<T>> {\r\n const result = this.runObject<T>(agentName, params);\r\n for await (const _ of result.partialObjectStream) void _;\r\n const [object, usage, finishReason, toolCalls] = await Promise.all([\r\n result.object,\r\n result.usage,\r\n result.finishReason,\r\n result.toolCalls,\r\n ]);\r\n return { object, usage, finishReason, toolCalls };\r\n }\r\n\r\n private async *runStreamParts(\r\n agentName: string,\r\n params: {\r\n messages: Message[];\r\n signal?: AbortSignal;\r\n /** Optional per-call response_format (Fireworks json_schema shape). */\r\n responseFormat?: Record<string, unknown>;\r\n },\r\n ): AsyncGenerator<StreamPart, void, undefined> {\r\n const { messages } = params;\r\n if (!Array.isArray(messages) || messages.length === 0) {\r\n throw new RagableError(\r\n \"agents.run requires at least one message\",\r\n 400,\r\n { code: \"SDK_AGENTS_RUN_EMPTY_MESSAGES\" },\r\n );\r\n }\r\n const last = messages[messages.length - 1];\r\n if (!last || last.role !== \"user\") {\r\n throw new RagableError(\r\n 'agents.run: the final message must have role \"user\"',\r\n 400,\r\n { code: \"SDK_AGENTS_RUN_INVALID_LAST_MESSAGE\" },\r\n );\r\n }\r\n const history = messages\r\n .slice(0, -1)\r\n .filter((m) => m.role === \"user\" || m.role === \"assistant\")\r\n .map((m) => ({\r\n role: m.role as \"user\" | \"assistant\",\r\n content: m.content,\r\n }));\r\n\r\n // Inlined SSE fetch (bypasses chatStreamByName) so we can carry\r\n // response_format on the wire without changing the deprecated method.\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n const body: Record<string, unknown> = {\r\n message: last.content,\r\n ...(history.length > 0 ? { history } : {}),\r\n ...(params.responseFormat\r\n ? { response_format: params.responseFormat }\r\n : {}),\r\n };\r\n const response = await this.fetchImpl(\r\n this.toUrl(\r\n this.websiteAgentPath(\r\n `/agents/${encodeURIComponent(agentName)}/chat/stream`,\r\n ),\r\n ),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(body),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n },\r\n );\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n if (!response.body) return;\r\n for await (const event of readSseStream(response.body)) {\r\n const mapped = mapAgentEvent(event);\r\n if (mapped) yield mapped;\r\n }\r\n }\r\n\r\n /**\r\n * @deprecated Use {@link run} for new code. This method is kept for\r\n * back-compat with the original chat-stream DX.\r\n */\r\n async *chatStreamByName(\r\n agentName: string,\r\n params: AgentChatParams,\r\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n const response = await this.fetchImpl(\r\n this.toUrl(\r\n this.websiteAgentPath(\r\n `/agents/${encodeURIComponent(agentName)}/chat/stream`,\r\n ),\r\n ),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify({\r\n message: params.message,\r\n ...(params.history !== undefined ? { history: params.history } : {}),\r\n }),\r\n ...(params.signal !== undefined ? { signal: params.signal } : {}),\r\n },\r\n );\r\n\r\n if (!response.ok) {\r\n const payload = await parseMaybeJsonBody(response);\r\n const message = extractErrorMessage(payload, response.statusText);\r\n throw new RagableError(message, response.status, payload);\r\n }\r\n\r\n if (!response.body) return;\r\n yield* readSseStream(response.body);\r\n }\r\n\r\n /**\r\n * @deprecated Use {@link run} for new code. Returns the legacy callback-based\r\n * result type leaking server internals; the new Vercel-style API exposes\r\n * `textStream` / `fullStream` / promises for `text`, `usage`, `finishReason`.\r\n */\r\n async runChatStreamByName(\r\n agentName: string,\r\n params: AgentChatParams,\r\n handlers: AgentChatStreamHandlers = {},\r\n ): Promise<AgentChatStreamResult> {\r\n return runAgentChatStream(this.chatStreamByName(agentName, params), handlers, {\r\n signal: params.signal,\r\n });\r\n }\r\n\r\n /**\r\n * Same as {@link runChatStreamByName} but folds events into `AgentChat`-style segments\r\n * (`onSegments` / `onStreamingText`) and returns a history-ready assistant message.\r\n */\r\n async runChatUiByName(\r\n agentName: string,\r\n params: AgentChatParams,\r\n handlers: AgentChatStreamUiHandlers = {},\r\n ): Promise<AgentChatUiStreamResult> {\r\n return runAgentChatStreamForUi(\r\n this.chatStreamByName(agentName, params),\r\n handlers,\r\n { signal: params.signal },\r\n );\r\n }\r\n\r\n createConversation(params: {\r\n agent_name?: string;\r\n agentName?: string;\r\n title?: string | null;\r\n metadata?: unknown;\r\n }): Promise<AgentConversation> {\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\"/agent-conversations\"),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(params),\r\n },\r\n );\r\n }\r\n\r\n listConversations(params: {\r\n agent_name?: string;\r\n agentName?: string;\r\n } = {}): Promise<AgentConversation[]> {\r\n const agentName = params.agent_name ?? params.agentName;\r\n const qs = agentName\r\n ? `?agentName=${encodeURIComponent(agentName)}`\r\n : \"\";\r\n return this.requestJson<AgentConversation[]>(\r\n this.websiteAgentPath(`/agent-conversations${qs}`),\r\n );\r\n }\r\n\r\n getConversation(conversationId: string): Promise<AgentConversation> {\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\r\n `/agent-conversations/${encodeURIComponent(conversationId)}`,\r\n ),\r\n );\r\n }\r\n\r\n updateConversation(\r\n conversationId: string,\r\n data: { title?: string | null; metadata?: unknown },\r\n ): Promise<AgentConversation> {\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\r\n `/agent-conversations/${encodeURIComponent(conversationId)}`,\r\n ),\r\n {\r\n method: \"PATCH\",\r\n headers,\r\n body: JSON.stringify(data),\r\n },\r\n );\r\n }\r\n\r\n addMessage(\r\n conversationOrId: AgentConversation | string,\r\n message: AgentConversationMessage,\r\n ): Promise<AgentConversation> {\r\n const conversationId =\r\n typeof conversationOrId === \"string\" ? conversationOrId : conversationOrId.id;\r\n const headers = new Headers(this.options.headers);\r\n headers.set(\"Content-Type\", \"application/json\");\r\n return this.requestJson<AgentConversation>(\r\n this.websiteAgentPath(\r\n `/agent-conversations/${encodeURIComponent(conversationId)}/messages`,\r\n ),\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(message),\r\n },\r\n );\r\n }\r\n\r\n subscribeToConversation(\r\n conversationId: string,\r\n callback: (conversation: AgentConversation) => void,\r\n options: { intervalMs?: number } = {},\r\n ): AgentConversationSubscription {\r\n let stopped = false;\r\n let timer: ReturnType<typeof setTimeout> | null = null;\r\n const intervalMs = Math.max(500, options.intervalMs ?? 1500);\r\n const tick = async () => {\r\n if (stopped) return;\r\n try {\r\n callback(await this.getConversation(conversationId));\r\n } finally {\r\n if (!stopped) timer = setTimeout(tick, intervalMs);\r\n }\r\n };\r\n void tick();\r\n return {\r\n unsubscribe: () => {\r\n stopped = true;\r\n if (timer) clearTimeout(timer);\r\n },\r\n };\r\n }\r\n}\r\n\r\nexport interface AgentPublicChatParams extends AgentChatParams {\r\n triggerSubtype?: string;\r\n triggerNodeId?: string;\r\n}\r\n\r\n// ─── Main browser client ─────────────────────────────────────────────────────\r\n\r\nexport class RagableBrowser<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n AuthUser extends object = DefaultAuthUser,\r\n Functions extends RagableFunctions = DefaultRagableFunctions,\r\n> {\r\n readonly agents: RagableBrowserAgentsClient;\r\n readonly ai: RagableBrowserAiClient;\r\n readonly auth: RagableBrowserAuthClient<AuthUser>;\r\n readonly database: RagableBrowserDatabaseClient<Database>;\r\n readonly db: RagableBrowserDatabaseClient<Database>;\r\n readonly storage: RagableBrowserStorageClient;\r\n readonly mail: RagableBrowserMailClient;\r\n /**\r\n * Backend edge functions — call a `/functions/<name>.ts` handler with\r\n * `client.functions.<name>(input)`. Runs server-side. See {@link FunctionInvoker}.\r\n */\r\n readonly functions: FunctionInvoker<Functions>;\r\n readonly transport: Transport;\r\n private readonly _ragableAuth: RagableAuth<AuthUser> | null;\r\n\r\n constructor(options: RagableBrowserClientOptions) {\r\n this.transport = new Transport({\r\n fetch: options.fetch,\r\n headers: options.headers,\r\n ...options.transport,\r\n });\r\n\r\n if (options.authGroupId) {\r\n this._ragableAuth = new RagableAuth<AuthUser>({\r\n authGroupId: options.authGroupId,\r\n fetch: options.fetch,\r\n headers: options.headers,\r\n auth: options.auth,\r\n });\r\n\r\n // On a 401, force a single-flight refresh and retry — covers token\r\n // rotation, clock skew, and early revocation that the proactive\r\n // skew-based refresh would miss. Returns null (no retry) when there is no\r\n // user session, e.g. anonymous `publicAnon` traffic.\r\n this.transport.setRefreshHandler(async () => {\r\n const mode = effectiveDataAuth(options);\r\n if (mode !== \"user\" && mode !== \"auto\") return null;\r\n return this._ragableAuth!.getValidAccessToken(true).catch(() => null);\r\n });\r\n\r\n // Eagerly restore the persisted session so the first render and any\r\n // `onAuthStateChange` subscriber see it. Idempotent + memoized in\r\n // RagableAuth; safe to call whenever an auth group is configured.\r\n this._ragableAuth.initialize().catch(() => {});\r\n } else {\r\n this._ragableAuth = null;\r\n }\r\n\r\n this.agents = new RagableBrowserAgentsClient(options);\r\n this.ai = new RagableBrowserAiClient({\r\n organizationId: options.organizationId,\r\n ...(options.websiteId !== undefined ? { websiteId: options.websiteId } : {}),\r\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\r\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\r\n apiBase: normalizeBrowserApiBase(),\r\n });\r\n this.auth = new RagableBrowserAuthClient<AuthUser>(options, this._ragableAuth);\r\n this.database = new RagableBrowserDatabaseClient<Database>(\r\n options,\r\n this._ragableAuth as RagableAuth | null,\r\n );\r\n this.database._setTransport(this.transport);\r\n this.db = this.database;\r\n this.storage = new RagableBrowserStorageClient(\r\n options,\r\n bindFetch(options.fetch),\r\n this._ragableAuth as RagableAuth | null,\r\n );\r\n this.mail = new RagableBrowserMailClient(options, this._ragableAuth as RagableAuth | null);\r\n this.functions = new RagableBrowserFunctionsClient(\r\n options,\r\n this._ragableAuth as RagableAuth | null,\r\n ).asInvoker<Functions>();\r\n }\r\n\r\n /** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */\r\n from = <TableName extends RagableTableNames<Database>>(\r\n table: TableName,\r\n databaseInstanceId?: string,\r\n ): PostgrestTableApi<Database, TableName> => {\r\n return this.database.from(table, databaseInstanceId);\r\n };\r\n\r\n /**\r\n * Resolves once the persisted session has been restored (and refreshed if it\r\n * was expired). Await this before reading auth state at startup to avoid a\r\n * logged-out flash, e.g. `const session = await client.ready()`. Resolves\r\n * `null` when no auth group is configured or no session is stored.\r\n */\r\n ready(): Promise<AuthSession<AuthUser> | null> {\r\n return this._ragableAuth\r\n ? this._ragableAuth.initialize()\r\n : Promise.resolve(null);\r\n }\r\n\r\n destroy(): void {\r\n this._ragableAuth?.destroy();\r\n }\r\n}\r\n\r\nexport function createBrowserClient<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n AuthUser extends object = DefaultAuthUser,\r\n Functions extends RagableFunctions = DefaultRagableFunctions,\r\n>(\r\n options: RagableBrowserClientOptions,\r\n): RagableBrowser<Database, AuthUser, Functions> {\r\n return new RagableBrowser<Database, AuthUser, Functions>(options);\r\n}\r\n\r\nexport const createRagableBrowserClient = createBrowserClient;\r\n","/**\n * Server-side client — the authenticated SDK for code that runs on a trusted\n * server (a Ragable backend **function**, an Engine, or your own Node service).\n *\n * Unlike the browser client there is **no sign-in / session machinery** here:\n * a server is not a logged-in user. Instead you provide credentials up front and\n * the client speaks to the same Ragable data plane the browser uses, so the\n * semantics (collection security, `{ data, error }` shapes, PostgREST) are\n * identical — this reuses the exact same fetch-based sub-clients, never a\n * reimplementation.\n *\n * Two privilege levels:\n * - **caller** (default): acts as the end user who invoked you — uses their\n * forwarded access token, falling back to the public anon key for anonymous\n * callers. Collection security applies, exactly as in the browser.\n * - **admin**: authenticates with the auth group's **data-admin key**, which\n * bypasses collection security (owner/group/claim grants do not apply) and\n * can write protected collections. Reach for it deliberately.\n *\n * ```ts\n * // inside /functions/<name>.ts — `context.ragable` is a pre-built server client\n * export default async function createTask(input, context) {\n * // as the caller (respects collection security):\n * const { data, error } = await context.ragable.db.collections.tasks.insert(input);\n * // privileged work (bypasses collection security):\n * await context.ragable.asAdmin().db.collections.audit_log.insert({ action: \"create\" });\n * return data;\n * }\n * ```\n */\n\nimport { RagableBrowserAiClient } from \"./ai\";\nimport {\n normalizeBrowserApiBase,\n RagableBrowserAgentsClient,\n RagableBrowserDatabaseClient,\n RagableBrowserFunctionsClient,\n RagableBrowserMailClient,\n RagableBrowserStorageClient,\n type RagableBrowserClientOptions,\n} from \"./browser\";\nimport type { DefaultRagableDatabase, RagableDatabase } from \"./database-schema\";\nimport type {\n DefaultRagableFunctions,\n FunctionInvoker,\n RagableFunctions,\n} from \"./functions\";\nimport { bindFetch, RagableError } from \"./request-client\";\nimport { Transport } from \"./transport\";\n\n/** Which credential a server client authenticates with. */\nexport type ServerPrivilege = \"caller\" | \"admin\";\n\n/**\n * Inputs to {@link createServerClient}. The IDs and keys are normally supplied by\n * the runtime (a function's injected `context.ragable`); construct one by hand\n * only for a standalone server.\n */\nexport interface RagableServerClientConfig {\n organizationId: string;\n websiteId?: string;\n authGroupId?: string;\n databaseInstanceId?: string;\n storageBucketId?: string;\n mailAccountId?: string;\n /**\n * The auth group's **data-admin key**. Required for `admin` privilege; omit it\n * and `asAdmin()` throws. Server-only — never expose this to the browser.\n */\n adminKey?: string;\n /**\n * The invoking end user's access token (a real auth-group JWT), forwarded by\n * the runtime. `null`/omitted for anonymous callers. Used by `caller`\n * privilege; the public anon key is the fallback when this is absent.\n */\n callerToken?: string | null;\n /** Public anon key — the `caller` fallback when no end user is signed in. */\n publicAnonKey?: string;\n /** Default privilege for the returned client. Defaults to `\"caller\"`. */\n defaultPrivilege?: ServerPrivilege;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\n/** Translate the server config into browser-client options for a given privilege. */\nfunction optionsForPrivilege(\n config: RagableServerClientConfig,\n privilege: ServerPrivilege,\n): RagableBrowserClientOptions {\n const base: RagableBrowserClientOptions = {\n organizationId: config.organizationId,\n ...(config.websiteId !== undefined ? { websiteId: config.websiteId } : {}),\n ...(config.authGroupId !== undefined ? { authGroupId: config.authGroupId } : {}),\n ...(config.databaseInstanceId !== undefined\n ? { databaseInstanceId: config.databaseInstanceId }\n : {}),\n ...(config.fetch !== undefined ? { fetch: config.fetch } : {}),\n ...(config.headers !== undefined ? { headers: config.headers } : {}),\n };\n\n if (privilege === \"admin\") {\n const key = config.adminKey?.trim();\n if (!key) {\n throw new RagableError(\n \"Admin privilege requires `adminKey` (the auth group's data-admin key). \" +\n \"It is not available — admin functions may be disabled for this project.\",\n 403,\n { code: \"SDK_ADMIN_KEY_REQUIRED\" },\n );\n }\n // The data-admin key is the only accepted credential; it bypasses security.\n return { ...base, dataAuth: \"admin\", dataStaticKey: key };\n }\n\n // caller: a real end-user JWT when present, else the public anon key. `auto`\n // prefers the user token and falls back to the static key, matching the\n // generated browser client.\n return {\n ...base,\n dataAuth: \"auto\",\n getAccessToken: () => config.callerToken ?? null,\n ...(config.publicAnonKey !== undefined\n ? { dataStaticKey: config.publicAnonKey }\n : {}),\n };\n}\n\n/**\n * A trusted, server-side Ragable client. Surface mirrors the browser client\n * (`db`, `storage`, `mail`, `functions`, `ai`, `agents`) minus `auth` — a server\n * authenticates with keys, not a session. Switch privilege with {@link asAdmin}\n * / {@link asCaller}.\n */\nexport class RagableServerClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n Functions extends RagableFunctions = DefaultRagableFunctions,\n> {\n readonly database: RagableBrowserDatabaseClient<Database>;\n readonly db: RagableBrowserDatabaseClient<Database>;\n readonly storage: RagableBrowserStorageClient;\n readonly mail: RagableBrowserMailClient;\n readonly functions: FunctionInvoker<Functions>;\n readonly ai: RagableBrowserAiClient;\n readonly agents: RagableBrowserAgentsClient;\n /** Which credential this client is using. */\n readonly privilege: ServerPrivilege;\n\n constructor(\n private readonly config: RagableServerClientConfig,\n privilege: ServerPrivilege,\n ) {\n this.privilege = privilege;\n const options = optionsForPrivilege(config, privilege);\n\n // No auth session server-side: every sub-client is constructed with a null\n // RagableAuth and resolves its bearer from the options (caller token / key).\n const transport = new Transport({\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\n ...options.transport,\n });\n\n this.database = new RagableBrowserDatabaseClient<Database>(options, null);\n this.database._setTransport(transport);\n this.db = this.database;\n this.storage = new RagableBrowserStorageClient(options, bindFetch(options.fetch), null);\n this.mail = new RagableBrowserMailClient(options, null);\n this.functions = new RagableBrowserFunctionsClient(options, null).asInvoker<Functions>();\n this.ai = new RagableBrowserAiClient({\n organizationId: options.organizationId,\n ...(options.websiteId !== undefined ? { websiteId: options.websiteId } : {}),\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\n apiBase: normalizeBrowserApiBase(),\n });\n this.agents = new RagableBrowserAgentsClient(options);\n }\n\n /**\n * A client authenticated with the **data-admin key** — bypasses collection\n * security (owner/group/claim grants do not apply) and can write protected\n * collections. Throws `SDK_ADMIN_KEY_REQUIRED` when no admin key is configured.\n */\n asAdmin(): RagableServerClient<Database, Functions> {\n return new RagableServerClient<Database, Functions>(this.config, \"admin\");\n }\n\n /**\n * A client scoped to the invoking end user's identity (respects collection\n * security). This is already the default; use it to drop back from `asAdmin()`.\n */\n asCaller(): RagableServerClient<Database, Functions> {\n return new RagableServerClient<Database, Functions>(this.config, \"caller\");\n }\n}\n\n/**\n * Create a server-side Ragable client. Defaults to **caller** privilege (acts as\n * the invoking end user, respecting collection security); call `.asAdmin()` for\n * privileged, security-bypassing access.\n */\nexport function createServerClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n Functions extends RagableFunctions = DefaultRagableFunctions,\n>(\n config: RagableServerClientConfig,\n): RagableServerClient<Database, Functions> {\n return new RagableServerClient<Database, Functions>(\n config,\n config.defaultPrivilege ?? \"caller\",\n );\n}\n","export type {\r\n ColumnName,\r\n ColumnValue,\r\n DefaultRagableDatabase,\r\n Json,\r\n RagableDatabase,\r\n RagableTableDefinition,\r\n RagableTableNames,\r\n TableInsertRow,\r\n TableRow,\r\n TableUpdatePatch,\r\n Tables,\r\n TablesInsert,\r\n TablesUpdate,\r\n} from \"./database-schema\";\r\n\r\nexport type { RequestOptions } from \"./request-client\";\r\nexport {\r\n bindFetch,\r\n DEFAULT_RAGABLE_API_BASE,\r\n extractErrorMessage,\r\n formatSdkError,\r\n formatPostgrestError,\r\n RagableAbortError,\r\n RagableError,\r\n RagableNetworkError,\r\n RagableSdkError,\r\n RagableTimeoutError,\r\n} from \"./request-client\";\r\n\r\nexport type {\r\n AgentChatMessage,\r\n AgentChatParams,\r\n AgentChatStreamDonePayload,\r\n AgentChatStreamHandlers,\r\n AgentChatStreamResult,\r\n AgentStreamAgentInfoEvent,\r\n AgentStreamEvent,\r\n RunAgentChatStreamOptions,\r\n} from \"./agent-stream\";\r\nexport {\r\n isIncompleteAgentStreamError,\r\n parseAgentStreamAgentInfo,\r\n parseAgentStreamDone,\r\n runAgentChatStream,\r\n runAgentChatStreamLenient,\r\n} from \"./agent-stream\";\r\n\r\nexport type {\r\n AgentChatStreamUiHandlers,\r\n AgentChatUiAssistantMessage,\r\n AgentChatUiSegment,\r\n AgentChatUiStreamResult,\r\n} from \"./agent-chat-ui\";\r\nexport {\r\n collectAssistantTextFromUiSegments,\r\n finalizeAgentChatUiTurn,\r\n foldAgentStreamIntoUiSegments,\r\n runAgentChatStreamForUi,\r\n} from \"./agent-chat-ui\";\r\n\r\nexport type {\r\n AgentConversation,\r\n AgentConversationMessage,\r\n AgentConversationSubscription,\r\n AgentPublicChatParams,\r\n BrowserAuthSession,\r\n BrowserAuthTokens,\r\n BrowserCollectionApi,\r\n BrowserCollectionDefinition,\r\n BrowserCollectionFactory,\r\n BrowserCollectionFindParams,\r\n BrowserCollectionRecord,\r\n BrowserCollections,\r\n CollectionReturnMode,\r\n CollectionRowData,\r\n CollectionRowWithMeta,\r\n CollectionWhere,\r\n BrowserDataAuthMode,\r\n BrowserRealtimeNotification,\r\n BrowserRealtimeStatus,\r\n BrowserRealtimeSubscribeParams,\r\n BrowserRealtimeSubscription,\r\n BrowserSqlQueryParams,\r\n BrowserSqlQueryResult,\r\n BrowserStorageBulkDeleteResult,\r\n BrowserStorageDownloadResult,\r\n BrowserStorageItem,\r\n BrowserStorageListResult,\r\n BrowserStorageSignedUrlResult,\r\n BrowserStorageUploadResult,\r\n PostgrestResult,\r\n RagableBrowserClientOptions,\r\n SupabaseCompatSession,\r\n WhereInput,\r\n WhereOperatorObject,\r\n} from \"./browser\";\r\nexport {\r\n assertPostgrestSuccess,\r\n BrowserStorageBucketClient,\r\n collectionRecordToRowWithMeta,\r\n collectionRecordsToRowWithMeta,\r\n createBrowserClient,\r\n createRagableBrowserClient,\r\n effectiveDataAuth,\r\n normalizeBrowserApiBase,\r\n RagableBrowser,\r\n RagableBrowserAgentsClient,\r\n RagableBrowserAuthClient,\r\n RagableBrowserDatabaseClient,\r\n RagableBrowserMailClient,\r\n RagableBrowserStorageClient,\r\n toRagableResult,\r\n unwrapPostgrest,\r\n} from \"./browser\";\r\nexport type {\r\n MailMessageDetail,\r\n MailMessagePreview,\r\n MailSearchParams,\r\n MailSendParams,\r\n MailSendResult,\r\n} from \"./browser\";\r\n\r\nexport type {\r\n BrowserSqlExecParams,\r\n BrowserSqlExecResult,\r\n PostgRESTFetch,\r\n PostgRESTFetchParams,\r\n PostgrestUpsertOptions,\r\n RunQuery,\r\n} from \"./browser-postgrest\";\r\nexport type { RagableResult } from \"./browser-postgrest\";\r\nexport {\r\n asPostgrestResponse,\r\n PostgrestDeleteReturningBuilder,\r\n PostgrestDeleteRootBuilder,\r\n PostgrestInsertReturningBuilder,\r\n PostgrestInsertRootBuilder,\r\n PostgrestInsertSdkErrorReturning,\r\n PostgrestInsertSdkErrorRoot,\r\n PostgrestSelectBuilder,\r\n PostgrestTableApi,\r\n PostgrestUpdateReturningBuilder,\r\n PostgrestUpdateRootBuilder,\r\n PostgrestUpsertReturningBuilder,\r\n PostgrestUpsertRootBuilder,\r\n} from \"./browser-postgrest\";\r\n\r\nexport type { SseJsonEvent } from \"./sse\";\r\nexport { parseSseDataLine, readSseStream } from \"./sse\";\r\n\r\nexport type {\r\n FinishReason,\r\n Message,\r\n StreamPart,\r\n TokenUsage,\r\n} from \"./stream-parts\";\r\nexport { mapAgentEvent, mapFireworksChunk } from \"./stream-parts\";\r\n\r\nexport type {\r\n GenerateObjectResult,\r\n GenerateTextResult,\r\n JsonSchema,\r\n StreamObjectParams,\r\n StreamObjectResult,\r\n StreamTextParams,\r\n StreamTextResult,\r\n ToolCallRecord,\r\n} from \"./ai\";\r\nexport {\r\n buildInferenceRequestBody,\r\n buildResponseFormat,\r\n createStreamResultFromParts,\r\n RagableBrowserAiClient,\r\n streamObjectFromContext,\r\n wrapStreamTextAsObject,\r\n} from \"./ai\";\r\n\r\nexport { tryParsePartialJson } from \"./partial-json\";\r\n\r\nexport type {\r\n HttpMethod,\r\n RetryOptions,\r\n TransportOptions,\r\n TransportRequest,\r\n} from \"./transport\";\r\nexport { generateIdempotencyKey, Transport, parseTransportResponse } from \"./transport\";\r\n\r\nexport type {\r\n SessionStorage,\r\n AuthBroadcastMessage,\r\n} from \"./auth-storage\";\r\nexport {\r\n AuthBroadcastChannel,\r\n CookieStorageAdapter,\r\n detectStorage,\r\n LocalStorageAdapter,\r\n MemoryStorageAdapter,\r\n SessionStorageAdapter,\r\n} from \"./auth-storage\";\r\n\r\nexport type {\r\n AuthChangeEvent,\r\n AuthSignUpCredentials,\r\n AuthOptions,\r\n AuthSession,\r\n AuthUpdateUserAttributes,\r\n AuthUserMetadata,\r\n DefaultAuthUser,\r\n RagableAuthConfig,\r\n} from \"./auth\";\r\nexport { RagableAuth } from \"./auth\";\r\n\r\nexport type {\r\n DefaultRagableFunctions,\r\n FunctionInvoker,\r\n RagableFunctionCall,\r\n RagableFunctionContext,\r\n RagableFunctionHandler,\r\n RagableFunctionInvokeOptions,\r\n RagableFunctions,\r\n} from \"./functions\";\r\nexport { RagableBrowserFunctionsClient } from \"./browser\";\r\n\r\nexport type {\r\n RagableServerClientConfig,\r\n ServerPrivilege,\r\n} from \"./server\";\r\nexport { createServerClient, RagableServerClient } from \"./server\";\r\n\r\n// ─── Top-level client factory ────────────────────────────────────────────────\r\n\r\nimport {\r\n createBrowserClient,\r\n RagableBrowser,\r\n type RagableBrowserClientOptions,\r\n} from \"./browser\";\r\nimport type { DefaultAuthUser } from \"./auth\";\r\nimport type { DefaultRagableDatabase, RagableDatabase } from \"./database-schema\";\r\nimport type { DefaultRagableFunctions, RagableFunctions } from \"./functions\";\r\n\r\nexport function createClient<\r\n Database extends RagableDatabase = DefaultRagableDatabase,\r\n AuthUser extends object = DefaultAuthUser,\r\n Functions extends RagableFunctions = DefaultRagableFunctions,\r\n>(\r\n options: RagableBrowserClientOptions,\r\n): RagableBrowser<Database, AuthUser, Functions> {\r\n return createBrowserClient<Database, AuthUser, Functions>(options);\r\n}\r\n"],"mappings":"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","names":["asString","asNumber","assertAborted","asNum","key"]}
|