@rebasepro/client 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -10
- package/dist/api-keys.d.ts +1 -0
- package/dist/auth.d.ts +35 -38
- package/dist/collection.d.ts +9 -13
- package/dist/data-proxy.test.d.ts +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/index.d.ts +41 -21
- package/dist/index.es.js +605 -368
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +616 -379
- package/dist/index.umd.js.map +1 -1
- package/dist/sdk_query_builder.d.ts +63 -0
- package/dist/storage-registry.d.ts +42 -0
- package/dist/storage.d.ts +9 -1
- package/dist/transport.d.ts +2 -6
- package/dist/websocket.d.ts +25 -21
- package/package.json +13 -12
- package/src/api-keys.ts +1 -0
- package/src/auth.ts +188 -64
- package/src/collection.test.ts +94 -5
- package/src/collection.ts +103 -184
- package/src/data-proxy.test.ts +167 -0
- package/src/errors.ts +9 -0
- package/src/index.ts +218 -24
- package/src/reviver.ts +2 -2
- package/src/sdk_query_builder.ts +138 -0
- package/src/storage-registry.ts +102 -0
- package/src/storage.ts +92 -50
- package/src/transport.ts +31 -105
- package/src/websocket.ts +133 -135
package/dist/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","names":[],"sources":["../src/reviver.ts","../src/transport.ts","../src/auth.ts","../src/admin.ts","../src/cron.ts","../src/api-keys.ts","../src/collection.ts","../src/functions.ts","../src/storage.ts","../src/websocket.ts","../src/index.ts"],"sourcesContent":["import { EntityReference, EntityRelation, GeoPoint, Vector, Entity } from \"@rebasepro/types\";\n\nexport function rebaseReviver(_key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && \"__type\" in value) {\n const record = value as Record<string, unknown>;\n switch (record.__type) {\n case \"date\":\n case \"Date\": {\n if (typeof record.value !== \"string\") {\n return value;\n }\n const date = new Date(record.value);\n return isNaN(date.getTime()) ? null : date;\n }\n case \"reference\":\n case \"EntityReference\":\n return new EntityReference({\n id: String(record.id),\n path: record.path as string,\n driver: record.driver as string | undefined,\n databaseId: record.databaseId as string | undefined\n });\n case \"relation\":\n case \"EntityRelation\":\n return new EntityRelation(\n record.id as string | number,\n record.path as string,\n record.data as Entity | undefined\n );\n case \"GeoPoint\":\n return new GeoPoint(record.latitude as number, record.longitude as number);\n case \"Vector\":\n return new Vector(record.value as number[]);\n default:\n return value;\n }\n }\n return value;\n}\n","import { FindParams as TypesFindParams, FindResponse as TypesFindResponse, WhereFieldValue, WhereFilterOpShort } from \"@rebasepro/types\";\nimport { rebaseReviver } from \"./reviver\";\n\nexport interface RebaseClientConfig {\n baseUrl?: string;\n token?: string;\n apiPath?: string;\n fetch?: typeof globalThis.fetch;\n onUnauthorized?: () => Promise<boolean>;\n websocketUrl?: string; // Optional real-time WebSocket connection\n}\n\n/**\n * Re-export from `@rebasepro/types` for backward compatibility.\n */\nexport type FindParams = TypesFindParams;\nexport type FindResponse<T> = TypesFindResponse<T extends Record<string, unknown> ? T : Record<string, unknown>>;\n\nexport class RebaseApiError extends Error {\n status: number;\n code?: string;\n details?: unknown;\n\n constructor(status: number, message: string, code?: string, details?: unknown) {\n super(message);\n this.name = \"RebaseApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n/**\n * Maps a short operator alias to the PostgREST-style short code.\n */\nconst OP_MAP: Record<string, string> = {\n \"==\": \"eq\",\n\"!=\": \"neq\",\n \">\": \"gt\",\n\">=\": \"gte\",\n \"<\": \"lt\",\n\"<=\": \"lte\",\n \"not-in\": \"nin\",\n \"array-contains\": \"cs\",\n \"array-contains-any\": \"csa\"\n};\n\n/**\n * Normalise a single `WhereFieldValue` into the PostgREST query-string\n * representation the backend expects.\n *\n * Supports:\n * - `null` → `\"eq.null\"`\n * - `true`/`false` → `\"eq.true\"` / `\"eq.false\"`\n * - `42` → `\"42\"` (plain equality)\n * - `\"active\"` → `\"active\"` (plain equality, backward-compat)\n * - `\"gte.18\"` → `\"gte.18\"` (pass-through PostgREST string)\n * - `[\">=\", 18]` → `\"gte.18\"` (tuple syntax)\n * - `[\"in\", [1,2]]` → `\"in.(1,2)\"` (tuple with array value)\n * - `[\"!=\", null]` → `\"neq.null\"`\n */\nfunction normalizeWhereValue(value: WhereFieldValue): string {\n // Null → eq.null\n if (value === null) return \"eq.null\";\n\n // Boolean → eq.true / eq.false\n if (typeof value === \"boolean\") return `eq.${value}`;\n\n // Number → plain equality\n if (typeof value === \"number\") return String(value);\n\n // Tuple: [operator, val]\n if (Array.isArray(value)) {\n const conditions: [WhereFilterOpShort, any][] = Array.isArray(value[0])\n ? (value as [WhereFilterOpShort, any][])\n : [value as [WhereFilterOpShort, any]];\n\n const [rawOp, val] = conditions[0] || [];\n if (rawOp) {\n const op = OP_MAP[rawOp] ?? rawOp;\n if (val === null) return `${op}.null`;\n if (Array.isArray(val)) return `${op}.(${val.join(\",\")})`;\n return `${op}.${val}`;\n }\n }\n\n // String — pass through (either plain equality value or PostgREST syntax)\n return String(value);\n}\n\nfunction serializeLogicalCondition(cond: any): string {\n if (\"type\" in cond) {\n const sub = (cond.conditions ?? []).map(serializeLogicalCondition).join(\",\");\n return `${cond.type}(${sub})`;\n } else {\n const op = OP_MAP[cond.operator] ?? cond.operator;\n let formattedValue = cond.value;\n if (Array.isArray(cond.value)) {\n formattedValue = `(${cond.value.join(\",\")})`;\n } else if (cond.value === null) {\n formattedValue = \"null\";\n }\n return `${cond.column}.${op}.${formattedValue}`;\n }\n}\n\nexport function buildQueryString(params?: FindParams): string {\n if (!params) return \"\";\n const parts: string[] = [];\n\n if (params.limit != null) parts.push(`limit=${params.limit}`);\n if (params.offset != null) parts.push(`offset=${params.offset}`);\n if (params.page != null) parts.push(`page=${params.page}`);\n\n if (params.orderBy) {\n parts.push(`orderBy=${encodeURIComponent(params.orderBy)}`);\n }\n\n if (params.searchString) {\n parts.push(`searchString=${encodeURIComponent(params.searchString)}`);\n }\n\n if (params.include && params.include.length > 0) {\n parts.push(`include=${encodeURIComponent(params.include.join(\",\"))}`);\n }\n\n if (params.logical) {\n const root = params.logical;\n const serialized = (root.conditions ?? []).map(serializeLogicalCondition).join(\",\");\n parts.push(`${root.type}=${encodeURIComponent(`(${serialized})`)}`);\n }\n\n if (params.where) {\n for (const [field, value] of Object.entries(params.where)) {\n if (Array.isArray(value) && value.length > 0 && Array.isArray(value[0])) {\n for (const subVal of value) {\n const normalized = normalizeWhereValue(subVal as WhereFieldValue);\n parts.push(`${encodeURIComponent(field)}=${encodeURIComponent(normalized)}`);\n }\n } else {\n const normalized = normalizeWhereValue(value as WhereFieldValue);\n parts.push(`${encodeURIComponent(field)}=${encodeURIComponent(normalized)}`);\n }\n }\n }\n\n return parts.length > 0 ? \"?\" + parts.join(\"&\") : \"\";\n}\n\nexport interface Transport {\n request: <T = unknown>(path: string, init?: RequestInit) => Promise<T>;\n setToken: (newToken: string | null) => void;\n setAuthTokenGetter: (getter: () => Promise<string | null>) => void;\n setOnUnauthorized: (handler: () => Promise<boolean>) => void;\n readonly baseUrl: string;\n readonly apiPath: string;\n readonly fetchFn: typeof globalThis.fetch;\n getHeaders: (init?: RequestInit) => Record<string, string>;\n resolveToken: () => Promise<string | null>;\n}\n\nexport function createTransport(config: RebaseClientConfig): Transport {\n const fetchFn = config.fetch || globalThis.fetch;\n const apiPath = config.apiPath || \"/api\";\n let token = config.token;\n let tokenGetter: (() => Promise<string | null>) | undefined;\n let onUnauthorizedHandler = config.onUnauthorized;\n\n function getHeaders(activeToken: string | undefined, init?: RequestInit) {\n return {\n \"Content-Type\": \"application/json\",\n ...(activeToken ? { Authorization: `Bearer ${activeToken}` } : {}),\n ...((init?.headers as Record<string, string>) || {})\n };\n }\n\n async function request<T = unknown>(path: string, init?: RequestInit): Promise<T> {\n const base = config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"\";\n const url = base + apiPath + path;\n\n let activeToken = token;\n if (tokenGetter) {\n try {\n const fetched = await tokenGetter();\n if (fetched !== null && fetched !== undefined) {\n activeToken = fetched;\n }\n } catch (e) {\n // Ignore error, fallback to static token if any\n }\n }\n\n const headers = getHeaders(activeToken, init);\n\n // If passing FormData, we MUST let fetch set the boundary, so remove Content-Type\n if (init?.body instanceof FormData) {\n delete (headers as Record<string, string>)[\"Content-Type\"];\n }\n\n const res = await fetchFn(url, { ...init,\nheaders });\n\n if (res.status === 204) return undefined as T; // SAFETY: HTTP 204 No Content has no body\n\n const text = await res.text().catch(() => \"\");\n let body: Record<string, unknown> = {};\n if (text) {\n try {\n body = JSON.parse(text, rebaseReviver) as Record<string, unknown>;\n } catch (e) {\n // If not valid JSON, fallback\n }\n }\n\n const getErrorField = (obj: Record<string, unknown>, field: string): unknown => {\n const err = obj?.error;\n if (err && typeof err === \"object\" && err !== null && field in (err as Record<string, unknown>)) {\n return (err as Record<string, unknown>)[field];\n }\n return obj?.[field];\n };\n\n if (res.status === 401 && onUnauthorizedHandler) {\n const retried = await onUnauthorizedHandler();\n if (retried) {\n let retryToken = token;\n if (tokenGetter) {\n try {\n const fetched = await tokenGetter();\n if (fetched !== null && fetched !== undefined) {\n retryToken = fetched;\n }\n } catch (e) { /* ignore */ }\n }\n const retryHeaders = getHeaders(retryToken, init) as Record<string, string>;\n const retryRes = await fetchFn(url, { ...init,\nheaders: retryHeaders });\n if (retryRes.status === 204) return undefined as T; // SAFETY: HTTP 204 No Content has no body\n const retryText = await retryRes.text().catch(() => \"\");\n let retryBody: Record<string, unknown> = {};\n if (retryText) {\n try {\n retryBody = JSON.parse(retryText, rebaseReviver);\n } catch (e) { /* ignore */ }\n }\n if (!retryRes.ok) {\n let fallbackMessage = retryRes.statusText;\n if (retryRes.status === 404 && !fallbackMessage) {\n const method = init?.method || \"GET\";\n fallbackMessage = `Endpoint not found (${method} ${path}). This usually means the collection is not registered on the backend, or the frontend API URL configuration (e.g. VITE_API_URL) is missing or pointing to the wrong host.`;\n }\n throw new RebaseApiError(\n retryRes.status,\n String(getErrorField(retryBody, \"message\") || fallbackMessage || `Request failed with status ${retryRes.status}`),\n getErrorField(retryBody, \"code\") as string | undefined,\n getErrorField(retryBody, \"details\")\n );\n }\n return retryBody as T;\n }\n }\n\n if (!res.ok) {\n let fallbackMessage = res.statusText;\n if (res.status === 404 && !fallbackMessage) {\n const method = init?.method || \"GET\";\n fallbackMessage = `Endpoint not found (${method} ${path}). This usually means the collection is not registered on the backend, or the frontend API URL configuration (e.g. VITE_API_URL) is missing or pointing to the wrong host.`;\n }\n throw new RebaseApiError(\n res.status,\n String(getErrorField(body, \"message\") || fallbackMessage || `Request failed with status ${res.status}`),\n getErrorField(body, \"code\") as string | undefined,\n getErrorField(body, \"details\")\n );\n }\n\n return body as T;\n }\n\n return {\n request,\n setToken(newToken: string | null) { token = newToken || undefined; },\n setAuthTokenGetter(getter: () => Promise<string | null>) { tokenGetter = getter; },\n setOnUnauthorized(handler: () => Promise<boolean>) { onUnauthorizedHandler = handler; },\n get baseUrl() { return config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"\"; },\n get apiPath() { return apiPath; },\n get fetchFn() { return fetchFn; },\n getHeaders: (init?: RequestInit) => getHeaders(token, init) as Record<string, string>,\n resolveToken: async () => {\n if (tokenGetter) {\n try {\n const fetched = await tokenGetter();\n if (fetched !== null && fetched !== undefined) {\n return fetched;\n }\n } catch (e) { /* ignore */ }\n }\n return token || null;\n }\n };\n}\n","import { RebaseApiError, Transport } from \"./transport\";\nimport { AuthChangeEvent } from \"@rebasepro/types\";\n\n\nexport interface RebaseUser {\n uid: string;\n email: string | null;\n displayName: string | null;\n photoURL: string | null;\n emailVerified?: boolean;\n roles?: string[];\n providerId: string;\n isAnonymous: boolean;\n}\n\nexport interface RebaseTokens {\n accessToken: string;\n refreshToken: string;\n accessTokenExpiresAt: number;\n}\n\nexport interface RebaseSession {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n user: RebaseUser;\n}\n\nexport type { AuthChangeEvent };\n\n\nexport interface AuthConfig {\n needsSetup: boolean;\n registrationEnabled: boolean;\n emailServiceEnabled?: boolean;\n passwordReset?: boolean;\n emailVerification?: boolean;\n magicLink?: boolean;\n enabledProviders: string[];\n}\n\nexport interface AuthStorage {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n removeItem: (key: string) => void;\n}\n\nexport function createMemoryStorage(): AuthStorage {\n const store: Record<string, string> = {};\n return {\n getItem(key) { return store[key] ?? null; },\n setItem(key, value) { store[key] = value; },\n removeItem(key) { delete store[key]; }\n };\n}\n\nfunction detectStorage(): AuthStorage {\n try {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(\"__rebase_test__\", \"1\");\n localStorage.removeItem(\"__rebase_test__\");\n return localStorage;\n }\n } catch (e) { /* ignore */ }\n return createMemoryStorage();\n}\n\nexport interface CreateAuthOptions {\n storage?: AuthStorage;\n authPath?: string;\n autoRefresh?: boolean;\n persistSession?: boolean;\n}\n\nexport function createAuth(transport: Transport, options?: CreateAuthOptions) {\n const opts = options || {};\n const storage = opts.storage || detectStorage();\n const authPath = opts.authPath || \"/auth\";\n const autoRefresh = opts.autoRefresh !== false;\n const persistSession = opts.persistSession !== false;\n\n const STORAGE_KEY = \"rebase_auth\";\n const REFRESH_BUFFER_MS = 120000;\n\n let currentSession: RebaseSession | null = null;\n const listeners = new Set<(event: AuthChangeEvent, session: RebaseSession | null) => void>();\n let refreshTimeout: ReturnType<typeof setTimeout> | null = null;\n\n function authUrl(endpoint: string) {\n return transport.baseUrl + transport.apiPath + authPath + endpoint;\n }\n\n function getFetch() {\n return transport.fetchFn || globalThis.fetch;\n }\n\n function throwApiError(status: number, body: { error?: { message?: string; code?: string; details?: unknown }; message?: string; code?: string; details?: unknown } | undefined, statusText: string): never {\n throw new RebaseApiError(\n status,\n body?.error?.message || body?.message || statusText,\n body?.error?.code || body?.code,\n body?.error?.details || body?.details\n );\n }\n\n function emit(event: AuthChangeEvent, session: RebaseSession | null) {\n for (const fn of listeners) {\n try { fn(event, session); } catch (e) { /* ignore */ }\n }\n }\n\n function saveSession(session: RebaseSession) {\n if (!persistSession) return;\n try {\n storage.setItem(STORAGE_KEY, JSON.stringify(session));\n } catch (e) { /* ignore */ }\n }\n\n function clearStoredSession() {\n try {\n storage.removeItem(STORAGE_KEY);\n } catch (e) { /* ignore */ }\n }\n\n function loadStoredSession(): RebaseSession | null {\n try {\n const raw = storage.getItem(STORAGE_KEY);\n if (raw) return JSON.parse(raw) as RebaseSession;\n } catch (e) { /* ignore */ }\n return null;\n }\n\n function scheduleRefresh(expiresAt: number) {\n if (refreshTimeout) clearTimeout(refreshTimeout);\n if (!autoRefresh) return;\n\n const delay = (expiresAt - REFRESH_BUFFER_MS) - Date.now();\n\n if (delay <= 0) {\n refreshSession().catch(() => signOut());\n return;\n }\n\n refreshTimeout = setTimeout(async () => {\n try {\n await refreshSession();\n } catch (e) {\n signOut();\n }\n }, delay);\n }\n\n function handleAuthResponse(data: { tokens: RebaseTokens, user: RebaseUser }, event?: AuthChangeEvent): RebaseSession {\n const session: RebaseSession = {\n accessToken: data.tokens.accessToken,\n refreshToken: data.tokens.refreshToken,\n expiresAt: data.tokens.accessTokenExpiresAt,\n user: data.user\n };\n currentSession = session;\n saveSession(session);\n transport.setToken(session.accessToken);\n scheduleRefresh(session.expiresAt);\n emit(event || \"SIGNED_IN\", session);\n return session;\n }\n\n async function signInWithEmail(email: string, password: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/login\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email,\npassword })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n async function signUp(email: string, password: string, displayName?: string) {\n const fetchFn = getFetch();\n const payload: Record<string, string> = { email,\npassword };\n if (displayName !== undefined) payload.displayName = displayName;\n const res = await fetchFn(authUrl(\"/register\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload)\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n /**\n * Sign in with Google.\n *\n * Supports three invocation styles:\n * - `signInWithGoogle({ idToken })` — ID-token flow (One Tap / Sign In button)\n * - `signInWithGoogle({ accessToken })` — Access-token flow (popup)\n * - `signInWithGoogle({ code, redirectUri })` — Authorization code flow (most secure)\n */\n async function signInWithGoogle(\n payload: { idToken: string } | { accessToken: string } | { code: string; redirectUri: string }\n ) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/google\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload)\n });\n const responseBody = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, responseBody, res.statusText);\n const session = handleAuthResponse(responseBody, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n async function signInWithLinkedin(code: string, redirectUri: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/linkedin\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code,\nredirectUri })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n /**\n * Generic OAuth sign-in. Posts the given payload to `/auth/{providerId}`.\n * Use this for any provider registered on the backend.\n */\n async function signInWithOAuth(providerId: string, payload: Record<string, unknown>) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(`/${providerId}`), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload)\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n // Convenience wrappers for all supported OAuth providers\n\n async function signInWithGitHub(code: string, redirectUri: string) {\n return signInWithOAuth(\"github\", { code,\nredirectUri });\n }\n\n async function signInWithMicrosoft(code: string, redirectUri: string) {\n return signInWithOAuth(\"microsoft\", { code,\nredirectUri });\n }\n\n async function signInWithApple(code: string, redirectUri: string, user?: { name?: { firstName?: string; lastName?: string }; email?: string }) {\n return signInWithOAuth(\"apple\", { code,\nredirectUri,\nuser });\n }\n\n async function signInWithFacebook(code: string, redirectUri: string) {\n return signInWithOAuth(\"facebook\", { code,\nredirectUri });\n }\n\n async function signInWithTwitter(code: string, redirectUri: string, codeVerifier: string) {\n return signInWithOAuth(\"twitter\", { code,\nredirectUri,\ncodeVerifier });\n }\n\n async function signInWithDiscord(code: string, redirectUri: string) {\n return signInWithOAuth(\"discord\", { code,\nredirectUri });\n }\n\n async function signInWithGitLab(code: string, redirectUri: string) {\n return signInWithOAuth(\"gitlab\", { code,\nredirectUri });\n }\n\n async function signInWithBitbucket(code: string, redirectUri: string) {\n return signInWithOAuth(\"bitbucket\", { code,\nredirectUri });\n }\n\n async function signInWithSlack(code: string, redirectUri: string) {\n return signInWithOAuth(\"slack\", { code,\nredirectUri });\n }\n\n async function signInWithSpotify(code: string, redirectUri: string) {\n return signInWithOAuth(\"spotify\", { code,\nredirectUri });\n }\n\n async function signOut() {\n const fetchFn = getFetch();\n try {\n if (currentSession?.refreshToken) {\n await fetchFn(authUrl(\"/logout\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refreshToken: currentSession.refreshToken })\n });\n }\n } catch (e) { /* ignore */ }\n currentSession = null;\n clearStoredSession();\n if (refreshTimeout) {\n clearTimeout(refreshTimeout);\n refreshTimeout = null;\n }\n transport.setToken(null);\n emit(\"SIGNED_OUT\", null);\n }\n\n async function refreshSession() {\n if (!currentSession?.refreshToken) {\n throw new Error(\"No active session to refresh\");\n }\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/refresh\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refreshToken: currentSession.refreshToken })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session: RebaseSession = {\n accessToken: body.tokens.accessToken,\n refreshToken: body.tokens.refreshToken,\n expiresAt: body.tokens.accessTokenExpiresAt,\n user: currentSession.user\n };\n currentSession = session;\n saveSession(session);\n transport.setToken(session.accessToken);\n scheduleRefresh(session.expiresAt);\n emit(\"TOKEN_REFRESHED\", session);\n return session;\n }\n\n async function getUser() {\n const data = await transport.request<{ user: RebaseUser }>(authPath + \"/me\", { method: \"GET\" });\n return data.user;\n }\n\n async function updateUser(updates: { displayName?: string, photoURL?: string }) {\n const data = await transport.request<{ user: RebaseUser }>(authPath + \"/me\", {\n method: \"PATCH\",\n body: JSON.stringify(updates)\n });\n if (currentSession) {\n currentSession = { ...currentSession,\nuser: data.user };\n saveSession(currentSession);\n emit(\"USER_UPDATED\", currentSession);\n }\n return data.user;\n }\n\n async function resetPasswordForEmail(email: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/forgot-password\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function resetPassword(token: string, password: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/reset-password\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ token,\npassword })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function changePassword(oldPassword: string, newPassword: string) {\n return transport.request<{ success: boolean; message: string; }>(authPath + \"/change-password\", {\n method: \"POST\",\n body: JSON.stringify({ oldPassword,\nnewPassword })\n });\n }\n\n async function sendVerificationEmail() {\n return transport.request<{ success: boolean; message: string; }>(authPath + \"/send-verification\", {\n method: \"POST\"\n });\n }\n\n async function verifyEmail(token: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/verify-email?token=\" + encodeURIComponent(token)), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" }\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function sendMagicLink(email: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/magic-link\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function verifyMagicLink(token: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/magic-link/verify\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ token })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n async function getSessions() {\n const data = await transport.request<{ sessions: Record<string, unknown>[] }>(authPath + \"/sessions\", { method: \"GET\" });\n return data.sessions;\n }\n\n async function revokeSession(sessionId: string) {\n return transport.request<{ success: boolean }>(authPath + \"/sessions/\" + encodeURIComponent(sessionId), {\n method: \"DELETE\"\n });\n }\n\n async function revokeAllSessions() {\n const result = await transport.request<{ success: boolean }>(authPath + \"/sessions\", {\n method: \"DELETE\"\n });\n currentSession = null;\n clearStoredSession();\n if (refreshTimeout) {\n clearTimeout(refreshTimeout);\n refreshTimeout = null;\n }\n transport.setToken(null);\n emit(\"SIGNED_OUT\", null);\n return result;\n }\n\n async function getAuthConfig() {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/config\"), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" }\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as AuthConfig;\n }\n\n function getSession() {\n return currentSession;\n }\n\n function onAuthStateChange(callback: (event: AuthChangeEvent, session: RebaseSession | null) => void) {\n listeners.add(callback);\n return () => listeners.delete(callback);\n }\n\n if (persistSession) {\n const stored = loadStoredSession();\n if (stored && stored.accessToken && stored.refreshToken) {\n if (stored.expiresAt > Date.now()) {\n currentSession = stored;\n transport.setToken(stored.accessToken);\n scheduleRefresh(stored.expiresAt);\n } else if (stored.refreshToken) {\n currentSession = stored;\n refreshSession().catch(() => {\n currentSession = null;\n clearStoredSession();\n transport.setToken(null);\n });\n }\n }\n }\n\n return {\n signInWithEmail,\n signUp,\n signInWithGoogle,\n signInWithLinkedin,\n signInWithOAuth,\n signInWithGitHub,\n signInWithMicrosoft,\n signInWithApple,\n signInWithFacebook,\n signInWithTwitter,\n signInWithDiscord,\n signInWithGitLab,\n signInWithBitbucket,\n signInWithSlack,\n signInWithSpotify,\n signOut,\n refreshSession,\n getUser,\n updateUser,\n resetPasswordForEmail,\n resetPassword,\n changePassword,\n sendVerificationEmail,\n verifyEmail,\n sendMagicLink,\n verifyMagicLink,\n getSessions,\n revokeSession,\n revokeAllSessions,\n getAuthConfig,\n getSession,\n onAuthStateChange\n };\n}\n\nexport interface CookieStorageOptions {\n path?: string;\n domain?: string;\n secure?: boolean;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n maxAge?: number;\n}\n\nexport function createCookieStorage(options: CookieStorageOptions = {}): AuthStorage {\n const defaultOptions = {\n path: \"/\",\n sameSite: \"Lax\" as const,\n ...options\n };\n\n return {\n getItem(key: string): string | null {\n if (typeof document === \"undefined\") return null;\n const nameEQ = encodeURIComponent(key) + \"=\";\n const ca = document.cookie.split(\";\");\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === \" \") c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) {\n return decodeURIComponent(c.substring(nameEQ.length, c.length));\n }\n }\n return null;\n },\n setItem(key: string, value: string): void {\n if (typeof document === \"undefined\") return;\n let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;\n\n if (defaultOptions.path) {\n cookieStr += `; path=${defaultOptions.path}`;\n }\n if (defaultOptions.domain) {\n cookieStr += `; domain=${defaultOptions.domain}`;\n }\n if (defaultOptions.maxAge !== undefined) {\n cookieStr += `; max-age=${defaultOptions.maxAge}`;\n } else {\n cookieStr += `; max-age=${365 * 24 * 60 * 60}`;\n }\n if (defaultOptions.secure) {\n cookieStr += \"; secure\";\n }\n if (defaultOptions.sameSite) {\n cookieStr += `; samesite=${defaultOptions.sameSite}`;\n }\n\n document.cookie = cookieStr;\n },\n removeItem(key: string): void {\n if (typeof document === \"undefined\") return;\n let cookieStr = `${encodeURIComponent(key)}=; path=${defaultOptions.path || \"/\"}; max-age=-1`;\n if (defaultOptions.domain) {\n cookieStr += `; domain=${defaultOptions.domain}`;\n }\n document.cookie = cookieStr;\n }\n };\n}\n","import type { Transport } from \"./transport\";\nimport { AdminUser } from \"@rebasepro/types\";\n\nexport type { AdminUser };\n\n\nexport interface CreateAdminOptions {\n adminPath?: string;\n}\n\nexport function createAdmin(transport: Transport, options?: CreateAdminOptions) {\n const opts = options || {};\n const adminPath = opts.adminPath || \"/admin\";\n\n async function listUsers() {\n return transport.request<{ users: AdminUser[] }>(adminPath + \"/users\", { method: \"GET\" });\n }\n\n async function listUsersPaginated(options?: { search?: string; limit?: number; offset?: number; orderBy?: string; orderDir?: \"asc\" | \"desc\" }) {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n if (options?.search) params.set(\"search\", options.search);\n if (options?.orderBy) params.set(\"orderBy\", options.orderBy);\n if (options?.orderDir) params.set(\"orderDir\", options.orderDir);\n const qs = params.toString();\n return transport.request<{ users: AdminUser[]; total: number; limit: number; offset: number }>(\n adminPath + \"/users\" + (qs ? \"?\" + qs : \"\"), { method: \"GET\" }\n );\n }\n\n async function getUser(userId: string) {\n return transport.request<{ user: AdminUser }>(adminPath + \"/users/\" + encodeURIComponent(userId), { method: \"GET\" });\n }\n\n async function createUser(data: { email: string, displayName?: string, password?: string, roles?: string[] }) {\n return transport.request<{ user: AdminUser }>(adminPath + \"/users\", {\n method: \"POST\",\n body: JSON.stringify(data)\n });\n }\n\n async function updateUser(userId: string, data: { email?: string, displayName?: string, password?: string, roles?: string[] }) {\n return transport.request<{ user: AdminUser }>(adminPath + \"/users/\" + encodeURIComponent(userId), {\n method: \"PUT\",\n body: JSON.stringify(data)\n });\n }\n\n async function deleteUser(userId: string) {\n return transport.request<{ success: boolean }>(adminPath + \"/users/\" + encodeURIComponent(userId), {\n method: \"DELETE\"\n });\n }\n\n async function resetPassword(userId: string, options?: { password?: string }) {\n return transport.request<{ user: AdminUser; temporaryPassword?: string; invitationSent?: boolean }>(\n adminPath + \"/users/\" + encodeURIComponent(userId) + \"/reset-password\",\n {\n method: \"POST\",\n ...(options?.password ? { body: JSON.stringify({ password: options.password }) } : {})\n }\n );\n }\n\n async function listRoles() {\n return transport.request<{ roles: Array<{ id: string; name: string }> }>(\n adminPath + \"/roles\",\n { method: \"GET\" }\n );\n }\n\n async function bootstrap() {\n return transport.request<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>(adminPath + \"/bootstrap\", {\n method: \"POST\"\n });\n }\n\n return {\n listUsers,\n listUsersPaginated,\n getUser,\n createUser,\n updateUser,\n deleteUser,\n resetPassword,\n listRoles,\n bootstrap\n };\n}\n","import { Transport } from \"./transport\";\nimport type { CronJobStatus, CronJobLogEntry } from \"@rebasepro/types\";\n\nexport interface CreateCronOptions {\n cronPath?: string;\n}\n\nexport function createCron(transport: Transport, options?: CreateCronOptions) {\n const cronPath = options?.cronPath || \"/cron\";\n\n async function listJobs(): Promise<{ jobs: CronJobStatus[] }> {\n return transport.request<{ jobs: CronJobStatus[] }>(cronPath, { method: \"GET\" });\n }\n\n async function getJob(jobId: string): Promise<{ job: CronJobStatus }> {\n return transport.request<{ job: CronJobStatus }>(\n cronPath + \"/\" + encodeURIComponent(jobId),\n { method: \"GET\" }\n );\n }\n\n async function triggerJob(jobId: string): Promise<{ log: CronJobLogEntry; job: CronJobStatus }> {\n return transport.request<{ log: CronJobLogEntry; job: CronJobStatus }>(\n cronPath + \"/\" + encodeURIComponent(jobId) + \"/trigger\",\n { method: \"POST\" }\n );\n }\n\n async function getJobLogs(\n jobId: string,\n options?: { limit?: number }\n ): Promise<{ logs: CronJobLogEntry[] }> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return transport.request<{ logs: CronJobLogEntry[] }>(\n cronPath + \"/\" + encodeURIComponent(jobId) + \"/logs\" + (qs ? \"?\" + qs : \"\"),\n { method: \"GET\" }\n );\n }\n\n async function toggleJob(\n jobId: string,\n enabled: boolean\n ): Promise<{ job: CronJobStatus }> {\n return transport.request<{ job: CronJobStatus }>(\n cronPath + \"/\" + encodeURIComponent(jobId),\n {\n method: \"PUT\",\n body: JSON.stringify({ enabled })\n }\n );\n }\n\n return {\n listJobs,\n getJob,\n triggerJob,\n getJobLogs,\n toggleJob\n };\n}\n","import type { Transport } from \"./transport\";\n\n// Re-define the types locally since they live in server-core, not in @rebasepro/types.\n// These match the server-side types exactly.\n\n/** A single permission entry scoping an API key to a collection and its allowed operations. */\nexport interface ApiKeyPermission {\n collection: string;\n operations: (\"read\" | \"write\" | \"delete\")[];\n}\n\n/** An API key with the secret portion masked (returned by list / get / update). */\nexport interface ApiKeyMasked {\n id: string;\n name: string;\n key_prefix: string;\n permissions: ApiKeyPermission[];\n rate_limit: number | null;\n created_by: string;\n created_at: string;\n updated_at: string;\n last_used_at: string | null;\n expires_at: string | null;\n revoked_at: string | null;\n}\n\n/** An API key including the full secret (returned only on creation). */\nexport interface ApiKeyWithSecret extends ApiKeyMasked {\n key: string;\n}\n\n/** Payload for creating a new API key. */\nexport interface CreateApiKeyRequest {\n name: string;\n permissions: ApiKeyPermission[];\n rate_limit?: number | null;\n expires_at?: string | null;\n}\n\n/** Payload for updating an existing API key. */\nexport interface UpdateApiKeyRequest {\n name?: string;\n permissions?: ApiKeyPermission[];\n rate_limit?: number | null;\n expires_at?: string | null;\n}\n\n/** Options for the `createApiKeys` factory. */\nexport interface CreateApiKeysOptions {\n apiKeysPath?: string;\n}\n\n/**\n * Creates a client for managing API keys via the admin routes.\n *\n * @param transport - The shared HTTP transport created by `createTransport`.\n * @param options - Optional overrides (e.g. a custom base path).\n */\nexport function createApiKeys(transport: Transport, options?: CreateApiKeysOptions) {\n const apiKeysPath = options?.apiKeysPath || \"/admin/api-keys\";\n\n /** List all API keys (masked). */\n async function listKeys(): Promise<{ keys: ApiKeyMasked[] }> {\n return transport.request<{ keys: ApiKeyMasked[] }>(apiKeysPath, { method: \"GET\" });\n }\n\n /** Get a single API key by ID (masked). */\n async function getKey(id: string): Promise<{ key: ApiKeyMasked }> {\n return transport.request<{ key: ApiKeyMasked }>(\n apiKeysPath + \"/\" + encodeURIComponent(id),\n { method: \"GET\" }\n );\n }\n\n /** Create a new API key. The full secret is included in the response. */\n async function createKey(data: CreateApiKeyRequest): Promise<{ key: ApiKeyWithSecret }> {\n return transport.request<{ key: ApiKeyWithSecret }>(apiKeysPath, {\n method: \"POST\",\n body: JSON.stringify(data)\n });\n }\n\n /** Update an existing API key. */\n async function updateKey(id: string, data: UpdateApiKeyRequest): Promise<{ key: ApiKeyMasked }> {\n return transport.request<{ key: ApiKeyMasked }>(\n apiKeysPath + \"/\" + encodeURIComponent(id),\n {\n method: \"PUT\",\n body: JSON.stringify(data)\n }\n );\n }\n\n /** Revoke (soft-delete) an API key. */\n async function revokeKey(id: string): Promise<{ success: boolean }> {\n return transport.request<{ success: boolean }>(\n apiKeysPath + \"/\" + encodeURIComponent(id),\n { method: \"DELETE\" }\n );\n }\n\n return {\n listKeys,\n getKey,\n createKey,\n updateKey,\n revokeKey\n };\n}\n","import { buildQueryString, FindParams, RebaseApiError, Transport } from \"./transport\";\nimport { RebaseWebSocketClient } from \"./websocket\";\nimport {\n CollectionAccessor,\n Entity,\n FilterOperator,\n FilterValues,\n FindResponse,\n WhereFieldValue,\n WhereFilterOp,\n LogicalCondition,\n WhereValue\n} from \"@rebasepro/types\";\n\nimport { QueryBuilder } from \"./query_builder\";\n\nfunction parseWhereFilter(where?: Record<string, WhereFieldValue>): FilterValues<string> | undefined {\n if (!where) return undefined;\n const filters: Record<string, any> = {};\n\n const OP_TO_FILTER: Record<string, WhereFilterOp> = {\n \"eq\": \"==\",\n \"neq\": \"!=\",\n \"gt\": \">\",\n \"gte\": \">=\",\n \"lt\": \"<\",\n \"lte\": \"<=\",\n \"==\": \"==\",\n \"!=\": \"!=\",\n \">\": \">\",\n \">=\": \">=\",\n \"<\": \"<\",\n \"<=\": \"<=\",\n \"in\": \"in\",\n \"nin\": \"not-in\",\n \"not-in\": \"not-in\",\n \"cs\": \"array-contains\",\n \"csa\": \"array-contains-any\",\n \"array-contains\": \"array-contains\",\n \"array-contains-any\": \"array-contains-any\"\n };\n\n const parseSingle = (rawValue: any, fieldKey: string): [WhereFilterOp, unknown] => {\n if (rawValue === null) return [\"==\", null];\n if (typeof rawValue === \"boolean\") return [\"==\", rawValue];\n if (typeof rawValue === \"number\") return [\"==\", rawValue];\n\n if (Array.isArray(rawValue) && rawValue.length === 2 && typeof rawValue[0] === \"string\") {\n const [rawOp, val] = rawValue;\n return [OP_TO_FILTER[rawOp] ?? \"==\", val];\n }\n\n const value = String(rawValue);\n const dotIndex = value.indexOf(\".\");\n if (dotIndex > 0) {\n const opStr = value.substring(0, dotIndex);\n const valStr = value.substring(dotIndex + 1);\n let op: WhereFilterOp = \"==\";\n let val: string | number | boolean | null | string[] = valStr;\n\n switch (opStr) {\n case \"eq\":\n op = \"==\";\n break;\n case \"neq\":\n op = \"!=\";\n break;\n case \"gt\":\n op = \">\";\n break;\n case \"gte\":\n op = \">=\";\n break;\n case \"lt\":\n op = \"<\";\n break;\n case \"lte\":\n op = \"<=\";\n break;\n case \"in\":\n op = \"in\";\n val = valStr.startsWith(\"(\") && valStr.endsWith(\")\")\n ? valStr.slice(1, -1).split(\",\").map(v => v.trim())\n : valStr.split(\",\");\n break;\n case \"nin\":\n op = \"not-in\";\n val = valStr.startsWith(\"(\") && valStr.endsWith(\")\")\n ? valStr.slice(1, -1).split(\",\").map(v => v.trim())\n : valStr.split(\",\");\n break;\n case \"cs\":\n op = \"array-contains\";\n break;\n case \"csa\":\n op = \"array-contains-any\";\n val = valStr.startsWith(\"(\") && valStr.endsWith(\")\")\n ? valStr.slice(1, -1).split(\",\").map(v => v.trim())\n : valStr.split(\",\");\n break;\n default:\n op = \"==\";\n val = value;\n }\n if (val === \"true\") val = true;\n else if (val === \"false\") val = false;\n else if (val === \"null\") val = null;\n else if (typeof val === \"string\" && /^[0-9]+(\\.[0-9]+)?$/.test(val) && fieldKey !== \"id\" && !fieldKey.endsWith(\"_id\")) val = Number(val);\n\n return [op, val];\n } else {\n return [\"==\", value];\n }\n };\n\n for (const [key, rawValue] of Object.entries(where)) {\n if (Array.isArray(rawValue) && rawValue.length > 0 && Array.isArray(rawValue[0])) {\n filters[key] = rawValue.map(r => parseSingle(r, key));\n } else {\n filters[key] = parseSingle(rawValue, key);\n }\n }\n return filters;\n}\n\n/**\n * Wrap a flat row (returned by the REST API as `{ id, ...fields }`) into\n * a proper `Entity<M>` structure expected by the core framework.\n * The `id` is kept inside `values` as well, since collection properties\n * may define an `isId` field that the form binds to `formex.values`.\n */\nfunction rowToEntity<M extends Record<string, unknown>>(row: Record<string, unknown>, slug: string): Entity<M> {\n return {\n id: row.id as string | number,\n path: slug,\n values: row as M\n };\n}\n\n/**\n * CollectionClient extends `CollectionAccessor` from `@rebasepro/types` so that\n * `client.data` can be passed directly to the core Rebase component.\n *\n * Additionally it exposes fluent query builder methods like `.where()`, `.orderBy()`.\n */\nexport interface CollectionClient<M extends Record<string, unknown> = Record<string, unknown>> extends CollectionAccessor<M> {\n where<K extends keyof M & string>(column: K, operator: FilterOperator, value: WhereValue<M[K]>): QueryBuilder<M>;\n where(logicalCondition: LogicalCondition): QueryBuilder<M>;\n\n orderBy(column: keyof M & string, ascending?: \"asc\" | \"desc\"): QueryBuilder<M>;\n\n limit(count: number): QueryBuilder<M>;\n\n offset(count: number): QueryBuilder<M>;\n\n search(searchString: string): QueryBuilder<M>;\n\n include(...relations: string[]): QueryBuilder<M>;\n\n count(params?: FindParams): Promise<number>;\n}\n\nexport function createCollectionClient<M extends Record<string, unknown> = Record<string, unknown>>(transport: Transport, slug: string, ws?: RebaseWebSocketClient): CollectionClient<M> {\n const basePath = `/data/${slug}`;\n\n const client: CollectionClient<M> = {\n async find(params?: FindParams): Promise<FindResponse<M>> {\n const qs = buildQueryString(params);\n const raw = await transport.request<{\n data: Record<string, unknown>[];\n meta: FindResponse<M>[\"meta\"]\n }>(basePath + qs, { method: \"GET\" });\n return {\n data: (raw.data || []).map((row: Record<string, unknown>) => rowToEntity<M>(row, slug)),\n meta: raw.meta\n };\n },\n\n async findById(id: string | number) {\n try {\n const raw = await transport.request<Record<string, unknown>>(`${basePath}/${encodeURIComponent(String(id))}`, { method: \"GET\" });\n if (!raw) return undefined;\n return rowToEntity<M>(raw, slug);\n } catch (err) {\n if (err instanceof RebaseApiError && err.status === 404) {\n return undefined;\n }\n throw err;\n }\n },\n\n async create(data: Partial<M>, id?: string | number) {\n const body: Record<string, unknown> = { ...data };\n if (id !== undefined) {\n body.id = id;\n }\n const raw = await transport.request<Record<string, unknown>>(basePath, {\n method: \"POST\",\n body: JSON.stringify(body)\n });\n return rowToEntity<M>(raw, slug);\n },\n\n async update(id: string | number, data: Partial<M>) {\n const raw = await transport.request<Record<string, unknown>>(`${basePath}/${encodeURIComponent(String(id))}`, {\n method: \"PUT\",\n body: JSON.stringify(data)\n });\n return rowToEntity<M>(raw, slug);\n },\n\n async delete(id: string | number) {\n return transport.request<void>(`${basePath}/${encodeURIComponent(String(id))}`, {\n method: \"DELETE\"\n });\n },\n\n async count(params?: FindParams): Promise<number> {\n const countParams: FindParams = {\n ...params,\n limit: undefined,\n offset: undefined\n };\n const qs = buildQueryString(countParams);\n const raw = await transport.request<{ count: number }>(basePath + \"/count\" + qs, { method: \"GET\" });\n return raw.count ?? 0;\n },\n\n // Fluent builder instantiation\n where(columnOrCondition: string | LogicalCondition, operator?: FilterOperator, value?: unknown) {\n const builder = new QueryBuilder<M>(client as unknown as CollectionAccessor<M>);\n if (typeof columnOrCondition === \"object\") {\n return builder.where(columnOrCondition);\n }\n return builder.where(columnOrCondition as keyof M & string, operator!, value as WhereValue<M[keyof M & string]>);\n },\n orderBy(column: keyof M & string, ascending?: \"asc\" | \"desc\") {\n return new QueryBuilder<M>(client).orderBy(column, ascending);\n },\n limit(count: number) {\n return new QueryBuilder<M>(client).limit(count);\n },\n offset(count: number) {\n return new QueryBuilder<M>(client).offset(count);\n },\n search(searchString: string) {\n return new QueryBuilder<M>(client).search(searchString);\n },\n include(...relations: string[]) {\n return new QueryBuilder<M>(client).include(...relations);\n }\n };\n\n if (ws) {\n client.listen = (params: FindParams | undefined, onUpdate: (response: FindResponse<M>) => void, onError?: (error: Error) => void) => {\n return ws.listenCollection(\n {\n path: slug,\n filter: parseWhereFilter(params?.where),\n limit: params?.limit,\n startAfter: params?.offset ? String(params.offset) : undefined,\n orderBy: params?.orderBy?.split(\":\")[0],\n order: params?.orderBy?.split(\":\")[1] as \"asc\" | \"desc\",\n searchString: params?.searchString\n },\n (entities: Entity[]) => {\n const requestedLimit = params?.limit || 20;\n onUpdate({\n data: entities as Entity<M>[],\n meta: {\n total: entities.length,\n limit: requestedLimit,\n offset: params?.offset || 0,\n hasMore: entities.length >= requestedLimit\n }\n });\n },\n onError\n );\n };\n\n client.listenById = (id: string | number, onUpdate: (data: Entity<M> | undefined) => void, onError?: (error: Error) => void) => {\n return ws.listenEntity(\n {\n path: slug,\n entityId: String(id)\n },\n (entity: Entity | null) => {\n if (entity) {\n onUpdate(entity as Entity<M>);\n } else {\n onUpdate(undefined);\n }\n },\n onError\n );\n };\n }\n\n return client;\n}\n","import type { Transport } from \"./transport\";\n\n/**\n * Client interface for invoking custom backend functions.\n *\n * Custom functions are Hono route files auto-mounted by the Rebase backend\n * at `/api/functions/{name}`. The `FunctionsClient` wraps the shared\n * transport so callers never need to manually construct URLs or inject\n * auth tokens.\n *\n * @example\n * ```ts\n * const result = await client.functions.invoke<{ job: Job }>('extract-job', {\n * url: 'https://example.com/posting',\n * html: htmlContent,\n * });\n * ```\n */\nexport interface FunctionsClient {\n /**\n * Invoke a custom backend function by name.\n *\n * @typeParam T - Expected shape of the response payload.\n * @param name - Function name (the filename without extension, e.g. `\"extract-job\"`).\n * @param payload - Optional JSON-serialisable body sent as `POST`.\n * @param options - Optional overrides (HTTP method, sub-path, extra headers).\n * @returns The parsed JSON response from the function.\n */\n invoke<T = unknown>(\n name: string,\n payload?: unknown,\n options?: FunctionInvokeOptions,\n ): Promise<T>;\n}\n\nexport interface FunctionInvokeOptions {\n /** HTTP method — defaults to `\"POST\"`. */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n /** Sub-path appended after the function name, e.g. `\"status/123\"`. */\n path?: string;\n /** Extra headers merged into the request (auth is still injected automatically). */\n headers?: Record<string, string>;\n}\n\n/**\n * Create a `FunctionsClient` backed by the given transport.\n *\n * The transport already handles:\n * - Base URL resolution\n * - JWT injection via `Authorization: Bearer`\n * - 401 retry / `onUnauthorized` flow\n * - Consistent error throwing via `RebaseApiError`\n *\n * @internal\n */\nexport function createFunctionsClient(transport: Transport): FunctionsClient {\n return {\n async invoke<T = unknown>(\n name: string,\n payload?: unknown,\n options?: FunctionInvokeOptions\n ): Promise<T> {\n const method = options?.method ?? \"POST\";\n const subPath = options?.path ? `/${options.path.replace(/^\\//, \"\")}` : \"\";\n const routePath = `/functions/${encodeURIComponent(name)}${subPath}`;\n\n const init: RequestInit = { method };\n\n if (payload !== undefined && method !== \"GET\") {\n init.body = JSON.stringify(payload);\n }\n\n if (options?.headers) {\n init.headers = options.headers;\n }\n\n return transport.request<T>(routePath, init);\n }\n };\n}\n","import { StorageSource, UploadFileProps, UploadFileResult, DownloadConfig, StorageListResult, DownloadMetadata } from \"@rebasepro/types\";\nimport { Transport } from \"./transport\";\n\nexport function createStorage(transport: Transport): StorageSource {\n const urlsCache = new Map<string, DownloadConfig>();\n\n // We expect the transport to point to /api, and storage endpoints handle /api/storage internally if they are relative?\n // Wait, useBackendStorageSource uses `${apiUrl}/api/storage` directly.\n // Transport has `.request` which hits `${config.baseUrl}${config.apiPath}${path}`.\n // Assuming `config.apiPath` is \"/api\", we just request(`/storage/upload`, ...).\n\n async function putObject({\n file,\n key,\n metadata,\n bucket\n }: UploadFileProps): Promise<UploadFileResult> {\n const formData = new FormData();\n formData.append(\"file\", file);\n\n if (key) formData.append(\"key\", key);\n if (bucket) formData.append(\"bucket\", bucket);\n\n if (metadata) {\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== undefined && value !== null) {\n formData.append(\n `metadata_${key}`,\n typeof value === \"string\" ? value : JSON.stringify(value)\n );\n }\n }\n }\n\n // We use fetchFn directly if we need to do multipart boundary, but Transport.request might override Content-Type?\n // Wait, transport.request defaults to application/json. We must remove Content-Type header or allow it to be evaluated by fetch when body is FormData!\n const result = await transport.request<{ data: UploadFileResult }>(\"/storage/upload\", {\n method: \"POST\",\n body: formData,\n headers: {\n // transport.request merges headers, so to prevent it setting application/json we can delete it\n // in transport if body is FormData, or we can explicitly set it to an empty string.\n // Let's rely on standard behaviour for now and adjust transport if it fails.\n }\n });\n\n return result.data;\n }\n\n async function getSignedUrl(\n keyOrUrl: string,\n bucket?: string\n ): Promise<DownloadConfig> {\n const cacheKey = bucket ? `${bucket}/${keyOrUrl}` : keyOrUrl;\n const cached = urlsCache.get(cacheKey);\n if (cached) return cached;\n\n let filePath = keyOrUrl;\n\n if (filePath && (filePath.startsWith(\"local://\") || filePath.startsWith(\"s3://\"))) {\n filePath = filePath.substring(filePath.indexOf(\"://\") + 3);\n }\n\n if (bucket && filePath && !filePath.startsWith(bucket)) {\n filePath = `${bucket}/${filePath}`;\n }\n\n if (!filePath || filePath.trim() === \"\" || filePath === \"/\") {\n return { url: null,\nfileNotFound: true };\n }\n\n try {\n const result = await transport.request<{ data: DownloadMetadata }>(`/storage/metadata/${filePath}`);\n\n const activeToken = await transport.resolveToken();\n const tokenQuery = activeToken ? `?token=${activeToken}` : \"\";\n\n const downloadConfig: DownloadConfig = {\n url: `${transport.baseUrl}${transport.apiPath}/storage/file/${filePath}${tokenQuery}`,\n metadata: result.data\n };\n\n urlsCache.set(cacheKey, downloadConfig);\n return downloadConfig;\n } catch (e: unknown) {\n if (e instanceof Error && \"status\" in e && (e as { status: number }).status === 404) {\n return { url: null,\nfileNotFound: true };\n }\n throw e;\n }\n }\n\n async function getObject(\n key: string,\n bucket?: string\n ): Promise<File | null> {\n let filePath = key;\n\n if (filePath && (filePath.startsWith(\"local://\") || filePath.startsWith(\"s3://\"))) {\n filePath = filePath.substring(filePath.indexOf(\"://\") + 3);\n }\n\n if (bucket && filePath && !filePath.startsWith(bucket)) {\n filePath = `${bucket}/${filePath}`;\n }\n\n if (!filePath || filePath.trim() === \"\" || filePath === \"/\") {\n return null;\n }\n\n // We must use plain fetch because transport.request expects JSON response, but here we want a Blob.\n const url = `${transport.baseUrl}${transport.apiPath}/storage/file/${filePath}`;\n\n // This is a bit manual, but necessary for blob handling\n const response = await transport.fetchFn(url, {\n headers: transport.getHeaders ? transport.getHeaders() : {}\n });\n\n if (response.status === 404) return null;\n if (!response.ok) throw new Error(\"Failed to get file\");\n\n const blob = await response.blob();\n const fileName = filePath.split(\"/\").pop() || \"file\";\n return new File([blob], fileName, { type: blob.type });\n }\n\n async function deleteObject(\n key: string,\n bucket?: string\n ): Promise<void> {\n let filePath = key;\n\n if (filePath && (filePath.startsWith(\"local://\") || filePath.startsWith(\"s3://\"))) {\n filePath = filePath.substring(filePath.indexOf(\"://\") + 3);\n }\n\n if (bucket && filePath && !filePath.startsWith(bucket)) {\n filePath = `${bucket}/${filePath}`;\n }\n\n if (!filePath || filePath.trim() === \"\" || filePath === \"/\") {\n return;\n }\n\n try {\n await transport.request(`/storage/file/${filePath}`, { method: \"DELETE\" });\n } catch (e: unknown) {\n if (!(e instanceof Error && \"status\" in e && (e as { status: number }).status === 404)) throw e;\n }\n\n urlsCache.delete(bucket ? `${bucket}/${key}` : key);\n }\n\n async function listObjects(\n prefix: string,\n options?: {\n bucket?: string;\n maxResults?: number;\n pageToken?: string;\n }\n ): Promise<StorageListResult> {\n const params = new URLSearchParams();\n if (prefix) params.set(\"prefix\", prefix);\n if (options?.bucket) params.set(\"bucket\", options.bucket);\n if (options?.maxResults) params.set(\"maxResults\", String(options.maxResults));\n if (options?.pageToken) params.set(\"pageToken\", options.pageToken);\n\n const result = await transport.request<{ data: StorageListResult }>(`/storage/list?${params.toString()}`);\n return result.data;\n }\n\n return {\n putObject,\n getSignedUrl,\n getObject,\n deleteObject,\n listObjects\n };\n}\n","import {\n DeleteEntityProps,\n Entity,\n EntityCollection,\n FetchCollectionProps,\n FetchEntityProps,\n SaveEntityProps,\n WebSocketMessage,\n WebSocketErrorPayload,\n CollectionUpdateMessage,\n EntityUpdateMessage,\n TableMetadata,\n BranchInfo\n} from \"@rebasepro/types\";\nimport { rebaseReviver } from \"./reviver\";\n\n\n\n/**\n * Extract error message and code from a WebSocket message payload.\n * Handles both `{ error: string }` and `{ error: { message, code } }` shapes.\n */\nfunction extractMessageError(message: WebSocketMessage): { errorMessage: string; errorCode?: string } {\n const payload = message.payload as WebSocketErrorPayload | undefined;\n const errPayload = payload?.error;\n const errorMessage = typeof errPayload === \"object\"\n ? errPayload.message\n : payload?.message || (typeof errPayload === \"string\" ? errPayload : undefined) || message.error || \"Unknown error\";\n const errorCode = typeof errPayload === \"object\"\n ? errPayload.code\n : payload?.code;\n return { errorMessage,\nerrorCode };\n}\n\nexport interface RebaseWebSocketConfig {\n websocketUrl: string;\n /** Optional auth token getter for WebSocket authentication */\n getAuthToken?: () => Promise<string | null>;\n /** Optional WebSocket constructor to override globalThis.WebSocket (e.g. for Node environments) */\n WebSocket?: typeof WebSocket;\n /** Callback to handle unauthorized requests or token expiration (refreshes auth session) */\n onUnauthorized?: () => Promise<boolean>;\n}\n\n\nexport class ApiError extends Error {\n public code?: string;\n public error?: string;\n\n constructor(message: string, error?: string, code?: string) {\n super(message);\n this.name = \"ApiError\";\n this.code = code;\n this.error = error;\n }\n}\n\n\nexport class RebaseWebSocketClient {\n private websocketUrl: string;\n private ws: WebSocket | null = null;\n public getAuthToken?: () => Promise<string | null>;\n private subscriptions = new Map<string, {\n onUpdate: (data: WebSocketMessage) => void,\n onError?: (error: Error) => void\n }>();\n\n private listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n public on(event: \"connect\" | \"disconnect\" | \"reconnect\" | \"error\", cb: (...args: unknown[]) => void) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n return () => this.listeners.get(event)!.delete(cb);\n }\n\n private emit(event: string, ...args: unknown[]) {\n if (this.listeners.has(event)) {\n this.listeners.get(event)!.forEach(cb => cb(...args));\n }\n }\n\n // New: Subscription deduplication management with optimizations\n private collectionSubscriptions = new Map<string, {\n backendSubscriptionId: string;\n callbacks: Map<string, {\n onUpdate: (entities: Entity[]) => void;\n onError?: (error: Error) => void;\n }>;\n props: FetchCollectionProps;\n latestData?: Entity[]; // Cache the latest data\n lastUpdated?: number; // Timestamp for cache invalidation\n isInitialDataReceived?: boolean; // Track if we got initial data\n }>();\n\n private entitySubscriptions = new Map<string, {\n backendSubscriptionId: string;\n callbacks: Map<string, {\n onUpdate: (entity: Entity | null) => void;\n onError?: (error: Error) => void;\n }>;\n props: FetchEntityProps;\n latestData?: Entity | null; // Cache the latest data\n lastUpdated?: number; // Timestamp for cache invalidation\n isInitialDataReceived?: boolean; // Track if we got initial data\n }>();\n\n // Maps to quickly find subscription by backend subscription ID\n private backendToCollectionKey = new Map<string, string>();\n private backendToEntityKey = new Map<string, string>();\n\n\n private pendingRequests = new Map<string, {\n resolve: (p: unknown) => void;\n reject: (p: Error) => void;\n message?: Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void }\n }>();\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private isConnected = false;\n private messageQueue: Record<string, unknown>[] = [];\n private requestTimeoutMs = 30000;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n\n private isAuthenticated = false;\n private authPromise: Promise<void> | null = null;\n private WebSocketConstructor: typeof WebSocket | undefined;\n public onUnauthorized?: () => Promise<boolean>;\n private refreshInProgress: Promise<boolean> | null = null;\n\n constructor(config: RebaseWebSocketConfig) {\n this.websocketUrl = config.websocketUrl;\n this.getAuthToken = config.getAuthToken;\n this.onUnauthorized = config.onUnauthorized;\n this.WebSocketConstructor = config.WebSocket || (typeof WebSocket !== \"undefined\" ? WebSocket : undefined);\n\n if (!this.WebSocketConstructor) {\n console.warn(\"WebSocket is not defined in this environment. Realtime subscriptions will not work unless you provide a WebSocket implementation in the config.\");\n } else {\n this.initWebSocket();\n }\n }\n\n /**\n * Authenticate the WebSocket connection\n */\n async authenticate(token: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const requestId = `auth_${Date.now()}`;\n\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n this.authPromise = null; // Clear promise so we can retry later\n reject(new Error(\"Authentication timeout\"));\n }, 30000);\n\n this.pendingRequests.set(requestId, {\n resolve: () => {\n clearTimeout(timeout);\n this.isAuthenticated = true;\n resolve();\n },\n reject: (error) => {\n clearTimeout(timeout);\n reject(error);\n }\n });\n\n const message = {\n type: \"AUTHENTICATE\",\n requestId,\n payload: { token }\n };\n\n if (!this.isConnected || !this.ws) {\n this.messageQueue.unshift(message); // Auth should be first\n } else {\n this.ws.send(JSON.stringify(message));\n }\n });\n }\n\n /**\n * Set the auth token getter function\n */\n setAuthTokenGetter(getAuthToken: () => Promise<string | null>): void {\n this.getAuthToken = getAuthToken;\n // Auto-authenticate if we are already connected but didn't have the token getter yet\n if (this.isConnected && !this.isAuthenticated && !this.authPromise) {\n console.debug(\"WebSocket auto-authenticating after token getter set\");\n this.getAuthToken().then(token => {\n if (!this.ws) return; // Prevent memory leaks / actions after disconnect\n if (token) {\n this.authenticate(token).catch(e => {\n if (this.ws) console.debug(\"WebSocket auto-auth skipped:\", e?.message || e);\n });\n }\n }).catch(e => {\n // User not logged in or auth still loading — this is expected,\n // the WebSocket will authenticate on-demand when a request is made.\n if (this.ws) console.debug(\"WebSocket auto-auth skipped:\", e?.message || e);\n });\n }\n }\n\n public disconnect(): void {\n this.isAuthenticated = false;\n this.authPromise = null;\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect on explicit disconnect\n this.ws.onerror = null; // Prevent errors on explicit disconnect\n this.ws.onopen = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n }\n\n // Initialize WebSocket connection\n private initWebSocket() {\n if (!this.WebSocketConstructor) return;\n if (this.ws?.readyState === this.WebSocketConstructor.OPEN) return;\n\n // Guard against race condition: if a previous socket is still connecting, tear it down\n if (this.ws) {\n this.ws.onclose = null;\n this.ws.close();\n this.ws = null;\n }\n\n try {\n this.ws = new this.WebSocketConstructor(this.websocketUrl);\n\n this.ws!.onopen = async () => {\n console.debug(\"Connected to PostgreSQL backend\");\n const wasReconnect = this.reconnectAttempts > 0;\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n // Auto-authenticate if token getter is available\n if (this.getAuthToken && !this.isAuthenticated) {\n try {\n const token = await this.getAuthToken();\n if (token) {\n await this.authenticate(token);\n console.debug(\"WebSocket auto-authenticated\");\n }\n } catch (error) {\n // User not logged in or auth still loading — this is expected.\n // Authentication will happen on-demand when the user logs in.\n console.debug(\"WebSocket connected without auth:\", (error as Error)?.message || error);\n }\n }\n\n this.emit(wasReconnect ? \"reconnect\" : \"connect\");\n this.processMessageQueue();\n\n // Re-subscribe all active subscriptions after reconnect.\n // The server-side subscription state was lost when the connection dropped,\n // so we need to re-register every active subscription.\n if (wasReconnect) {\n this.resubscribeAll();\n }\n };\n\n this.ws!.onmessage = (event) => {\n try {\n const message = JSON.parse(event.data, rebaseReviver);\n this.handleWebSocketMessage(message);\n } catch (error) {\n console.error(\"Error parsing WebSocket message:\", error);\n }\n };\n\n this.ws!.onclose = () => {\n console.debug(\"Disconnected from PostgreSQL backend\");\n this.isConnected = false;\n this.isAuthenticated = false;\n this.authPromise = null;\n this.emit(\"disconnect\");\n\n // Re-queue pending requests so the UI doesn't hang indefinitely or crash\n for (const [reqId, request] of this.pendingRequests.entries()) {\n if (reqId.startsWith(\"auth_\")) {\n request.reject(new Error(\"Connection closed during authentication\"));\n } else if (request.message) {\n request.message._queuedResolve = request.resolve;\n request.message._queuedReject = request.reject;\n this.messageQueue.push(request.message);\n } else {\n request.reject(new ApiError(\"Connection closed\", \"Connection closed\"));\n }\n this.pendingRequests.delete(reqId);\n }\n\n this.attemptReconnect();\n };\n\n this.ws!.onerror = (error) => {\n console.error(\"WebSocket error:\", error);\n this.isConnected = false;\n this.emit(\"error\", error);\n };\n } catch (error) {\n console.error(\"Failed to initialize WebSocket:\", error);\n this.attemptReconnect();\n }\n }\n\n private processMessageQueue() {\n while (this.messageQueue.length > 0 && this.isConnected) {\n const message = this.messageQueue.shift();\n if (message) this.sendMessage(message);\n }\n }\n\n private attemptReconnect() {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n console.error(\"Max reconnection attempts reached\");\n return;\n }\n\n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n\n console.debug(`Attempting to reconnect in ${delay}ms (attempt ${this.reconnectAttempts})`);\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n }\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n this.initWebSocket();\n }, delay);\n }\n\n private isAuthError(message: WebSocketMessage): boolean {\n if (message.type === \"AUTH_ERROR\") return true;\n const { errorMessage, errorCode } = extractMessageError(message);\n if (errorCode === \"UNAUTHORIZED\" || errorCode === \"JWT_EXPIRED\" || errorCode === \"AUTH_ERROR\") return true;\n const lowerMessage = errorMessage.toLowerCase();\n return lowerMessage.includes(\"unauthorized\") || lowerMessage.includes(\"token expired\") || lowerMessage.includes(\"token is expired\") || lowerMessage.includes(\"invalid token\") || lowerMessage.includes(\"session expired\") || lowerMessage.includes(\"auth error\");\n }\n\n private async handleAuthFailure(): Promise<boolean> {\n if (this.refreshInProgress) {\n return this.refreshInProgress;\n }\n this.refreshInProgress = (async () => {\n this.isAuthenticated = false;\n this.authPromise = null;\n if (this.onUnauthorized) {\n try {\n const refreshed = await this.onUnauthorized();\n if (refreshed && this.getAuthToken) {\n const token = await this.getAuthToken();\n if (token) {\n await this.authenticate(token);\n return true;\n }\n }\n } catch (error) {\n console.error(\"WebSocket auth refresh failed:\", error);\n }\n }\n return false;\n })();\n try {\n return await this.refreshInProgress;\n } finally {\n this.refreshInProgress = null;\n }\n }\n\n /**\n * Shared logic for re-subscribing a collection or entity subscription\n * after an auth error is resolved by refreshing credentials.\n */\n private resubscribeAfterAuthRefresh(\n message: WebSocketMessage,\n subscription: {\n backendSubscriptionId: string;\n callbacks: Map<string, { onUpdate: (...args: never[]) => void; onError?: (error: Error) => void }>;\n props: FetchCollectionProps | FetchEntityProps;\n },\n subscriptionKey: string,\n idPrefix: \"collection\" | \"entity\",\n backendKeyMap: Map<string, string>,\n messageType: \"subscribe_collection\" | \"subscribe_entity\"\n ): void {\n this.handleAuthFailure().then(refreshed => {\n if (refreshed) {\n const oldBackendId = subscription.backendSubscriptionId;\n const newBackendId = `${idPrefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n subscription.backendSubscriptionId = newBackendId;\n backendKeyMap.delete(oldBackendId);\n backendKeyMap.set(newBackendId, subscriptionKey);\n\n this.sendMessage({\n type: messageType,\n payload: {\n ...subscription.props,\n subscriptionId: newBackendId\n }\n }).catch(error => {\n console.error(`[WS] Failed to re-subscribe ${idPrefix} after auth refresh:`, subscriptionKey, error);\n subscription.callbacks.forEach(callback => {\n if (callback.onError) callback.onError(error);\n });\n });\n } else {\n const { errorMessage, errorCode } = extractMessageError(message);\n const error = new ApiError(errorMessage, errorMessage, errorCode);\n subscription.callbacks.forEach(callback => {\n if (callback.onError) callback.onError(error);\n });\n }\n }).catch(err => {\n subscription.callbacks.forEach(callback => {\n if (callback.onError) callback.onError(err);\n });\n });\n }\n\n private handleWebSocketMessage(message: WebSocketMessage) {\n const {\n type,\n requestId,\n subscriptionId\n } = message;\n\n // Handle responses to pending requests\n if (requestId && this.pendingRequests.has(requestId)) {\n const pendingReq = this.pendingRequests.get(requestId)!;\n if (type === \"ERROR\" || type === \"AUTH_ERROR\" || message.error) {\n if (this.isAuthError(message)) {\n this.pendingRequests.delete(requestId);\n this.handleAuthFailure().then(refreshed => {\n if (refreshed && pendingReq.message) {\n this.doSendMessage(pendingReq.message, pendingReq.resolve, pendingReq.reject).catch(pendingReq.reject);\n } else {\n const { errorMessage, errorCode } = extractMessageError(message);\n pendingReq.reject(new ApiError(errorMessage, errorMessage, errorCode));\n }\n }).catch(err => {\n pendingReq.reject(err);\n });\n } else {\n this.pendingRequests.delete(requestId);\n const { errorMessage, errorCode } = extractMessageError(message);\n pendingReq.reject(new ApiError(errorMessage, errorMessage, errorCode));\n }\n } else {\n this.pendingRequests.delete(requestId);\n pendingReq.resolve(message.payload || message);\n }\n return;\n }\n\n // Handle subscription updates for collection subscriptions\n if (subscriptionId && type === \"collection_update\") {\n const subscriptionKey = this.backendToCollectionKey.get(subscriptionId);\n if (subscriptionKey) {\n const collectionSub = this.collectionSubscriptions.get(subscriptionKey);\n if (collectionSub) {\n const incomingEntities = (message.entities || []) as Entity[];\n\n // Structural merge: preserve cached entity references for entities\n // whose values haven't changed. This prevents downstream React components\n // from re-rendering (VirtualTableCell uses deepEqual on rowData —\n // same reference = instant true, avoiding expensive deep comparison).\n const entities = this.mergeEntities(collectionSub.latestData, incomingEntities);\n\n // Cache the latest data with optimizations\n collectionSub.latestData = entities;\n collectionSub.lastUpdated = Date.now();\n collectionSub.isInitialDataReceived = true;\n\n // Notify all callbacks for this subscription\n collectionSub.callbacks.forEach(callback => {\n try {\n callback.onUpdate(entities);\n } catch (error) {\n console.error(\"Error in collection subscription callback:\", error);\n if (callback.onError) {\n callback.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n });\n return;\n }\n }\n }\n\n // Handle instant entity-level patches for collection subscriptions.\n // These arrive before the full refetch and give immediate cross-tab feedback.\n if (subscriptionId && type === \"collection_entity_patch\") {\n const subscriptionKey = this.backendToCollectionKey.get(subscriptionId);\n if (subscriptionKey) {\n const collectionSub = this.collectionSubscriptions.get(subscriptionKey);\n if (collectionSub && collectionSub.isInitialDataReceived && collectionSub.latestData) {\n const patchEntity = message.entity ?? null;\n const patchEntityId = (message as unknown as { entityId: string }).entityId;\n let updated: Entity[];\n\n if (patchEntity === null || patchEntity === undefined) {\n // Entity was deleted — remove it from the cached list\n updated = collectionSub.latestData.filter(e => String(e.id) !== String(patchEntityId));\n } else {\n // Entity was created or updated — merge into the cached list\n const idx = collectionSub.latestData.findIndex(e => String(e.id) === String(patchEntity.id));\n if (idx >= 0) {\n // Update in place (preserve array position)\n updated = [...collectionSub.latestData];\n updated[idx] = patchEntity;\n } else {\n // New entity — prepend (most recently created entities first)\n updated = [patchEntity, ...collectionSub.latestData];\n }\n }\n\n collectionSub.latestData = updated;\n collectionSub.lastUpdated = Date.now();\n\n // Fire all callbacks with the patched data\n collectionSub.callbacks.forEach(callback => {\n try {\n callback.onUpdate(updated);\n } catch (error) {\n console.error(\"Error in collection patch callback:\", error);\n if (callback.onError) {\n callback.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n });\n return;\n }\n }\n }\n\n // Handle subscription updates for entity subscriptions\n if (subscriptionId && type === \"entity_update\") {\n const subscriptionKey = this.backendToEntityKey.get(subscriptionId);\n if (subscriptionKey) {\n const entitySub = this.entitySubscriptions.get(subscriptionKey);\n if (entitySub) {\n const entity = message.entity ?? null;\n // Cache the latest data with optimizations\n entitySub.latestData = entity;\n entitySub.lastUpdated = Date.now();\n entitySub.isInitialDataReceived = true;\n\n // Notify all callbacks for this subscription\n entitySub.callbacks.forEach(callback => {\n try {\n callback.onUpdate(entity);\n } catch (error) {\n console.error(\"Error in entity subscription callback:\", error);\n if (callback.onError) {\n callback.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n });\n return;\n }\n }\n }\n\n // Handle subscription errors\n if (subscriptionId && (type === \"ERROR\" || message.error)) {\n const collectionKey = this.backendToCollectionKey.get(subscriptionId);\n if (collectionKey) {\n const collectionSub = this.collectionSubscriptions.get(collectionKey);\n if (collectionSub) {\n if (this.isAuthError(message)) {\n this.resubscribeAfterAuthRefresh(\n message,\n collectionSub,\n collectionKey,\n \"collection\",\n this.backendToCollectionKey,\n \"subscribe_collection\"\n );\n return;\n }\n\n const { errorMessage, errorCode } = extractMessageError(message);\n const error = new ApiError(errorMessage, errorMessage, errorCode);\n collectionSub.callbacks.forEach(callback => {\n if (callback.onError) {\n callback.onError(error);\n }\n });\n return;\n }\n }\n\n const entityKey = this.backendToEntityKey.get(subscriptionId);\n if (entityKey) {\n const entitySub = this.entitySubscriptions.get(entityKey);\n if (entitySub) {\n if (this.isAuthError(message)) {\n this.resubscribeAfterAuthRefresh(\n message,\n entitySub,\n entityKey,\n \"entity\",\n this.backendToEntityKey,\n \"subscribe_entity\"\n );\n return;\n }\n\n const { errorMessage, errorCode } = extractMessageError(message);\n const error = new ApiError(errorMessage, errorMessage, errorCode);\n entitySub.callbacks.forEach(callback => {\n if (callback.onError) {\n callback.onError(error);\n }\n });\n return;\n }\n }\n }\n\n // Legacy subscription handling (for backward compatibility)\n if (subscriptionId && this.subscriptions.has(subscriptionId)) {\n const callback = this.subscriptions.get(subscriptionId);\n if (!callback) {\n throw new Error(`Subscription callback not found for subscriptionId: ${subscriptionId}`);\n }\n if (message.type === \"ERROR\" || message.error) {\n if (callback.onError) {\n const { errorMessage, errorCode } = extractMessageError(message);\n callback.onError(new ApiError(errorMessage, errorMessage, errorCode));\n }\n } else {\n callback.onUpdate(message);\n }\n }\n }\n\n private async ensureAuthenticated(retryCount = 3): Promise<void> {\n // If already authenticated or no token getter, skip\n if (this.isAuthenticated || !this.getAuthToken) return;\n\n // If auth is in progress, wait for it\n if (this.authPromise) {\n await this.authPromise;\n return;\n }\n\n // Try to authenticate with retries\n let lastError: unknown = null;\n\n for (let attempt = 0; attempt < retryCount; attempt++) {\n try {\n const token = await this.getAuthToken();\n if (!token) throw new Error(\"user not logged in\");\n this.authPromise = this.authenticate(token);\n await this.authPromise;\n this.authPromise = null;\n console.debug(\"WebSocket authenticated on demand\");\n return; // Success\n } catch (error: unknown) {\n this.authPromise = null;\n lastError = error;\n\n const errMsg = error instanceof Error ? error.message : String(error);\n // \"not logged in\" / \"Session expired\" are definitive - don't retry\n if (errMsg.includes(\"not logged in\") || errMsg.includes(\"Session expired\")) {\n console.warn(\"WebSocket auth failed: user not logged in\");\n throw error;\n }\n\n // \"still loading\" is transient - retry with backoff (auth controller\n // is restoring tokens from localStorage; it will resolve shortly)\n if (errMsg.includes(\"still loading\")) {\n if (attempt < retryCount - 1) {\n const delay = Math.min(500 * (attempt + 1), 2000);\n await new Promise(resolve => setTimeout(resolve, delay));\n continue;\n }\n }\n\n // For other errors, retry with backoff\n if (attempt < retryCount - 1) {\n const delay = Math.min(1000 * (attempt + 1), 3000);\n console.debug(`WebSocket auth attempt ${attempt + 1} failed, retrying in ${delay}ms...`);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n console.warn(\"WebSocket on-demand auth failed after retries:\", lastError);\n throw lastError;\n }\n\n async reauthenticate(): Promise<void> {\n if (!this.getAuthToken) return;\n\n this.isAuthenticated = false;\n try {\n const token = await this.getAuthToken();\n if (!token) throw new Error(\"user not logged in\");\n await this.authenticate(token);\n console.debug(\"WebSocket reauthenticated successfully\");\n } catch (error) {\n console.error(\"WebSocket reauthentication failed:\", error);\n throw error;\n }\n }\n\n private sendMessage(message: Record<string, unknown>): Promise<unknown> {\n // If already has a requestId (re-sending from queue), use the stored promise handlers\n const queuedMsg = message as Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void };\n if (queuedMsg._queuedResolve && queuedMsg._queuedReject) {\n return this.doSendMessage(message, queuedMsg._queuedResolve, queuedMsg._queuedReject);\n }\n\n if (!this.isConnected || !this.ws) {\n // Queue the message and return a promise that will be resolved when actually sent\n return new Promise<unknown>((resolve, reject) => {\n const queueable = message as Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void };\n queueable._queuedResolve = resolve;\n queueable._queuedReject = reject;\n this.messageQueue.push(message);\n });\n }\n\n return new Promise<unknown>((resolve, reject) => {\n this.doSendMessage(message, resolve, reject);\n });\n }\n\n private async doSendMessage(message: Record<string, unknown>, resolve: (value: unknown) => void, reject: (error: Error) => void): Promise<void> {\n // Ensure authenticated before sending non-auth messages\n if (message.type !== \"AUTHENTICATE\" && this.getAuthToken && !this.isAuthenticated) {\n try {\n await this.ensureAuthenticated();\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : \"Authentication required\";\n reject(new ApiError(errorMessage, errorMessage));\n return;\n }\n }\n\n const requestId = (message.requestId as string) || `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n message.requestId = requestId;\n\n const expectsResponse = ![\n \"subscribe_collection\",\n \"subscribe_entity\",\n \"unsubscribe\",\n \"join_channel\",\n \"leave_channel\",\n \"broadcast\",\n \"presence_track\",\n \"presence_untrack\",\n \"presence_state\"\n ].includes(message.type as string);\n\n if (expectsResponse && !this.pendingRequests.has(requestId)) {\n const timeoutHandle = setTimeout(() => {\n if (this.pendingRequests.has(requestId)) {\n this.pendingRequests.delete(requestId);\n reject(new ApiError(\"Request timed out\", \"Request timed out\"));\n }\n }, this.requestTimeoutMs);\n\n this.pendingRequests.set(requestId, {\n resolve: (value: unknown) => {\n clearTimeout(timeoutHandle);\n resolve(value);\n },\n reject: (error: Error) => {\n clearTimeout(timeoutHandle);\n reject(error);\n },\n message: message as Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void }\n });\n }\n\n try {\n this.ws!.send(JSON.stringify(message));\n if (!expectsResponse) {\n resolve(undefined);\n }\n } catch (error) {\n if (expectsResponse) {\n this.pendingRequests.delete(requestId);\n }\n reject(new ApiError(\"Failed to send message\", error instanceof Error ? error.message : \"Unknown error\"));\n }\n }\n\n // Data source methods\n async fetchCollection<M extends Record<string, unknown>>(props: FetchCollectionProps<M>): Promise<Entity<M>[]> {\n const response = await this.sendMessage({\n type: \"FETCH_COLLECTION\",\n payload: props\n }) as { entities?: Entity<M>[] };\n return response.entities || [];\n }\n\n async fetchEntity<M extends Record<string, unknown>>(props: FetchEntityProps<M>): Promise<Entity<M> | undefined> {\n const response = await this.sendMessage({\n type: \"FETCH_ENTITY\",\n payload: props\n }) as { entity?: Entity<M> };\n return response.entity ?? undefined;\n }\n\n async saveEntity<M extends Record<string, unknown>>(props: SaveEntityProps<M>): Promise<Entity<M>> {\n const response = await this.sendMessage({\n type: \"SAVE_ENTITY\",\n payload: props\n }) as { entity: Entity<M> };\n return response.entity;\n }\n\n async deleteEntity<M extends Record<string, unknown>>(props: DeleteEntityProps<M>): Promise<void> {\n await this.sendMessage({\n type: \"DELETE_ENTITY\",\n payload: props\n });\n }\n\n async executeSql(sql: string, options?: { database?: string, role?: string }): Promise<Record<string, unknown>[]> {\n const response = await this.sendMessage({\n type: \"EXECUTE_SQL\",\n payload: { sql,\noptions }\n }) as { result?: Record<string, unknown>[] };\n return response.result || [];\n }\n\n async fetchAvailableDatabases(): Promise<string[]> {\n const response = await this.sendMessage({\n type: \"FETCH_DATABASES\",\n payload: {}\n }) as { databases?: string[] };\n return response.databases || [];\n }\n\n async fetchAvailableRoles(): Promise<string[]> {\n const response = await this.sendMessage({\n type: \"FETCH_ROLES\"\n }) as { roles?: string[] };\n return response.roles || [];\n }\n\n async fetchCurrentDatabase(): Promise<string | undefined> {\n const response = await this.sendMessage({\n type: \"FETCH_CURRENT_DATABASE\"\n }) as { database?: string };\n return response.database;\n }\n\n async checkUniqueField(path: string, name: string, value: unknown, entityId?: string, collection?: EntityCollection): Promise<boolean> {\n const response = await this.sendMessage({\n type: \"CHECK_UNIQUE_FIELD\",\n payload: {\n path,\n name,\n value,\n entityId,\n collection\n }\n }) as { isUnique: boolean };\n return response.isUnique;\n }\n\n async countEntities<M extends Record<string, unknown>>(props: FetchCollectionProps<M>): Promise<number> {\n const response = await this.sendMessage({\n type: \"COUNT_ENTITIES\",\n payload: props\n }) as { count: number };\n return response.count;\n }\n\n async fetchUnmappedTables(mappedPaths?: string[]): Promise<string[]> {\n const response = await this.sendMessage({\n type: \"FETCH_UNMAPPED_TABLES\",\n payload: { mappedPaths }\n }) as { tables?: string[] };\n return response.tables || [];\n }\n\n async fetchTableMetadata(tableName: string): Promise<TableMetadata> {\n const response = await this.sendMessage({\n type: \"FETCH_TABLE_METADATA\",\n payload: { tableName }\n }) as { metadata?: TableMetadata };\n\n return response.metadata || ({ columns: [],\nforeignKeys: [],\njunctions: [],\npolicies: [] } as TableMetadata);\n }\n\n async createBranch(name: string, options?: { source?: string }): Promise<BranchInfo> {\n const response = await this.sendMessage({\n type: \"CREATE_BRANCH\",\n payload: { name,\noptions }\n }) as { branch: BranchInfo };\n return response.branch;\n }\n\n async deleteBranch(name: string): Promise<void> {\n await this.sendMessage({\n type: \"DELETE_BRANCH\",\n payload: { name }\n });\n }\n\n async listBranches(): Promise<BranchInfo[]> {\n const response = await this.sendMessage({\n type: \"LIST_BRANCHES\",\n payload: {}\n }) as { branches?: BranchInfo[] };\n return response.branches || [];\n }\n\n /**\n * Recursively compare two values for structural equality.\n * Handles primitives, null, undefined, Date, RegExp, arrays, and plain objects.\n */\n private deepEqual(a: unknown, b: unknown): boolean {\n // Same reference or same primitive\n if (a === b) return true;\n\n // Handle null/undefined\n if (a === null || b === null || a === undefined || b === undefined) return false;\n\n // Different types\n if (typeof a !== typeof b) return false;\n\n // Non-object primitives (number, string, boolean, bigint, symbol)\n // that weren't caught by === above (e.g. NaN !== NaN)\n if (typeof a !== \"object\") return false;\n\n // Date comparison\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n if (a instanceof Date || b instanceof Date) return false;\n\n // RegExp comparison\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.source === b.source && a.flags === b.flags;\n }\n if (a instanceof RegExp || b instanceof RegExp) return false;\n\n // Array comparison\n const aIsArray = Array.isArray(a);\n const bIsArray = Array.isArray(b);\n if (aIsArray !== bIsArray) return false;\n\n if (aIsArray && bIsArray) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!this.deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Plain object comparison\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n\n if (aKeys.length !== bKeys.length) return false;\n\n for (const key of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;\n if (!this.deepEqual(aObj[key], bObj[key])) return false;\n }\n\n return true;\n }\n\n private normalizeForComparison(val: unknown): unknown {\n if (!val) return val;\n\n if (Array.isArray(val)) {\n return val.map(item => this.normalizeForComparison(item));\n }\n\n if (typeof val === \"object\") {\n if (val instanceof Date) return val;\n if (val instanceof RegExp) return val;\n\n const obj = val as Record<string, unknown>;\n if (obj.__type === \"relation\") {\n const { data, ...rest } = obj;\n return rest;\n }\n\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n result[k] = this.normalizeForComparison(v);\n }\n return result;\n }\n\n return val;\n }\n\n /**\n * Merge incoming entities with cached data, preserving cached references\n * for entities whose values haven't changed. This avoids unnecessary\n * React re-renders when the server refetches all entities but most\n * haven't actually changed.\n */\n private mergeEntities(cached: Entity[] | undefined, incoming: Entity[]): Entity[] {\n if (!cached || cached.length === 0) return incoming;\n\n // Build a lookup from cached entities by ID for O(1) access\n const cachedById = new Map<string | number, Entity>();\n for (const entity of cached) {\n cachedById.set(entity.id, entity);\n }\n\n return incoming.map(incomingEntity => {\n const cachedEntity = cachedById.get(incomingEntity.id);\n if (!cachedEntity) return incomingEntity;\n\n if (cachedEntity.path === incomingEntity.path) {\n const normCached = this.normalizeForComparison(cachedEntity.values) as Record<string, unknown>;\n const normIncoming = this.normalizeForComparison(incomingEntity.values) as Record<string, unknown>;\n\n if (this.deepEqual(normCached, normIncoming)) {\n return cachedEntity;\n } else {\n // Deep debug: Why did it fail? Let's check which exact property differs\n // so the user can see it in their browser console if flashing still occurs.\n const mismatches: Record<string, { cached: unknown, incoming: unknown }> = {};\n const allKeys = new Set([...Object.keys(normCached), ...Object.keys(normIncoming)]);\n for (const key of allKeys) {\n if (!this.deepEqual(normCached[key], normIncoming[key])) {\n mismatches[key] = { cached: normCached[key],\nincoming: normIncoming[key] };\n }\n }\n console.debug(`[RebaseWS] Row ${incomingEntity.id} refetch mismatch:\\n`, JSON.stringify(mismatches, null, 2));\n }\n }\n return incomingEntity;\n });\n }\n\n // Subscription methods\n listenCollection<M extends Record<string, unknown>>(\n props: FetchCollectionProps<M>,\n onUpdate: (entities: Entity[]) => void,\n onError?: (error: Error) => void\n ): () => void {\n const subscriptionKey = this.createCollectionSubscriptionKey(props);\n const callbackId = `callback_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n // Check if we already have a subscription for these exact parameters\n const existingSubscription = this.collectionSubscriptions.get(subscriptionKey);\n\n if (existingSubscription) {\n // Reuse existing subscription - just add the new callback\n const callbackMap = existingSubscription.callbacks as Map<string, {\n onUpdate: (entities: Entity[]) => void;\n onError?: (error: Error) => void;\n }>;\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n // Immediately fire the callback with cached data if available\n if (existingSubscription.latestData !== undefined && existingSubscription.isInitialDataReceived) {\n try {\n onUpdate(existingSubscription.latestData);\n } catch (error) {\n console.error(\"Error in collection subscription callback:\", error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n }\n\n // Return unsubscribe function\n return () => {\n callbackMap.delete(callbackId);\n if (callbackMap.size === 0) {\n // No more callbacks, unsubscribe from backend\n this.collectionSubscriptions.delete(subscriptionKey);\n this.backendToCollectionKey.delete(existingSubscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: existingSubscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n };\n }\n\n // Create new subscription\n const backendSubscriptionId = `collection_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const callbackMap = new Map<string, {\n onUpdate: (entities: Entity[]) => void;\n onError?: (error: Error) => void;\n }>();\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n this.collectionSubscriptions.set(subscriptionKey, {\n backendSubscriptionId,\n callbacks: callbackMap,\n props\n });\n\n // Add reverse lookup\n this.backendToCollectionKey.set(backendSubscriptionId, subscriptionKey);\n\n // Send subscription request to backend\n this.sendMessage({\n type: \"subscribe_collection\",\n payload: {\n ...props,\n subscriptionId: backendSubscriptionId\n }\n }).catch(error => {\n if (onError) onError(error);\n });\n\n // Return unsubscribe function\n return () => {\n const subscription = this.collectionSubscriptions.get(subscriptionKey);\n if (subscription) {\n const callbacks = subscription.callbacks;\n callbacks.delete(callbackId);\n if (callbacks.size === 0) {\n this.collectionSubscriptions.delete(subscriptionKey);\n this.backendToCollectionKey.delete(subscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: subscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n }\n };\n }\n\n listenEntity<M extends Record<string, unknown>>(\n props: FetchEntityProps<M>,\n onUpdate: (entity: Entity | null) => void,\n onError?: (error: Error) => void\n ): () => void {\n const subscriptionKey = this.createEntitySubscriptionKey(props);\n const callbackId = `callback_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n // Check if we already have a subscription for these exact parameters\n const existingSubscription = this.entitySubscriptions.get(subscriptionKey);\n\n if (existingSubscription) {\n // Reuse existing subscription - just add the new callback\n const callbackMap = existingSubscription.callbacks as Map<string, {\n onUpdate: (entity: Entity | null) => void;\n onError?: (error: Error) => void;\n }>;\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n // Immediately fire the callback with cached data if available\n if (existingSubscription.latestData !== undefined && existingSubscription.isInitialDataReceived) {\n try {\n onUpdate(existingSubscription.latestData);\n } catch (error) {\n console.error(\"Error in entity subscription callback:\", error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n }\n\n // Return unsubscribe function\n return () => {\n callbackMap.delete(callbackId);\n if (callbackMap.size === 0) {\n // No more callbacks, unsubscribe from backend\n this.entitySubscriptions.delete(subscriptionKey);\n this.backendToEntityKey.delete(existingSubscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: existingSubscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n };\n }\n\n // Create new subscription\n const backendSubscriptionId = `entity_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const callbackMap = new Map<string, {\n onUpdate: (entity: Entity | null) => void;\n onError?: (error: Error) => void;\n }>();\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n this.entitySubscriptions.set(subscriptionKey, {\n backendSubscriptionId,\n callbacks: callbackMap,\n props\n });\n\n // Add reverse lookup\n this.backendToEntityKey.set(backendSubscriptionId, subscriptionKey);\n\n // Send subscription request to backend\n this.sendMessage({\n type: \"subscribe_entity\",\n payload: {\n ...props,\n subscriptionId: backendSubscriptionId\n }\n }).catch(error => {\n if (onError) onError(error);\n });\n\n // Return unsubscribe function\n return () => {\n const subscription = this.entitySubscriptions.get(subscriptionKey);\n if (subscription) {\n const callbacks = subscription.callbacks;\n callbacks.delete(callbackId);\n if (callbacks.size === 0) {\n this.entitySubscriptions.delete(subscriptionKey);\n this.backendToEntityKey.delete(subscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: subscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n }\n };\n }\n\n /**\n * Re-send all active subscriptions to the backend after a reconnect.\n * The server wipes subscription state when a client disconnects, so\n * we need to re-register everything to resume receiving updates.\n */\n private resubscribeAll(): void {\n console.debug(`[WS] Re-subscribing: ${this.collectionSubscriptions.size} collection(s), ${this.entitySubscriptions.size} entity(ies)`);\n\n // Re-subscribe collection subscriptions\n for (const [key, sub] of this.collectionSubscriptions.entries()) {\n // Generate a fresh backend ID since the old one is no longer valid on the server\n const oldBackendId = sub.backendSubscriptionId;\n const newBackendId = `collection_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n sub.backendSubscriptionId = newBackendId;\n\n // Update reverse lookup\n this.backendToCollectionKey.delete(oldBackendId);\n this.backendToCollectionKey.set(newBackendId, key);\n\n this.sendMessage({\n type: \"subscribe_collection\",\n payload: {\n ...sub.props,\n subscriptionId: newBackendId\n }\n }).catch(error => {\n console.error(\"[WS] Failed to re-subscribe collection:\", key, error);\n });\n }\n\n // Re-subscribe entity subscriptions\n for (const [key, sub] of this.entitySubscriptions.entries()) {\n const oldBackendId = sub.backendSubscriptionId;\n const newBackendId = `entity_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n sub.backendSubscriptionId = newBackendId;\n\n this.backendToEntityKey.delete(oldBackendId);\n this.backendToEntityKey.set(newBackendId, key);\n\n this.sendMessage({\n type: \"subscribe_entity\",\n payload: {\n ...sub.props,\n subscriptionId: newBackendId\n }\n }).catch(error => {\n console.error(\"[WS] Failed to re-subscribe entity:\", key, error);\n });\n }\n }\n\n private createCollectionSubscriptionKey(props: FetchCollectionProps): string {\n // Create a deterministic key based on subscription parameters\n const key = {\n path: props.path,\n filter: props.filter,\n limit: props.limit,\n startAfter: props.startAfter,\n orderBy: props.orderBy,\n order: props.order,\n searchString: props.searchString,\n collection: props.collection?.name\n };\n // Use replacer function (not array) to sort keys at all levels for deterministic output\n return JSON.stringify(key, (_, value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value).sort().reduce((sorted: Record<string, unknown>, k) => {\n sorted[k] = value[k];\n return sorted;\n }, {});\n }\n return value;\n });\n }\n\n private createEntitySubscriptionKey(props: FetchEntityProps): string {\n return `${props.path}|${props.entityId}`;\n }\n}\n","import { createTransport, RebaseClientConfig } from \"./transport\";\nimport { createAuth, CreateAuthOptions } from \"./auth\";\nimport { createAdmin, CreateAdminOptions } from \"./admin\";\nimport { createCron, CreateCronOptions } from \"./cron\";\nimport { createApiKeys, CreateApiKeysOptions } from \"./api-keys\";\nimport { createCollectionClient, CollectionClient } from \"./collection\";\nimport { createFunctionsClient } from \"./functions\";\nimport { createStorage } from \"./storage\";\nimport { RebaseWebSocketClient } from \"./websocket\";\nimport { RebaseClient, RebaseData, StorageSource } from \"@rebasepro/types\";\nimport { toSnakeCase } from \"@rebasepro/utils\";\n\nexport * from \"./transport\";\nexport * from \"./auth\";\nexport * from \"./admin\";\nexport * from \"./cron\";\nexport * from \"./api-keys\";\nexport * from \"./collection\";\nexport * from \"./query_builder\";\nexport * from \"./websocket\";\nexport * from \"./storage\";\nexport * from \"./reviver\";\nexport * from \"./functions\";\nexport type { Entity, FindResponse } from \"@rebasepro/types\";\n\nexport interface CreateRebaseClientOptions extends RebaseClientConfig {\n auth?: CreateAuthOptions;\n admin?: CreateAdminOptions;\n cron?: CreateCronOptions;\n apiKeys?: CreateApiKeysOptions;\n}\n\n// ─── Typed Data Proxy ────────────────────────────────────────────────────────\n// Adds typed collection accessors when `DB` is provided via the SDK generator.\n\ntype KebabToCamelCase<S extends string> =\n S extends `${infer T}-${infer U}`\n ? `${T}${Capitalize<KebabToCamelCase<U>>}`\n : S;\n\ntype TypedDataLayer<DB> = {\n collection<S extends string>(slug: S): CollectionClient<\n KebabToCamelCase<S> extends keyof DB\n ? (DB[KebabToCamelCase<S>] extends { Row: infer R extends Record<string, unknown> } ? R : Record<string, unknown>)\n : Record<string, unknown>\n >;\n} & {\n [K in keyof DB]: CollectionClient<\n DB[K] extends { Row: infer R extends Record<string, unknown> } ? R : Record<string, unknown>\n >;\n} & RebaseData;\n\n/**\n * The return type of `createRebaseClient<DB>()`.\n *\n * This is `RebaseClient` (from `@rebasepro/types`) with all optional\n * capabilities populated and the `data` layer narrowed to provide\n * typed collection accessors when a `DB` schema generic is supplied.\n */\nexport type CreateRebaseClientResult<DB = Record<string, unknown>> = Omit<RebaseClient, \"data\"> & {\n setToken: (token: string | null) => void;\n setAuthTokenGetter: (getter: () => Promise<string | null>) => void;\n setOnUnauthorized: (handler: () => Promise<boolean>) => void;\n resolveToken: () => Promise<string | null>;\n auth: ReturnType<typeof createAuth>;\n admin: ReturnType<typeof createAdmin>;\n cron: ReturnType<typeof createCron>;\n apiKeys: ReturnType<typeof createApiKeys>;\n functions: ReturnType<typeof createFunctionsClient>;\n ws?: RebaseWebSocketClient;\n storage: StorageSource;\n call: <T = unknown>(endpoint: string, payload?: unknown) => Promise<T>;\n data: TypedDataLayer<DB>;\n};\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\n/**\n * Derive a WebSocket URL from an HTTP base URL.\n * `http://` → `ws://`, `https://` → `wss://`.\n */\nfunction deriveWebSocketUrl(baseUrl?: string): string {\n if (typeof window !== \"undefined\") {\n let absoluteUrl = \"\";\n if (!baseUrl) {\n absoluteUrl = window.location.origin;\n } else if (/^https?:\\/\\//i.test(baseUrl) || /^wss?:\\/\\//i.test(baseUrl)) {\n absoluteUrl = baseUrl;\n } else {\n try {\n absoluteUrl = new URL(baseUrl, window.location.href).origin;\n } catch {\n absoluteUrl = window.location.origin;\n }\n }\n const protocol = absoluteUrl.startsWith(\"https:\") || absoluteUrl.startsWith(\"wss:\") ? \"wss:\" : \"ws:\";\n return absoluteUrl\n .replace(/^https?:\\/\\//i, `${protocol}//`)\n .replace(/^wss?:\\/\\//i, `${protocol}//`)\n .replace(/\\/$/, \"\");\n }\n\n if (!baseUrl) return \"\";\n if (!/^https?:\\/\\//i.test(baseUrl) && !/^wss?:\\/\\//i.test(baseUrl)) {\n return \"\";\n }\n return baseUrl\n .replace(/^https?:\\/\\//i, (match) => match.toLowerCase() === \"https://\" ? \"wss://\" : \"ws://\")\n .replace(/\\/$/, \"\");\n}\n\nexport function createRebaseClient<DB = Record<string, unknown>>(options: CreateRebaseClientOptions): CreateRebaseClientResult<DB> {\n const transport = createTransport(options);\n const auth = createAuth(transport, options.auth);\n const admin = createAdmin(transport, options.admin);\n const cron = createCron(transport, options.cron);\n const apiKeys = createApiKeys(transport, options.apiKeys);\n const storage = createStorage(transport);\n const functions = createFunctionsClient(transport);\n\n const resolvedWsUrl = options.websocketUrl ?? deriveWebSocketUrl(options.baseUrl);\n\n let ws: RebaseWebSocketClient | undefined;\n if (resolvedWsUrl) {\n const wsOnUnauthorized = options.onUnauthorized || (async () => {\n try {\n await auth.refreshSession();\n return true;\n } catch (e) {\n return false;\n }\n });\n\n ws = new RebaseWebSocketClient({\n websocketUrl: resolvedWsUrl,\n getAuthToken: async () => {\n let session = auth.getSession();\n if (session && session.expiresAt <= Date.now() + 10000) {\n try {\n session = await auth.refreshSession();\n } catch (e) { /* ignore */ }\n }\n return session?.accessToken || options.token || \"\";\n },\n onUnauthorized: wsOnUnauthorized\n });\n\n auth.onAuthStateChange((event, session) => {\n if (!ws) return;\n if (event === \"SIGNED_OUT\") {\n ws.disconnect();\n } else if (event === \"SIGNED_IN\" || event === \"TOKEN_REFRESHED\") {\n if (session?.accessToken) {\n ws.authenticate(session.accessToken).catch(console.warn);\n }\n }\n });\n }\n\n // Register transport callback for 401s after auth is instantiated.\n // IMPORTANT: We must use transport.setOnUnauthorized() here — NOT set\n // options.onUnauthorized — because the transport was already created above\n // and captured the (undefined) value from the config closure.\n if (!options.onUnauthorized) {\n transport.setOnUnauthorized(async () => {\n try {\n await auth.refreshSession();\n return true;\n } catch (e) {\n return false;\n }\n });\n }\n\n const collectionClients = new Map<string, CollectionClient<Record<string, unknown>>>();\n\n function collection(slug: string): CollectionClient<Record<string, unknown>> {\n if (!collectionClients.has(slug)) {\n collectionClients.set(slug, createCollectionClient(transport, slug, ws));\n }\n return collectionClients.get(slug)!;\n }\n\n const dataTarget = { collection } as Record<string, unknown>;\n\n const dataProxy = new Proxy(dataTarget, {\n get(_target, prop: string | symbol) {\n if (prop === \"collection\") {\n return collection;\n }\n if (typeof prop === \"symbol\") return undefined;\n if (typeof prop === \"string\" && prop !== \"then\" && prop !== \"toJSON\" && prop !== \"$$typeof\") {\n // Convert camelCase property names to snake_case slugs.\n // e.g. `companyMembers` → `company_members`\n const slug = toSnakeCase(prop);\n return collection(slug);\n }\n return undefined;\n }\n });\n\n const target = {\n auth,\n admin,\n cron,\n apiKeys,\n functions,\n storage,\n ws,\n setToken: transport.setToken,\n setAuthTokenGetter: transport.setAuthTokenGetter,\n setOnUnauthorized: transport.setOnUnauthorized,\n resolveToken: transport.resolveToken,\n baseUrl: transport.baseUrl,\n collection,\n call: async <T = unknown>(endpoint: string, payload?: unknown): Promise<T> => {\n const prefix = endpoint.startsWith(\"/\") ? \"\" : \"/\";\n const res = await transport.request<{ data: T }>(`${prefix}${endpoint}`, {\n method: \"POST\",\n body: payload ? JSON.stringify(payload) : undefined\n });\n return res.data ?? (res as T);\n },\n data: dataProxy,\n email: undefined\n } as unknown as CreateRebaseClientResult<DB>;\n\n return target;\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","names":[],"sources":["../src/reviver.ts","../src/transport.ts","../src/auth.ts","../src/admin.ts","../src/cron.ts","../src/api-keys.ts","../src/sdk_query_builder.ts","../src/collection.ts","../src/functions.ts","../src/storage.ts","../src/storage-registry.ts","../src/websocket.ts","../src/index.ts"],"sourcesContent":["import { EntityReference, EntityRelation, GeoPoint, Vector } from \"@rebasepro/types\";\n\nexport function rebaseReviver(_key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && \"__type\" in value) {\n const record = value as Record<string, unknown>;\n switch (record.__type) {\n case \"date\":\n case \"Date\": {\n if (typeof record.value !== \"string\") {\n return value;\n }\n const date = new Date(record.value);\n return isNaN(date.getTime()) ? null : date;\n }\n case \"reference\":\n case \"EntityReference\":\n return new EntityReference({\n id: String(record.id),\n path: record.path as string,\n driver: record.driver as string | undefined,\n databaseId: record.databaseId as string | undefined\n });\n case \"relation\":\n case \"EntityRelation\":\n return new EntityRelation(\n record.id as string | number,\n record.path as string,\n record.data as Record<string, unknown> | undefined\n );\n case \"GeoPoint\":\n return new GeoPoint(record.latitude as number, record.longitude as number);\n case \"Vector\":\n return new Vector(record.value as number[]);\n default:\n return value;\n }\n }\n return value;\n}\n","import { FindParams as TypesFindParams, FindResponse as TypesFindResponse, RebaseApiError } from \"@rebasepro/types\";\nimport { serializeFilter, serializeLogicalCondition, serializeOrderBy } from \"@rebasepro/common\";\nimport { rebaseReviver } from \"./reviver\";\n\n// The canonical client error now lives in `@rebasepro/types` so every package\n// (client, auth, …) throws one type. Re-exported here to preserve the historical\n// `import { RebaseApiError } from \".../transport\"` path used across the SDK.\nexport { RebaseApiError } from \"@rebasepro/types\";\nexport type { RebaseErrorInit } from \"@rebasepro/types\";\n\nexport interface RebaseClientConfig {\n baseUrl?: string;\n token?: string;\n apiPath?: string;\n fetch?: typeof globalThis.fetch;\n onUnauthorized?: () => Promise<boolean>;\n websocketUrl?: string; // Optional real-time WebSocket connection\n}\n\n/**\n * Re-export from `@rebasepro/types` for backward compatibility.\n */\nexport type FindParams = TypesFindParams;\nexport type FindResponse<T> = TypesFindResponse<T extends Record<string, unknown> ? T : Record<string, unknown>>;\n\nexport function buildQueryString(params?: FindParams): string {\n if (!params) return \"\";\n const parts: string[] = [];\n\n if (params.limit != null) parts.push(`limit=${params.limit}`);\n if (params.offset != null) parts.push(`offset=${params.offset}`);\n if (params.page != null) parts.push(`page=${params.page}`);\n\n if (params.orderBy) {\n const wire = serializeOrderBy(params.orderBy);\n if (wire) parts.push(`orderBy=${encodeURIComponent(wire)}`);\n }\n\n if (params.searchString) {\n parts.push(`searchString=${encodeURIComponent(params.searchString)}`);\n }\n\n if (params.include && params.include.length > 0) {\n parts.push(`include=${encodeURIComponent(params.include.join(\",\"))}`);\n }\n\n if (params.logical) {\n const root = params.logical;\n const serialized = (root.conditions ?? []).map(serializeLogicalCondition).join(\",\");\n parts.push(`${root.type}=${encodeURIComponent(`(${serialized})`)}`);\n }\n\n if (params.where) {\n const serialized = serializeFilter(params.where);\n for (const [field, value] of Object.entries(serialized)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n parts.push(`${encodeURIComponent(field)}=${encodeURIComponent(v)}`);\n }\n } else {\n parts.push(`${encodeURIComponent(field)}=${encodeURIComponent(value)}`);\n }\n }\n }\n\n return parts.length > 0 ? \"?\" + parts.join(\"&\") : \"\";\n}\n\nexport interface Transport {\n request: <T = unknown>(path: string, init?: RequestInit) => Promise<T>;\n setToken: (newToken: string | null) => void;\n setAuthTokenGetter: (getter: () => Promise<string | null>) => void;\n setOnUnauthorized: (handler: () => Promise<boolean>) => void;\n readonly baseUrl: string;\n readonly apiPath: string;\n readonly fetchFn: typeof globalThis.fetch;\n getHeaders: (init?: RequestInit) => Record<string, string>;\n resolveToken: () => Promise<string | null>;\n}\n\nexport function createTransport(config: RebaseClientConfig): Transport {\n const fetchFn = config.fetch || globalThis.fetch;\n const apiPath = config.apiPath || \"/api\";\n let token = config.token;\n let tokenGetter: (() => Promise<string | null>) | undefined;\n let onUnauthorizedHandler = config.onUnauthorized;\n\n function getHeaders(activeToken: string | undefined, init?: RequestInit) {\n return {\n \"Content-Type\": \"application/json\",\n ...(activeToken ? { Authorization: `Bearer ${activeToken}` } : {}),\n ...((init?.headers as Record<string, string>) || {})\n };\n }\n\n async function request<T = unknown>(path: string, init?: RequestInit): Promise<T> {\n const base = config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"\";\n const url = base + apiPath + path;\n\n let activeToken = token;\n if (tokenGetter) {\n try {\n const fetched = await tokenGetter();\n if (fetched !== null && fetched !== undefined) {\n activeToken = fetched;\n }\n } catch (e) {\n // Ignore error, fallback to static token if any\n }\n }\n\n const headers = getHeaders(activeToken, init);\n\n // If passing FormData, we MUST let fetch set the boundary, so remove Content-Type\n if (init?.body instanceof FormData) {\n delete (headers as Record<string, string>)[\"Content-Type\"];\n }\n\n const res = await fetchFn(url, { ...init,\nheaders });\n\n if (res.status === 204) return undefined as T; // SAFETY: HTTP 204 No Content has no body\n\n const text = await res.text().catch(() => \"\");\n let body: Record<string, unknown> = {};\n if (text) {\n try {\n body = JSON.parse(text, rebaseReviver) as Record<string, unknown>;\n } catch (e) {\n // If not valid JSON, fallback\n }\n }\n\n // The server always emits the canonical `{ error: { message, code, details? } }`\n // envelope (formatted by the central errorHandler), so we read strictly\n // from `body.error.*`.\n const getErrorField = (obj: Record<string, unknown>, field: string): unknown => {\n const err = obj?.error;\n if (err && typeof err === \"object\" && err !== null) {\n return (err as Record<string, unknown>)[field];\n }\n return undefined;\n };\n\n if (res.status === 401 && onUnauthorizedHandler) {\n const retried = await onUnauthorizedHandler();\n if (retried) {\n let retryToken = token;\n if (tokenGetter) {\n try {\n const fetched = await tokenGetter();\n if (fetched !== null && fetched !== undefined) {\n retryToken = fetched;\n }\n } catch (e) { /* ignore */ }\n }\n const retryHeaders = getHeaders(retryToken, init) as Record<string, string>;\n const retryRes = await fetchFn(url, { ...init,\nheaders: retryHeaders });\n if (retryRes.status === 204) return undefined as T; // SAFETY: HTTP 204 No Content has no body\n const retryText = await retryRes.text().catch(() => \"\");\n let retryBody: Record<string, unknown> = {};\n if (retryText) {\n try {\n retryBody = JSON.parse(retryText, rebaseReviver);\n } catch (e) { /* ignore */ }\n }\n if (!retryRes.ok) {\n let fallbackMessage = retryRes.statusText;\n if (retryRes.status === 404 && !fallbackMessage) {\n const method = init?.method || \"GET\";\n fallbackMessage = `Endpoint not found (${method} ${path}). This usually means the collection is not registered on the backend, or the frontend API URL configuration (e.g. VITE_API_URL) is missing or pointing to the wrong host.`;\n }\n throw new RebaseApiError(\n String(getErrorField(retryBody, \"message\") || fallbackMessage || `Request failed with status ${retryRes.status}`),\n {\n status: retryRes.status,\n code: getErrorField(retryBody, \"code\") as string | undefined,\n details: getErrorField(retryBody, \"details\")\n }\n );\n }\n return retryBody as T;\n }\n }\n\n if (!res.ok) {\n let fallbackMessage = res.statusText;\n if (res.status === 404 && !fallbackMessage) {\n const method = init?.method || \"GET\";\n fallbackMessage = `Endpoint not found (${method} ${path}). This usually means the collection is not registered on the backend, or the frontend API URL configuration (e.g. VITE_API_URL) is missing or pointing to the wrong host.`;\n }\n throw new RebaseApiError(\n String(getErrorField(body, \"message\") || fallbackMessage || `Request failed with status ${res.status}`),\n {\n status: res.status,\n code: getErrorField(body, \"code\") as string | undefined,\n details: getErrorField(body, \"details\")\n }\n );\n }\n\n return body as T;\n }\n\n return {\n request,\n setToken(newToken: string | null) { token = newToken || undefined; },\n setAuthTokenGetter(getter: () => Promise<string | null>) { tokenGetter = getter; },\n setOnUnauthorized(handler: () => Promise<boolean>) { onUnauthorizedHandler = handler; },\n get baseUrl() { return config.baseUrl ? config.baseUrl.replace(/\\/$/, \"\") : \"\"; },\n get apiPath() { return apiPath; },\n get fetchFn() { return fetchFn; },\n getHeaders: (init?: RequestInit) => getHeaders(token, init) as Record<string, string>,\n resolveToken: async () => {\n if (tokenGetter) {\n try {\n const fetched = await tokenGetter();\n if (fetched !== null && fetched !== undefined) {\n return fetched;\n }\n } catch (e) { /* ignore */ }\n }\n return token || null;\n }\n };\n}\n","import { RebaseApiError, Transport } from \"./transport\";\nimport type { AuthChangeEvent, RebaseSession, AuthTokens, DeviceSession, User } from \"@rebasepro/types\";\n\n// Re-export canonical types so `import { RebaseSession } from \"@rebasepro/client\"` keeps working\nexport type { RebaseSession, AuthTokens, AuthChangeEvent, DeviceSession } from \"@rebasepro/types\";\n\n/** @deprecated Use `User` from `@rebasepro/types` instead. */\nexport type RebaseUser = User;\n/** @deprecated Use `AuthTokens` from `@rebasepro/types` instead. */\nexport type RebaseTokens = AuthTokens;\n\n/** Minimal, non-sensitive user profile returned by {@link findUserByEmail}. */\nexport interface PublicUserProfile {\n uid: string;\n displayName: string | null;\n photoURL: string | null;\n}\n\n/** Map a raw user object from an auth response (`/login`, `/refresh`, `/me`) to a `User`. */\nfunction mapRawUser(raw: Record<string, unknown>): User {\n return {\n uid: raw.uid as string,\n email: (raw.email as string | null) ?? null,\n displayName: (raw.displayName as string | null) ?? null,\n photoURL: (raw.photoURL as string | null) ?? null,\n providerId: (raw.providerId as string | undefined) ?? \"password\",\n isAnonymous: (raw.isAnonymous as boolean | undefined) ?? false,\n emailVerified: raw.emailVerified as boolean | undefined,\n roles: raw.roles as string[] | undefined,\n metadata: raw.metadata as Record<string, unknown> | undefined,\n };\n}\n\n/** Placeholder user, used only as a last resort when none can be resolved. */\nconst EMPTY_USER: User = { uid: \"\", email: null, displayName: null, photoURL: null, providerId: \"password\", isAnonymous: false };\n\n\nexport interface AuthConfig {\n needsSetup: boolean;\n registrationEnabled: boolean;\n emailServiceEnabled?: boolean;\n passwordReset?: boolean;\n emailVerification?: boolean;\n magicLink?: boolean;\n enabledProviders: string[];\n}\n\nexport interface AuthStorage {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n removeItem: (key: string) => void;\n}\n\nexport function createMemoryStorage(): AuthStorage {\n const store: Record<string, string> = {};\n return {\n getItem(key) { return store[key] ?? null; },\n setItem(key, value) { store[key] = value; },\n removeItem(key) { delete store[key]; }\n };\n}\n\nfunction detectStorage(): AuthStorage {\n try {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(\"__rebase_test__\", \"1\");\n localStorage.removeItem(\"__rebase_test__\");\n return localStorage;\n }\n } catch (e) { /* ignore */ }\n return createMemoryStorage();\n}\n\nexport interface CreateAuthOptions {\n storage?: AuthStorage;\n authPath?: string;\n autoRefresh?: boolean;\n persistSession?: boolean;\n /**\n * Authentication flow mode.\n * - 'json' (default): Tokens are sent/received in JSON bodies. Refresh token is stored in local storage.\n * - 'cookie': Refresh token is sent/received via httpOnly cookies. Access token remains in memory.\n */\n authFlowMode?: \"json\" | \"cookie\";\n}\n\nexport function createAuth(transport: Transport, options?: CreateAuthOptions) {\n const opts = options || {};\n const storage = opts.storage || detectStorage();\n const authPath = opts.authPath || \"/auth\";\n const autoRefresh = opts.autoRefresh !== false;\n const persistSession = opts.persistSession !== false;\n const authFlowMode = opts.authFlowMode || \"json\";\n\n const STORAGE_KEY = \"rebase_auth\";\n const REFRESH_BUFFER_MS = 120000;\n // Auto-refresh resilience: retry transient failures with exponential backoff\n // (1s, 2s, 4s, … capped) before giving up and signing out.\n const MAX_REFRESH_RETRIES = 5;\n const REFRESH_RETRY_BASE_MS = 1000;\n const REFRESH_RETRY_MAX_MS = 30000;\n\n let currentSession: RebaseSession | null = null;\n const listeners = new Set<(event: AuthChangeEvent, session: RebaseSession | null) => void>();\n let refreshTimeout: ReturnType<typeof setTimeout> | null = null;\n // De-dupe concurrent refreshes. On boot (esp. cookie mode + React StrictMode)\n // multiple callers can trigger refresh at once; without this they race — the\n // server rotates the refresh token twice and the browser can end up with a\n // cookie the DB no longer matches. A single in-flight promise is shared.\n let inFlightRefresh: Promise<RebaseSession> | null = null;\n let resolveInitialized: (value: void | PromiseLike<void>) => void;\n const isInitialized = new Promise<void>((resolve) => {\n resolveInitialized = resolve;\n });\n\n function authUrl(endpoint: string) {\n return transport.baseUrl + transport.apiPath + authPath + endpoint;\n }\n\n function getFetch() {\n return transport.fetchFn || globalThis.fetch;\n }\n\n function throwApiError(status: number, body: { error?: { message?: string; code?: string; details?: unknown }; message?: string; code?: string; details?: unknown } | undefined, statusText: string): never {\n throw new RebaseApiError(\n body?.error?.message || body?.message || statusText,\n {\n status,\n code: body?.error?.code || body?.code,\n details: body?.error?.details || body?.details\n }\n );\n }\n\n function emit(event: AuthChangeEvent, session: RebaseSession | null) {\n for (const fn of listeners) {\n try { fn(event, session); } catch (e) { /* ignore */ }\n }\n }\n\n function saveSession(session: RebaseSession) {\n if (!persistSession || authFlowMode === \"cookie\") return;\n try {\n storage.setItem(STORAGE_KEY, JSON.stringify(session));\n } catch (e) { /* ignore */ }\n }\n\n function clearStoredSession() {\n try {\n storage.removeItem(STORAGE_KEY);\n } catch (e) { /* ignore */ }\n }\n\n function loadStoredSession(): RebaseSession | null {\n try {\n const raw = storage.getItem(STORAGE_KEY);\n if (raw) return JSON.parse(raw) as RebaseSession;\n } catch (e) { /* ignore */ }\n return null;\n }\n\n /**\n * A refresh failure is only fatal if the refresh token itself is rejected\n * (expired / invalid / forbidden). Network blips, timeouts, and 5xx (e.g. a\n * backend restart mid-session) are transient and must NOT log the user out.\n */\n function isFatalRefreshError(err: unknown): boolean {\n if (!(err instanceof RebaseApiError)) return false; // network/other → transient\n if (err.code === \"INVALID_TOKEN\" || err.code === \"TOKEN_EXPIRED\") return true;\n // 401/403 are auth failures; other statuses (incl. 5xx, 0) are transient.\n return err.status === 401 || err.status === 403;\n }\n\n async function attemptScheduledRefresh(attempt: number) {\n try {\n await refreshSession();\n // On success, refreshSession() re-schedules the next refresh itself.\n } catch (err) {\n if (isFatalRefreshError(err)) {\n signOut();\n return;\n }\n if (attempt >= MAX_REFRESH_RETRIES) {\n signOut();\n return;\n }\n // Transient failure — back off and retry rather than dropping the session.\n const backoff = Math.min(REFRESH_RETRY_BASE_MS * 2 ** attempt, REFRESH_RETRY_MAX_MS);\n refreshTimeout = setTimeout(() => { void attemptScheduledRefresh(attempt + 1); }, backoff);\n }\n }\n\n function scheduleRefresh(expiresAt: number) {\n if (refreshTimeout) clearTimeout(refreshTimeout);\n if (!autoRefresh) return;\n\n const delay = (expiresAt - REFRESH_BUFFER_MS) - Date.now();\n\n if (delay <= 0) {\n void attemptScheduledRefresh(0);\n return;\n }\n\n refreshTimeout = setTimeout(() => { void attemptScheduledRefresh(0); }, delay);\n }\n\n function handleAuthResponse(data: { tokens: AuthTokens, user: Record<string, unknown> }, event?: AuthChangeEvent): RebaseSession {\n const user: User = mapRawUser(data.user);\n const session: RebaseSession = {\n accessToken: data.tokens.accessToken,\n refreshToken: data.tokens.refreshToken || (currentSession?.refreshToken) || \"\",\n expiresAt: data.tokens.accessTokenExpiresAt,\n user\n };\n currentSession = session;\n saveSession(session);\n transport.setToken(session.accessToken);\n scheduleRefresh(session.expiresAt);\n emit(event || \"SIGNED_IN\", session);\n return session;\n }\n\n async function signInWithEmail(email: string, password: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/login\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email,\npassword }),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n async function signUp(email: string, password: string, displayName?: string) {\n const fetchFn = getFetch();\n const payload: Record<string, string> = { email,\npassword };\n if (displayName !== undefined) payload.displayName = displayName;\n const res = await fetchFn(authUrl(\"/register\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n /**\n * Sign in with Google.\n *\n * Supports three invocation styles:\n * - `signInWithGoogle({ idToken })` — ID-token flow (One Tap / Sign In button)\n * - `signInWithGoogle({ accessToken })` — Access-token flow (popup)\n * - `signInWithGoogle({ code, redirectUri })` — Authorization code flow (most secure)\n */\n async function signInWithGoogle(\n payload: { idToken: string } | { accessToken: string } | { code: string; redirectUri: string }\n ) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/google\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const responseBody = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, responseBody, res.statusText);\n const session = handleAuthResponse(responseBody, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n async function signInWithLinkedin(code: string, redirectUri: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/linkedin\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code,\nredirectUri }),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n /**\n * Generic OAuth sign-in. Posts the given payload to `/auth/{providerId}`.\n * Use this for any provider registered on the backend.\n */\n async function signInWithOAuth(providerId: string, payload: Record<string, unknown>) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(`/${providerId}`), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n // Convenience wrappers for all supported OAuth providers\n\n async function signInWithGitHub(code: string, redirectUri: string) {\n return signInWithOAuth(\"github\", { code,\nredirectUri });\n }\n\n async function signInWithMicrosoft(code: string, redirectUri: string) {\n return signInWithOAuth(\"microsoft\", { code,\nredirectUri });\n }\n\n async function signInWithApple(code: string, redirectUri: string, user?: { name?: { firstName?: string; lastName?: string }; email?: string }) {\n return signInWithOAuth(\"apple\", { code,\nredirectUri,\nuser });\n }\n\n async function signInWithFacebook(code: string, redirectUri: string) {\n return signInWithOAuth(\"facebook\", { code,\nredirectUri });\n }\n\n async function signInWithTwitter(code: string, redirectUri: string, codeVerifier: string) {\n return signInWithOAuth(\"twitter\", { code,\nredirectUri,\ncodeVerifier });\n }\n\n async function signInWithDiscord(code: string, redirectUri: string) {\n return signInWithOAuth(\"discord\", { code,\nredirectUri });\n }\n\n async function signInWithGitLab(code: string, redirectUri: string) {\n return signInWithOAuth(\"gitlab\", { code,\nredirectUri });\n }\n\n async function signInWithBitbucket(code: string, redirectUri: string) {\n return signInWithOAuth(\"bitbucket\", { code,\nredirectUri });\n }\n\n async function signInWithSlack(code: string, redirectUri: string) {\n return signInWithOAuth(\"slack\", { code,\nredirectUri });\n }\n\n async function signInWithSpotify(code: string, redirectUri: string) {\n return signInWithOAuth(\"spotify\", { code,\nredirectUri });\n }\n\n async function signOut() {\n const fetchFn = getFetch();\n try {\n if (authFlowMode === \"cookie\" || currentSession?.refreshToken) {\n await fetchFn(authUrl(\"/logout\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refreshToken: currentSession?.refreshToken }),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n }\n } catch (e) { /* ignore */ }\n currentSession = null;\n clearStoredSession();\n if (refreshTimeout) {\n clearTimeout(refreshTimeout);\n refreshTimeout = null;\n }\n transport.setToken(null);\n emit(\"SIGNED_OUT\", null);\n }\n\n function refreshSession(): Promise<RebaseSession> {\n // Share a single in-flight refresh across concurrent callers.\n if (inFlightRefresh) return inFlightRefresh;\n inFlightRefresh = doRefreshSession().finally(() => {\n inFlightRefresh = null;\n });\n return inFlightRefresh;\n }\n\n async function doRefreshSession(): Promise<RebaseSession> {\n if (authFlowMode !== \"cookie\" && !currentSession?.refreshToken) {\n throw new Error(\"No active session to refresh\");\n }\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/refresh\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refreshToken: currentSession?.refreshToken }),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n\n const accessToken = body.tokens.accessToken;\n transport.setToken(accessToken);\n\n // Resolve the user, in order of preference:\n // 1. the user returned by /refresh (modern backends include it),\n // 2. the user already in memory,\n // 3. a fetch of /me — required to restore a session from an httpOnly\n // cookie alone (cold start in cookie mode), where there is no\n // in-memory user and the backend didn't echo one.\n let user = currentSession?.user;\n if (body.user && typeof body.user.uid === \"string\") {\n user = mapRawUser(body.user as Record<string, unknown>);\n } else if (!user || !user.uid) {\n try {\n user = await getUser();\n } catch { /* fall through to the empty stub below */ }\n }\n\n const session: RebaseSession = {\n accessToken,\n refreshToken: body.tokens.refreshToken || currentSession?.refreshToken || \"\",\n expiresAt: body.tokens.accessTokenExpiresAt,\n user: user ?? EMPTY_USER\n };\n currentSession = session;\n saveSession(session);\n transport.setToken(session.accessToken);\n scheduleRefresh(session.expiresAt);\n emit(\"TOKEN_REFRESHED\", session);\n return session;\n }\n\n async function getUser() {\n const data = await transport.request<{ user: User }>(authPath + \"/me\", { method: \"GET\" });\n return data.user;\n }\n\n /**\n * Resolve an email to a minimal public profile (`uid`, `displayName`,\n * `photoURL`) for invite-by-email flows. Returns `null` when no account\n * matches. Requires the backend to opt in via `auth.allowUserLookup`;\n * otherwise the endpoint is absent and this rejects.\n */\n async function findUserByEmail(email: string): Promise<PublicUserProfile | null> {\n const data = await transport.request<{ user: PublicUserProfile | null }>(authPath + \"/find-user\", {\n method: \"POST\",\n body: JSON.stringify({ email })\n });\n return data.user;\n }\n\n async function updateUser(updates: { displayName?: string, photoURL?: string }) {\n const data = await transport.request<{ user: User }>(authPath + \"/me\", {\n method: \"PATCH\",\n body: JSON.stringify(updates)\n });\n if (currentSession) {\n currentSession = { ...currentSession,\nuser: data.user };\n saveSession(currentSession);\n emit(\"USER_UPDATED\", currentSession);\n }\n return data.user;\n }\n\n async function resetPasswordForEmail(email: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/forgot-password\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function resetPassword(token: string, password: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/reset-password\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ token,\npassword })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function changePassword(oldPassword: string, newPassword: string) {\n return transport.request<{ success: boolean; message: string; }>(authPath + \"/change-password\", {\n method: \"POST\",\n body: JSON.stringify({ oldPassword,\nnewPassword })\n });\n }\n\n async function sendVerificationEmail() {\n return transport.request<{ success: boolean; message: string; }>(authPath + \"/send-verification\", {\n method: \"POST\"\n });\n }\n\n async function verifyEmail(token: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/verify-email?token=\" + encodeURIComponent(token)), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" }\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function sendMagicLink(email: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/magic-link\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email })\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as { success: boolean; message: string; };\n }\n\n async function verifyMagicLink(token: string) {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/magic-link/verify\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ token }),\n credentials: authFlowMode === \"cookie\" ? \"include\" : undefined\n } as RequestInit);\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n const session = handleAuthResponse(body, \"SIGNED_IN\");\n return { user: session.user,\naccessToken: session.accessToken,\nrefreshToken: session.refreshToken };\n }\n\n async function getSessions(): Promise<DeviceSession[]> {\n const data = await transport.request<{ sessions: DeviceSession[] }>(authPath + \"/sessions\", { method: \"GET\" });\n return data.sessions;\n }\n\n async function revokeSession(sessionId: string) {\n return transport.request<{ success: boolean }>(authPath + \"/sessions/\" + encodeURIComponent(sessionId), {\n method: \"DELETE\"\n });\n }\n\n async function revokeAllSessions() {\n const result = await transport.request<{ success: boolean }>(authPath + \"/sessions\", {\n method: \"DELETE\"\n });\n currentSession = null;\n clearStoredSession();\n if (refreshTimeout) {\n clearTimeout(refreshTimeout);\n refreshTimeout = null;\n }\n transport.setToken(null);\n emit(\"SIGNED_OUT\", null);\n return result;\n }\n\n async function getAuthConfig() {\n const fetchFn = getFetch();\n const res = await fetchFn(authUrl(\"/config\"), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" }\n });\n const body = await res.json().catch(() => ({}));\n if (!res.ok) throwApiError(res.status, body, res.statusText);\n return body as AuthConfig;\n }\n\n function getSession() {\n return currentSession;\n }\n\n function onAuthStateChange(callback: (event: AuthChangeEvent, session: RebaseSession | null) => void) {\n listeners.add(callback);\n return () => listeners.delete(callback);\n }\n\n if (persistSession) {\n const stored = loadStoredSession();\n if (stored && stored.accessToken) {\n if (stored.expiresAt > Date.now()) {\n currentSession = stored;\n transport.setToken(stored.accessToken);\n scheduleRefresh(stored.expiresAt);\n resolveInitialized!();\n } else if (authFlowMode === \"cookie\" || stored.refreshToken) {\n currentSession = stored;\n refreshSession().then(() => {\n resolveInitialized!();\n }).catch(() => {\n currentSession = null;\n clearStoredSession();\n transport.setToken(null);\n resolveInitialized!();\n });\n } else {\n resolveInitialized!();\n }\n } else if (authFlowMode === \"cookie\") {\n // Silent refresh on boot to pick up httpOnly session\n refreshSession().then(() => {\n resolveInitialized!();\n }).catch(() => {\n resolveInitialized!();\n });\n } else {\n resolveInitialized!();\n }\n } else {\n resolveInitialized!();\n }\n\n return {\n signInWithEmail,\n signUp,\n signInWithGoogle,\n signInWithLinkedin,\n signInWithOAuth,\n signInWithGitHub,\n signInWithMicrosoft,\n signInWithApple,\n signInWithFacebook,\n signInWithTwitter,\n signInWithDiscord,\n signInWithGitLab,\n signInWithBitbucket,\n signInWithSlack,\n signInWithSpotify,\n signOut,\n refreshSession,\n getUser,\n findUserByEmail,\n updateUser,\n resetPasswordForEmail,\n resetPassword,\n changePassword,\n sendVerificationEmail,\n verifyEmail,\n sendMagicLink,\n verifyMagicLink,\n getSessions,\n revokeSession,\n revokeAllSessions,\n getAuthConfig,\n getSession,\n onAuthStateChange,\n isInitialized: () => isInitialized\n };\n}\n\nexport interface CookieStorageOptions {\n path?: string;\n domain?: string;\n secure?: boolean;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n maxAge?: number;\n}\n\nexport function createCookieStorage(options: CookieStorageOptions = {}): AuthStorage {\n const defaultOptions = {\n path: \"/\",\n sameSite: \"Lax\" as const,\n ...options\n };\n\n return {\n getItem(key: string): string | null {\n if (typeof document === \"undefined\") return null;\n const nameEQ = encodeURIComponent(key) + \"=\";\n const ca = document.cookie.split(\";\");\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === \" \") c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) {\n return decodeURIComponent(c.substring(nameEQ.length, c.length));\n }\n }\n return null;\n },\n setItem(key: string, value: string): void {\n if (typeof document === \"undefined\") return;\n let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;\n\n if (defaultOptions.path) {\n cookieStr += `; path=${defaultOptions.path}`;\n }\n if (defaultOptions.domain) {\n cookieStr += `; domain=${defaultOptions.domain}`;\n }\n if (defaultOptions.maxAge !== undefined) {\n cookieStr += `; max-age=${defaultOptions.maxAge}`;\n } else {\n cookieStr += `; max-age=${365 * 24 * 60 * 60}`;\n }\n if (defaultOptions.secure) {\n cookieStr += \"; secure\";\n }\n if (defaultOptions.sameSite) {\n cookieStr += `; samesite=${defaultOptions.sameSite}`;\n }\n\n document.cookie = cookieStr;\n },\n removeItem(key: string): void {\n if (typeof document === \"undefined\") return;\n let cookieStr = `${encodeURIComponent(key)}=; path=${defaultOptions.path || \"/\"}; max-age=-1`;\n if (defaultOptions.domain) {\n cookieStr += `; domain=${defaultOptions.domain}`;\n }\n document.cookie = cookieStr;\n }\n };\n}\n","import type { Transport } from \"./transport\";\nimport { AdminUser } from \"@rebasepro/types\";\n\nexport type { AdminUser };\n\n\nexport interface CreateAdminOptions {\n adminPath?: string;\n}\n\nexport function createAdmin(transport: Transport, options?: CreateAdminOptions) {\n const opts = options || {};\n const adminPath = opts.adminPath || \"/admin\";\n\n async function listUsers() {\n return transport.request<{ users: AdminUser[] }>(adminPath + \"/users\", { method: \"GET\" });\n }\n\n async function listUsersPaginated(options?: { search?: string; limit?: number; offset?: number; orderBy?: string; orderDir?: \"asc\" | \"desc\" }) {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n if (options?.search) params.set(\"search\", options.search);\n if (options?.orderBy) params.set(\"orderBy\", options.orderBy);\n if (options?.orderDir) params.set(\"orderDir\", options.orderDir);\n const qs = params.toString();\n return transport.request<{ users: AdminUser[]; total: number; limit: number; offset: number }>(\n adminPath + \"/users\" + (qs ? \"?\" + qs : \"\"), { method: \"GET\" }\n );\n }\n\n async function getUser(userId: string) {\n return transport.request<{ user: AdminUser }>(adminPath + \"/users/\" + encodeURIComponent(userId), { method: \"GET\" });\n }\n\n async function createUser(data: { email: string, displayName?: string, password?: string, roles?: string[] }) {\n return transport.request<{ user: AdminUser }>(adminPath + \"/users\", {\n method: \"POST\",\n body: JSON.stringify(data)\n });\n }\n\n async function updateUser(userId: string, data: { email?: string, displayName?: string, password?: string, roles?: string[] }) {\n return transport.request<{ user: AdminUser }>(adminPath + \"/users/\" + encodeURIComponent(userId), {\n method: \"PUT\",\n body: JSON.stringify(data)\n });\n }\n\n async function deleteUser(userId: string) {\n return transport.request<{ success: boolean }>(adminPath + \"/users/\" + encodeURIComponent(userId), {\n method: \"DELETE\"\n });\n }\n\n async function resetPassword(userId: string, options?: { password?: string }) {\n return transport.request<{ user: AdminUser; temporaryPassword?: string; invitationSent?: boolean }>(\n adminPath + \"/users/\" + encodeURIComponent(userId) + \"/reset-password\",\n {\n method: \"POST\",\n ...(options?.password ? { body: JSON.stringify({ password: options.password }) } : {})\n }\n );\n }\n\n async function listRoles() {\n return transport.request<{ roles: Array<{ id: string; name: string }> }>(\n adminPath + \"/roles\",\n { method: \"GET\" }\n );\n }\n\n async function bootstrap() {\n return transport.request<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>(adminPath + \"/bootstrap\", {\n method: \"POST\"\n });\n }\n\n return {\n listUsers,\n listUsersPaginated,\n getUser,\n createUser,\n updateUser,\n deleteUser,\n resetPassword,\n listRoles,\n bootstrap\n };\n}\n","import { Transport } from \"./transport\";\nimport type { CronJobStatus, CronJobLogEntry } from \"@rebasepro/types\";\n\nexport interface CreateCronOptions {\n cronPath?: string;\n}\n\nexport function createCron(transport: Transport, options?: CreateCronOptions) {\n const cronPath = options?.cronPath || \"/cron\";\n\n async function listJobs(): Promise<{ jobs: CronJobStatus[] }> {\n return transport.request<{ jobs: CronJobStatus[] }>(cronPath, { method: \"GET\" });\n }\n\n async function getJob(jobId: string): Promise<{ job: CronJobStatus }> {\n return transport.request<{ job: CronJobStatus }>(\n cronPath + \"/\" + encodeURIComponent(jobId),\n { method: \"GET\" }\n );\n }\n\n async function triggerJob(jobId: string): Promise<{ log: CronJobLogEntry; job: CronJobStatus }> {\n return transport.request<{ log: CronJobLogEntry; job: CronJobStatus }>(\n cronPath + \"/\" + encodeURIComponent(jobId) + \"/trigger\",\n { method: \"POST\" }\n );\n }\n\n async function getJobLogs(\n jobId: string,\n options?: { limit?: number }\n ): Promise<{ logs: CronJobLogEntry[] }> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return transport.request<{ logs: CronJobLogEntry[] }>(\n cronPath + \"/\" + encodeURIComponent(jobId) + \"/logs\" + (qs ? \"?\" + qs : \"\"),\n { method: \"GET\" }\n );\n }\n\n async function toggleJob(\n jobId: string,\n enabled: boolean\n ): Promise<{ job: CronJobStatus }> {\n return transport.request<{ job: CronJobStatus }>(\n cronPath + \"/\" + encodeURIComponent(jobId),\n {\n method: \"PUT\",\n body: JSON.stringify({ enabled })\n }\n );\n }\n\n return {\n listJobs,\n getJob,\n triggerJob,\n getJobLogs,\n toggleJob\n };\n}\n","import type { Transport } from \"./transport\";\n\n// Re-define the types locally since they live in server-core, not in @rebasepro/types.\n// These match the server-side types exactly.\n\n/** A single permission entry scoping an API key to a collection and its allowed operations. */\nexport interface ApiKeyPermission {\n collection: string;\n operations: (\"read\" | \"write\" | \"delete\")[];\n}\n\n/** An API key with the secret portion masked (returned by list / get / update). */\nexport interface ApiKeyMasked {\n id: string;\n name: string;\n key_prefix: string;\n permissions: ApiKeyPermission[];\n admin: boolean;\n rate_limit: number | null;\n created_by: string;\n created_at: string;\n updated_at: string;\n last_used_at: string | null;\n expires_at: string | null;\n revoked_at: string | null;\n}\n\n/** An API key including the full secret (returned only on creation). */\nexport interface ApiKeyWithSecret extends ApiKeyMasked {\n key: string;\n}\n\n/** Payload for creating a new API key. */\nexport interface CreateApiKeyRequest {\n name: string;\n permissions: ApiKeyPermission[];\n rate_limit?: number | null;\n expires_at?: string | null;\n}\n\n/** Payload for updating an existing API key. */\nexport interface UpdateApiKeyRequest {\n name?: string;\n permissions?: ApiKeyPermission[];\n rate_limit?: number | null;\n expires_at?: string | null;\n}\n\n/** Options for the `createApiKeys` factory. */\nexport interface CreateApiKeysOptions {\n apiKeysPath?: string;\n}\n\n/**\n * Creates a client for managing API keys via the admin routes.\n *\n * @param transport - The shared HTTP transport created by `createTransport`.\n * @param options - Optional overrides (e.g. a custom base path).\n */\nexport function createApiKeys(transport: Transport, options?: CreateApiKeysOptions) {\n const apiKeysPath = options?.apiKeysPath || \"/admin/api-keys\";\n\n /** List all API keys (masked). */\n async function listKeys(): Promise<{ keys: ApiKeyMasked[] }> {\n return transport.request<{ keys: ApiKeyMasked[] }>(apiKeysPath, { method: \"GET\" });\n }\n\n /** Get a single API key by ID (masked). */\n async function getKey(id: string): Promise<{ key: ApiKeyMasked }> {\n return transport.request<{ key: ApiKeyMasked }>(\n apiKeysPath + \"/\" + encodeURIComponent(id),\n { method: \"GET\" }\n );\n }\n\n /** Create a new API key. The full secret is included in the response. */\n async function createKey(data: CreateApiKeyRequest): Promise<{ key: ApiKeyWithSecret }> {\n return transport.request<{ key: ApiKeyWithSecret }>(apiKeysPath, {\n method: \"POST\",\n body: JSON.stringify(data)\n });\n }\n\n /** Update an existing API key. */\n async function updateKey(id: string, data: UpdateApiKeyRequest): Promise<{ key: ApiKeyMasked }> {\n return transport.request<{ key: ApiKeyMasked }>(\n apiKeysPath + \"/\" + encodeURIComponent(id),\n {\n method: \"PUT\",\n body: JSON.stringify(data)\n }\n );\n }\n\n /** Revoke (soft-delete) an API key. */\n async function revokeKey(id: string): Promise<{ success: boolean }> {\n return transport.request<{ success: boolean }>(\n apiKeysPath + \"/\" + encodeURIComponent(id),\n { method: \"DELETE\" }\n );\n }\n\n return {\n listKeys,\n getKey,\n createKey,\n updateKey,\n revokeKey\n };\n}\n","import {\n FindParams,\n FindResult,\n LogicalCondition,\n SDKCollectionClient,\n SDKQueryBuilderInterface,\n WhereFilterOp,\n WhereValue\n} from \"@rebasepro/types\";\n\n/**\n * SDK Query Builder — returns flat rows (`FindResult<M>`) instead of\n * Entity-wrapped results (`FindResponse<M>`).\n *\n * @example\n * const { data } = await rebase.data.posts\n * .where(\"status\", \"==\", \"published\")\n * .orderBy(\"created_at\", \"desc\")\n * .limit(10)\n * .find();\n *\n * console.log(data[0].title); // flat access\n */\nexport class SDKQueryBuilder<M extends Record<string, unknown> = Record<string, unknown>> implements SDKQueryBuilderInterface<M> {\n private params: FindParams = { where: {} };\n\n constructor(private collection: SDKCollectionClient<M>) {}\n\n /**\n * Add a filter condition to your query.\n * @example\n * client.data.users.where('age', '>=', 18).find()\n */\n where<K extends keyof M & string>(column: K, operator: WhereFilterOp, value: WhereValue<M[K]>): this;\n where(logicalCondition: LogicalCondition): this;\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown): this {\n if (typeof columnOrCondition === \"object\" && columnOrCondition !== null && \"type\" in columnOrCondition) {\n this.params.logical = columnOrCondition as LogicalCondition;\n return this;\n }\n\n if (!this.params.where) {\n this.params.where = {};\n }\n\n const column = columnOrCondition as string;\n const condition: [WhereFilterOp, unknown] = [operator!, value];\n const existing = this.params.where[column];\n\n if (existing === undefined) {\n this.params.where[column] = condition;\n } else if (Array.isArray(existing) && existing.length > 0 && Array.isArray(existing[0])) {\n (this.params.where[column] as [WhereFilterOp, unknown][]).push(condition);\n } else {\n let firstCondition: [WhereFilterOp, unknown];\n if (Array.isArray(existing) && existing.length === 2 && typeof existing[0] === \"string\") {\n firstCondition = existing as [WhereFilterOp, unknown];\n } else {\n firstCondition = [\"==\", existing];\n }\n this.params.where[column] = [firstCondition, condition];\n }\n\n return this;\n }\n\n /**\n * Order the results by a specific column.\n */\n orderBy(column: keyof M & string, direction: \"asc\" | \"desc\" = \"asc\"): this {\n this.params.orderBy = [column, direction];\n return this;\n }\n\n /**\n * Limit the number of results returned.\n */\n limit(count: number): this {\n this.params.limit = count;\n return this;\n }\n\n /**\n * Skip the first N results.\n */\n offset(count: number): this {\n this.params.offset = count;\n return this;\n }\n\n /**\n * Set a free-text search string if supported by the backend.\n */\n search(searchString: string): this {\n this.params.searchString = searchString;\n return this;\n }\n\n /**\n * Include related entities in the response.\n * Relations will be populated with full data instead of just IDs.\n *\n * @param relations - Relation names to include, or \"*\" for all.\n * @example\n * client.data.posts.include(\"tags\", \"author\").find()\n */\n include(...relations: string[]): this {\n this.params.include = relations;\n return this;\n }\n\n /**\n * Execute the find query and return the results as flat rows.\n */\n async find(): Promise<FindResult<M>> {\n return this.collection.find(this.params);\n }\n\n /**\n * Count the records matching this query.\n */\n async count(): Promise<number> {\n if (!this.collection.count) {\n throw new Error(\"count() is not supported by this collection client.\");\n }\n return this.collection.count(this.params);\n }\n\n /**\n * Listen to realtime updates matching this query.\n */\n listen(onUpdate: (data: FindResult<M>) => void, onError?: (error: Error) => void): () => void {\n if (!this.collection.listen) {\n throw new Error(\"Listen is only available when RebaseClient is configured with a websocketUrl.\");\n }\n return this.collection.listen(this.params, onUpdate, onError);\n }\n}\n","import { buildQueryString, FindParams, RebaseApiError, Transport } from \"./transport\";\nimport { RebaseWebSocketClient } from \"./websocket\";\nimport {\n FindResult,\n LogicalCondition,\n SDKCollectionClient,\n SDKQueryBuilderInterface,\n WhereFilterOp,\n WhereValue\n} from \"@rebasepro/types\";\n\nimport { SDKQueryBuilder } from \"./sdk_query_builder\";\n\n/**\n * The concrete, HTTP-backed implementation of the public\n * {@link SDKCollectionClient} contract — flat rows (no Entity wrapper), plus\n * fluent query-builder methods (`.where()`, `.orderBy()`, …).\n *\n * This is what `createRebaseClient().data.<collection>` returns. It is not a\n * separate API from {@link SDKCollectionClient}; it only widens it with\n * `count()`. Program against {@link SDKCollectionClient} when you want a\n * transport-agnostic type.\n */\nexport interface CollectionClient<\n M extends Record<string, unknown> = Record<string, unknown>,\n I = Partial<M>,\n U = Partial<M>\n> extends SDKCollectionClient<M, I, U> {\n count(params?: FindParams): Promise<number>;\n}\n\nexport function createCollectionClient<M extends Record<string, unknown> = Record<string, unknown>>(transport: Transport, slug: string, ws?: RebaseWebSocketClient): CollectionClient<M> {\n const basePath = `/data/${slug}`;\n\n const client: CollectionClient<M> = {\n async find(params?: FindParams): Promise<FindResult<M>> {\n const qs = buildQueryString(params);\n const raw = await transport.request<{\n data: Record<string, unknown>[];\n meta: FindResult<M>[\"meta\"]\n }>(basePath + qs, { method: \"GET\" });\n return {\n data: (raw.data || []) as M[],\n meta: raw.meta\n };\n },\n\n async findById(id: string | number) {\n try {\n const raw = await transport.request<Record<string, unknown>>(`${basePath}/${encodeURIComponent(String(id))}`, { method: \"GET\" });\n if (!raw) return undefined;\n return raw as M;\n } catch (err) {\n if (err instanceof RebaseApiError && err.status === 404) {\n return undefined;\n }\n throw err;\n }\n },\n\n async create(data: Partial<M>, id?: string | number) {\n const body: Record<string, unknown> = { ...data };\n if (id !== undefined) {\n body.id = id;\n }\n const raw = await transport.request<Record<string, unknown>>(basePath, {\n method: \"POST\",\n body: JSON.stringify(body)\n });\n return raw as M;\n },\n\n async update(id: string | number, data: Partial<M>) {\n const raw = await transport.request<Record<string, unknown>>(`${basePath}/${encodeURIComponent(String(id))}`, {\n method: \"PUT\",\n body: JSON.stringify(data)\n });\n return raw as M;\n },\n\n async delete(id: string | number) {\n await transport.request<void>(`${basePath}/${encodeURIComponent(String(id))}`, {\n method: \"DELETE\"\n });\n },\n\n async count(params?: FindParams): Promise<number> {\n const countParams: FindParams = {\n ...params,\n limit: undefined,\n offset: undefined\n };\n const qs = buildQueryString(countParams);\n const raw = await transport.request<{ count: number }>(basePath + \"/count\" + qs, { method: \"GET\" });\n return raw.count ?? 0;\n },\n\n // Fluent builder instantiation\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown) {\n const builder = new SDKQueryBuilder<M>(client);\n if (typeof columnOrCondition === \"object\") {\n return builder.where(columnOrCondition);\n }\n return builder.where(columnOrCondition as keyof M & string, operator!, value as WhereValue<M[keyof M & string]>);\n },\n orderBy(column: keyof M & string, direction?: \"asc\" | \"desc\") {\n return new SDKQueryBuilder<M>(client).orderBy(column, direction);\n },\n limit(count: number) {\n return new SDKQueryBuilder<M>(client).limit(count);\n },\n offset(count: number) {\n return new SDKQueryBuilder<M>(client).offset(count);\n },\n search(searchString: string) {\n return new SDKQueryBuilder<M>(client).search(searchString);\n },\n include(...relations: string[]) {\n return new SDKQueryBuilder<M>(client).include(...relations);\n }\n };\n\n if (ws) {\n client.listen = (params: FindParams | undefined, onUpdate: (response: FindResult<M>) => void, onError?: (error: Error) => void) => {\n let active = true;\n let lastUpdateId = 0;\n const unsub = ws.listenCollection(\n {\n path: slug,\n filter: params?.where,\n limit: params?.limit,\n startAfter: params?.offset ? String(params.offset) : undefined,\n orderBy: params?.orderBy?.[0],\n order: params?.orderBy?.[1],\n searchString: params?.searchString\n },\n (incomingRows: Record<string, unknown>[]) => {\n const currentUpdateId = ++lastUpdateId;\n const requestedLimit = params?.limit || 20;\n const offset = params?.offset || 0;\n\n // WS client already delivers flat rows — just cast\n const rows = incomingRows as M[];\n\n // Heuristic metadata (used as fallback if count call fails)\n const heuristicTotal = rows.length;\n const heuristicHasMore = rows.length >= requestedLimit;\n\n // Try to get authoritative count; fall back to heuristic\n if (client.count) {\n client.count(params)\n .then((total) => {\n if (active && currentUpdateId === lastUpdateId) {\n onUpdate({\n data: rows,\n meta: {\n total,\n limit: requestedLimit,\n offset,\n hasMore: offset + rows.length < total\n }\n });\n }\n })\n .catch(() => {\n // Count failed — use heuristic meta\n if (active && currentUpdateId === lastUpdateId) {\n onUpdate({\n data: rows,\n meta: {\n total: heuristicTotal,\n limit: requestedLimit,\n offset,\n hasMore: heuristicHasMore\n }\n });\n }\n });\n } else {\n // No count method — fire immediately with heuristic meta\n onUpdate({\n data: rows,\n meta: {\n total: heuristicTotal,\n limit: requestedLimit,\n offset,\n hasMore: heuristicHasMore\n }\n });\n }\n },\n onError\n );\n\n return () => {\n active = false;\n unsub();\n };\n };\n\n client.listenById = (id: string | number, onUpdate: (data: M | undefined) => void, onError?: (error: Error) => void) => {\n return ws.listenOne(\n {\n path: slug,\n id: String(id)\n },\n (row: Record<string, unknown> | null) => {\n if (row) {\n onUpdate(row as M);\n } else {\n onUpdate(undefined);\n }\n },\n onError\n );\n };\n }\n\n return client;\n}\n","import type { Transport } from \"./transport\";\n\n/**\n * Client interface for invoking custom backend functions.\n *\n * Custom functions are Hono route files auto-mounted by the Rebase backend\n * at `/api/functions/{name}`. The `FunctionsClient` wraps the shared\n * transport so callers never need to manually construct URLs or inject\n * auth tokens.\n *\n * @example\n * ```ts\n * const result = await client.functions.invoke<{ job: Job }>('extract-job', {\n * url: 'https://example.com/posting',\n * html: htmlContent,\n * });\n * ```\n */\nexport interface FunctionsClient {\n /**\n * Invoke a custom backend function by name.\n *\n * @typeParam T - Expected shape of the response payload.\n * @param name - Function name (the filename without extension, e.g. `\"extract-job\"`).\n * @param payload - Optional JSON-serialisable body sent as `POST`.\n * @param options - Optional overrides (HTTP method, sub-path, extra headers).\n * @returns The parsed JSON response from the function.\n */\n invoke<T = unknown>(\n name: string,\n payload?: unknown,\n options?: FunctionInvokeOptions,\n ): Promise<T>;\n}\n\nexport interface FunctionInvokeOptions {\n /** HTTP method — defaults to `\"POST\"`. */\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n /** Sub-path appended after the function name, e.g. `\"status/123\"`. */\n path?: string;\n /** Extra headers merged into the request (auth is still injected automatically). */\n headers?: Record<string, string>;\n}\n\n/**\n * Create a `FunctionsClient` backed by the given transport.\n *\n * The transport already handles:\n * - Base URL resolution\n * - JWT injection via `Authorization: Bearer`\n * - 401 retry / `onUnauthorized` flow\n * - Consistent error throwing via `RebaseApiError`\n *\n * @internal\n */\nexport function createFunctionsClient(transport: Transport): FunctionsClient {\n return {\n async invoke<T = unknown>(\n name: string,\n payload?: unknown,\n options?: FunctionInvokeOptions\n ): Promise<T> {\n const method = options?.method ?? \"POST\";\n const subPath = options?.path ? `/${options.path.replace(/^\\//, \"\")}` : \"\";\n const routePath = `/functions/${encodeURIComponent(name)}${subPath}`;\n\n const init: RequestInit = { method };\n\n if (payload !== undefined && method !== \"GET\") {\n init.body = JSON.stringify(payload);\n }\n\n if (options?.headers) {\n init.headers = options.headers;\n }\n\n return transport.request<T>(routePath, init);\n }\n };\n}\n","import { StorageSource, UploadFileProps, UploadFileResult, DownloadConfig, StorageListResult, DownloadMetadata, PUBLIC_STORAGE_PREFIX, isPublicStoragePath } from \"@rebasepro/types\";\nimport { Transport } from \"./transport\";\n\n/**\n * Create a StorageSource that talks to the Rebase backend REST API.\n *\n * @param transport - HTTP transport instance\n * @param storageId - Optional storage-source key for multi-backend routing.\n * When set, it is forwarded to the server so the correct\n * `StorageController` is resolved from the registry.\n */\nexport function createStorage(transport: Transport, storageId?: string): StorageSource {\n const urlsCache = new Map<string, { config: DownloadConfig; expiresAt?: number }>();\n\n /** Append ?storageId=... to a path when multi-backend routing is active. */\n const withStorageId = (path: string): string => {\n if (!storageId) return path;\n const sep = path.includes(\"?\") ? \"&\" : \"?\";\n return `${path}${sep}storageId=${encodeURIComponent(storageId)}`;\n };\n\n async function putObject({\n file,\n key,\n metadata,\n bucket,\n public: isPublic\n }: UploadFileProps): Promise<UploadFileResult> {\n const formData = new FormData();\n formData.append(\"file\", file);\n\n // Public objects live under the public prefix so they can be served\n // token-less via a stable, permanent URL. Normalize the key here so the\n // stored path is self-describing (no server round-trip needed to know\n // it's public).\n let effectiveKey = key;\n if (isPublic && effectiveKey && !isPublicStoragePath(effectiveKey)) {\n effectiveKey = `${PUBLIC_STORAGE_PREFIX}${effectiveKey.replace(/^\\/+/, \"\")}`;\n }\n\n if (effectiveKey) formData.append(\"key\", effectiveKey);\n if (bucket) formData.append(\"bucket\", bucket);\n if (storageId) formData.append(\"storageId\", storageId);\n\n if (metadata) {\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== undefined && value !== null) {\n formData.append(\n `metadata_${key}`,\n typeof value === \"string\" ? value : JSON.stringify(value)\n );\n }\n }\n }\n\n const result = await transport.request<{ data: UploadFileResult }>(withStorageId(\"/storage/upload\"), {\n method: \"POST\",\n body: formData,\n headers: {}\n });\n\n return result.data;\n }\n\n async function getSignedUrl(\n keyOrUrl: string,\n bucket?: string\n ): Promise<DownloadConfig> {\n const cacheKey = bucket ? `${bucket}/${keyOrUrl}` : keyOrUrl;\n const cachedEntry = urlsCache.get(cacheKey);\n if (cachedEntry) {\n if (!cachedEntry.expiresAt || cachedEntry.expiresAt > Date.now()) {\n return cachedEntry.config;\n }\n urlsCache.delete(cacheKey);\n }\n\n let filePath = keyOrUrl;\n\n if (filePath && (filePath.startsWith(\"local://\") || filePath.startsWith(\"s3://\") || filePath.startsWith(\"gs://\"))) {\n filePath = filePath.substring(filePath.indexOf(\"://\") + 3);\n }\n\n if (bucket && filePath && !filePath.startsWith(bucket)) {\n filePath = `${bucket}/${filePath}`;\n }\n\n if (!filePath || filePath.trim() === \"\" || filePath === \"/\") {\n return { url: null, fileNotFound: true };\n }\n\n // ── Public objects ────────────────────────────────────────────────\n // A public file (under the public prefix) is served token-less via a\n // stable, permanent, CDN-cacheable URL. No metadata round-trip and no\n // token are needed — build the URL directly and cache it forever.\n if (isPublicStoragePath(filePath)) {\n const publicConfig: DownloadConfig = {\n url: withStorageId(`${transport.baseUrl}${transport.apiPath}/storage/file/${filePath}`)\n };\n urlsCache.set(cacheKey, { config: publicConfig }); // no expiry\n return publicConfig;\n }\n\n try {\n const result = await transport.request<{ data: DownloadMetadata }>(withStorageId(`/storage/metadata/${filePath}`));\n\n // Public object (server-confirmed): token-less permanent URL.\n if (result.data.public) {\n const publicConfig: DownloadConfig = {\n url: withStorageId(`${transport.baseUrl}${transport.apiPath}/storage/file/${filePath}`),\n metadata: result.data\n };\n urlsCache.set(cacheKey, { config: publicConfig }); // no expiry\n return publicConfig;\n }\n\n // Private object: use the short-lived, file-scoped download token\n // minted by the server. We deliberately do NOT fall back to the\n // caller's access token — a URL must never carry a full-privilege\n // credential. If no scoped token is present the URL fails closed.\n const scopedToken = result.data.token;\n const tokenQuery = scopedToken ? `?token=${scopedToken}` : \"\";\n\n const downloadConfig: DownloadConfig = {\n // `withStorageId` picks `?` or `&` based on whether the token\n // query is already present, so the URL stays valid even when\n // there is no token.\n url: withStorageId(`${transport.baseUrl}${transport.apiPath}/storage/file/${filePath}${tokenQuery}`),\n metadata: result.data\n };\n\n const expiresAt = result.data.tokenExpiresIn\n ? Date.now() + (result.data.tokenExpiresIn - 10) * 1000 // subtract 10s buffer\n : undefined;\n\n urlsCache.set(cacheKey, { config: downloadConfig, expiresAt });\n return downloadConfig;\n } catch (e: unknown) {\n if (e instanceof Error && \"status\" in e && (e as { status: number }).status === 404) {\n return { url: null, fileNotFound: true };\n }\n throw e;\n }\n }\n\n async function getObject(\n key: string,\n bucket?: string\n ): Promise<File | null> {\n const downloadConfig = await getSignedUrl(key, bucket);\n if (downloadConfig.fileNotFound || !downloadConfig.url) {\n return null;\n }\n\n // Fetch using the signed URL directly. Since the scoped token is in the ?token= query param,\n // we explicitly omit any Authorization headers to prevent passing full access tokens to file serving routes.\n const response = await transport.fetchFn(downloadConfig.url, {\n headers: {}\n });\n\n if (response.status === 404) return null;\n if (!response.ok) throw new Error(\"Failed to get file\");\n\n const blob = await response.blob();\n const fileName = (bucket ? `${bucket}/${key}` : key).split(\"/\").pop() || \"file\";\n return new File([blob], fileName, { type: blob.type });\n }\n\n async function deleteObject(\n key: string,\n bucket?: string\n ): Promise<void> {\n let filePath = key;\n\n if (filePath && (filePath.startsWith(\"local://\") || filePath.startsWith(\"s3://\") || filePath.startsWith(\"gs://\"))) {\n filePath = filePath.substring(filePath.indexOf(\"://\") + 3);\n }\n\n if (bucket && filePath && !filePath.startsWith(bucket)) {\n filePath = `${bucket}/${filePath}`;\n }\n\n if (!filePath || filePath.trim() === \"\" || filePath === \"/\") {\n return;\n }\n\n try {\n await transport.request(withStorageId(`/storage/file/${filePath}`), { method: \"DELETE\" });\n } catch (e: unknown) {\n if (!(e instanceof Error && \"status\" in e && (e as { status: number }).status === 404)) throw e;\n }\n\n urlsCache.delete(bucket ? `${bucket}/${key}` : key);\n }\n\n async function listObjects(\n prefix: string,\n options?: {\n bucket?: string;\n maxResults?: number;\n pageToken?: string;\n }\n ): Promise<StorageListResult> {\n const params = new URLSearchParams();\n if (prefix) params.set(\"prefix\", prefix);\n if (options?.bucket) params.set(\"bucket\", options.bucket);\n if (options?.maxResults) params.set(\"maxResults\", String(options.maxResults));\n if (options?.pageToken) params.set(\"pageToken\", options.pageToken);\n\n if (storageId) params.set(\"storageId\", storageId);\n\n const result = await transport.request<{ data: StorageListResult }>(`/storage/list?${params.toString()}`);\n return result.data;\n }\n\n return {\n putObject,\n getSignedUrl,\n getObject,\n deleteObject,\n listObjects\n };\n}\n","/**\n * Client-side storage source registry.\n *\n * Manages multiple `StorageSource` instances keyed by\n * `StorageSourceDefinition.key`. Collection properties reference\n * a source by key via `StorageConfig.storageSource`.\n *\n * Typical bootstrap flow:\n * 1. Fetch definitions from `GET /api/storage/sources`\n * 2. Build server-backed sources automatically via `createStorage(transport, key)`\n * 3. Register \"direct\" sources manually (e.g. Firebase Storage hook)\n */\n\nimport type { StorageSource, StorageSourceRegistry, StorageSourceDefinition } from \"@rebasepro/types\";\nimport { DEFAULT_STORAGE_SOURCE_KEY } from \"@rebasepro/types\";\nimport { createStorage } from \"./storage\";\nimport type { Transport } from \"./transport\";\n\n/**\n * Default implementation of the client-side `StorageSourceRegistry`.\n */\nexport class ClientStorageSourceRegistry implements StorageSourceRegistry {\n private sources = new Map<string, StorageSource>();\n\n /**\n * Register a storage source.\n * @param key - Unique key matching a `StorageSourceDefinition.key`\n * @param source - The `StorageSource` instance\n */\n register(key: string, source: StorageSource): void {\n this.sources.set(key, source);\n }\n\n getDefault(): StorageSource {\n const source = this.sources.get(DEFAULT_STORAGE_SOURCE_KEY);\n if (!source) {\n throw new Error(\n `[StorageSourceRegistry] No default storage source registered. ` +\n `Register one with key \"${DEFAULT_STORAGE_SOURCE_KEY}\".`\n );\n }\n return source;\n }\n\n get(key: string | undefined | null): StorageSource | undefined {\n if (key === undefined || key === null) {\n return this.sources.get(DEFAULT_STORAGE_SOURCE_KEY);\n }\n return this.sources.get(key);\n }\n\n getOrDefault(key: string | undefined | null): StorageSource {\n if (key === undefined || key === null) {\n return this.getDefault();\n }\n const source = this.sources.get(key);\n if (source) return source;\n\n // Fallback to default\n console.warn(\n `[StorageSourceRegistry] Storage source \"${key}\" not found, ` +\n `falling back to \"${DEFAULT_STORAGE_SOURCE_KEY}\".`\n );\n return this.getDefault();\n }\n\n has(key: string): boolean {\n return this.sources.has(key);\n }\n\n list(): string[] {\n return Array.from(this.sources.keys());\n }\n\n /**\n * Build a registry from `StorageSourceDefinition[]` and an HTTP transport.\n *\n * - Sources with `transport: \"server\"` are auto-wired via `createStorage(transport, key)`.\n * - Sources with `transport: \"direct\"` are **not** auto-wired — they must\n * be registered manually after this call (e.g. via a Firebase hook).\n *\n * @param definitions - Array of storage source definitions\n * @param transport - HTTP transport for server-backed sources\n */\n static fromDefinitions(\n definitions: StorageSourceDefinition[],\n transport: Transport\n ): ClientStorageSourceRegistry {\n const registry = new ClientStorageSourceRegistry();\n\n for (const def of definitions) {\n if (def.transport === \"server\") {\n // Auto-create a server-backed StorageSource for this key\n const source = createStorage(transport, def.key === DEFAULT_STORAGE_SOURCE_KEY ? undefined : def.key);\n registry.register(def.key, source);\n }\n // \"direct\" sources must be registered manually\n }\n\n return registry;\n }\n}\n","import {\n DeleteProps,\n CollectionConfig,\n FetchCollectionProps,\n FetchOneProps,\n SaveProps,\n WebSocketMessage,\n WebSocketErrorPayload,\n CollectionUpdateMessage,\n SingleUpdateMessage,\n TableMetadata,\n BranchInfo,\n RebaseApiError\n} from \"@rebasepro/types\";\nimport { rebaseReviver } from \"./reviver\";\n\n\n\n/**\n * Extract error message and code from a WebSocket message payload.\n * Handles both `{ error: string }` and `{ error: { message, code } }` shapes.\n */\nfunction extractMessageError(message: WebSocketMessage): { errorMessage: string; errorCode?: string } {\n const payload = message.payload as WebSocketErrorPayload | undefined;\n const errPayload = payload?.error;\n const errorMessage = typeof errPayload === \"object\"\n ? errPayload.message\n : payload?.message || (typeof errPayload === \"string\" ? errPayload : undefined) || message.error || \"Unknown error\";\n const errorCode = typeof errPayload === \"object\"\n ? errPayload.code\n : payload?.code;\n return { errorMessage,\nerrorCode };\n}\n\nexport interface RebaseWebSocketConfig {\n websocketUrl: string;\n /** Optional auth token getter for WebSocket authentication */\n getAuthToken?: () => Promise<string | null>;\n /** Optional WebSocket constructor to override globalThis.WebSocket (e.g. for Node environments) */\n WebSocket?: typeof WebSocket;\n /** Callback to handle unauthorized requests or token expiration (refreshes auth session) */\n onUnauthorized?: () => Promise<boolean>;\n}\n\n\n/**\n * Low-level realtime WebSocket client.\n *\n * @internal Not a stable app-facing API. `createRebaseClient()` constructs and\n * manages this internally (exposed as `client.ws`, typed by the minimal\n * `RebaseWebSocket` contract in `@rebasepro/types`). It is re-exported from the\n * package root only because the `@rebasepro/client-postgresql` driver\n * instantiates it directly; its surface may change without a major bump.\n */\nexport class RebaseWebSocketClient {\n private websocketUrl: string;\n private ws: WebSocket | null = null;\n public getAuthToken?: () => Promise<string | null>;\n private subscriptions = new Map<string, {\n onUpdate: (data: WebSocketMessage) => void,\n onError?: (error: Error) => void\n }>();\n\n private listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n public on(event: \"connect\" | \"disconnect\" | \"reconnect\" | \"error\", cb: (...args: unknown[]) => void) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(cb);\n return () => this.listeners.get(event)!.delete(cb);\n }\n\n private emit(event: string, ...args: unknown[]) {\n if (this.listeners.has(event)) {\n this.listeners.get(event)!.forEach(cb => cb(...args));\n }\n }\n\n // New: Subscription deduplication management with optimizations\n private collectionSubscriptions = new Map<string, {\n backendSubscriptionId: string;\n callbacks: Map<string, {\n onUpdate: (rows: Record<string, unknown>[]) => void;\n onError?: (error: Error) => void;\n }>;\n props: FetchCollectionProps;\n latestData?: Record<string, unknown>[]; // Cache the latest flat rows\n lastUpdated?: number; // Timestamp for cache invalidation\n isInitialDataReceived?: boolean; // Track if we got initial data\n }>();\n\n private singleSubscriptions = new Map<string, {\n backendSubscriptionId: string;\n callbacks: Map<string, {\n onUpdate: (row: Record<string, unknown> | null) => void;\n onError?: (error: Error) => void;\n }>;\n props: FetchOneProps;\n latestData?: Record<string, unknown> | null; // Cache the latest flat row\n lastUpdated?: number; // Timestamp for cache invalidation\n isInitialDataReceived?: boolean; // Track if we got initial data\n }>();\n\n // Maps to quickly find subscription by backend subscription ID\n private backendToCollectionKey = new Map<string, string>();\n private backendToEntityKey = new Map<string, string>();\n\n\n private pendingRequests = new Map<string, {\n resolve: (p: unknown) => void;\n reject: (p: Error) => void;\n message?: Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void }\n }>();\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private isConnected = false;\n private messageQueue: Record<string, unknown>[] = [];\n private requestTimeoutMs = 30000;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n\n private isAuthenticated = false;\n private authPromise: Promise<void> | null = null;\n private WebSocketConstructor: typeof WebSocket | undefined;\n public onUnauthorized?: () => Promise<boolean>;\n private refreshInProgress: Promise<boolean> | null = null;\n\n constructor(config: RebaseWebSocketConfig) {\n this.websocketUrl = config.websocketUrl;\n this.getAuthToken = config.getAuthToken;\n this.onUnauthorized = config.onUnauthorized;\n this.WebSocketConstructor = config.WebSocket || (typeof WebSocket !== \"undefined\" ? WebSocket : undefined);\n\n if (!this.WebSocketConstructor) {\n console.warn(\"WebSocket is not defined in this environment. Realtime subscriptions will not work unless you provide a WebSocket implementation in the config.\");\n } else {\n this.initWebSocket();\n }\n }\n\n /**\n * Authenticate the WebSocket connection\n */\n async authenticate(token: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const requestId = `auth_${Date.now()}`;\n\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n this.authPromise = null; // Clear promise so we can retry later\n reject(new Error(\"Authentication timeout\"));\n }, 30000);\n\n this.pendingRequests.set(requestId, {\n resolve: () => {\n clearTimeout(timeout);\n this.isAuthenticated = true;\n resolve();\n },\n reject: (error) => {\n clearTimeout(timeout);\n reject(error);\n }\n });\n\n const message = {\n type: \"AUTHENTICATE\",\n requestId,\n payload: { token }\n };\n\n if (!this.isConnected || !this.ws) {\n this.messageQueue.unshift(message); // Auth should be first\n } else {\n this.ws.send(JSON.stringify(message));\n }\n });\n }\n\n /**\n * Set the auth token getter function\n */\n setAuthTokenGetter(getAuthToken: () => Promise<string | null>): void {\n this.getAuthToken = getAuthToken;\n // Auto-authenticate if we are already connected but didn't have the token getter yet\n if (this.isConnected && !this.isAuthenticated && !this.authPromise) {\n console.debug(\"WebSocket auto-authenticating after token getter set\");\n this.getAuthToken().then(token => {\n if (!this.ws) return; // Prevent memory leaks / actions after disconnect\n if (token) {\n this.authenticate(token).catch(e => {\n if (this.ws) console.debug(\"WebSocket auto-auth skipped:\", e?.message || e);\n });\n }\n }).catch(e => {\n // User not logged in or auth still loading — this is expected,\n // the WebSocket will authenticate on-demand when a request is made.\n if (this.ws) console.debug(\"WebSocket auto-auth skipped:\", e?.message || e);\n });\n }\n }\n\n public disconnect(): void {\n this.isAuthenticated = false;\n this.authPromise = null;\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect on explicit disconnect\n this.ws.onerror = null; // Prevent errors on explicit disconnect\n this.ws.onopen = null;\n this.ws.onmessage = null;\n this.ws.close();\n this.ws = null;\n }\n }\n\n // Initialize WebSocket connection\n private initWebSocket() {\n if (!this.WebSocketConstructor) return;\n if (this.ws?.readyState === this.WebSocketConstructor.OPEN) return;\n\n // Guard against race condition: if a previous socket is still connecting, tear it down\n if (this.ws) {\n this.ws.onclose = null;\n this.ws.close();\n this.ws = null;\n }\n\n try {\n this.ws = new this.WebSocketConstructor(this.websocketUrl);\n\n this.ws!.onopen = async () => {\n console.debug(\"Connected to PostgreSQL backend\");\n const wasReconnect = this.reconnectAttempts > 0;\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n // Auto-authenticate if token getter is available\n if (this.getAuthToken && !this.isAuthenticated) {\n try {\n const token = await this.getAuthToken();\n if (token) {\n await this.authenticate(token);\n console.debug(\"WebSocket auto-authenticated\");\n }\n } catch (error) {\n // User not logged in or auth still loading — this is expected.\n // Authentication will happen on-demand when the user logs in.\n console.debug(\"WebSocket connected without auth:\", (error as Error)?.message || error);\n }\n }\n\n this.emit(wasReconnect ? \"reconnect\" : \"connect\");\n this.processMessageQueue();\n\n // Re-subscribe all active subscriptions after reconnect.\n // The server-side subscription state was lost when the connection dropped,\n // so we need to re-register every active subscription.\n if (wasReconnect) {\n this.resubscribeAll();\n }\n };\n\n this.ws!.onmessage = (event) => {\n try {\n const message = JSON.parse(event.data, rebaseReviver);\n this.handleWebSocketMessage(message);\n } catch (error) {\n console.error(\"Error parsing WebSocket message:\", error);\n }\n };\n\n this.ws!.onclose = () => {\n console.debug(\"Disconnected from PostgreSQL backend\");\n this.isConnected = false;\n this.isAuthenticated = false;\n this.authPromise = null;\n this.emit(\"disconnect\");\n\n // Re-queue pending requests so the UI doesn't hang indefinitely or crash\n for (const [reqId, request] of this.pendingRequests.entries()) {\n if (reqId.startsWith(\"auth_\")) {\n request.reject(new Error(\"Connection closed during authentication\"));\n } else if (request.message) {\n request.message._queuedResolve = request.resolve;\n request.message._queuedReject = request.reject;\n this.messageQueue.push(request.message);\n } else {\n request.reject(new RebaseApiError(\"Connection closed\"));\n }\n this.pendingRequests.delete(reqId);\n }\n\n this.attemptReconnect();\n };\n\n this.ws!.onerror = (error) => {\n console.error(\"WebSocket error:\", error);\n this.isConnected = false;\n this.emit(\"error\", error);\n };\n } catch (error) {\n console.error(\"Failed to initialize WebSocket:\", error);\n this.attemptReconnect();\n }\n }\n\n private processMessageQueue() {\n while (this.messageQueue.length > 0 && this.isConnected) {\n const message = this.messageQueue.shift();\n if (message) this.sendMessage(message);\n }\n }\n\n private attemptReconnect() {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n console.error(\"Max reconnection attempts reached\");\n return;\n }\n\n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n\n console.debug(`Attempting to reconnect in ${delay}ms (attempt ${this.reconnectAttempts})`);\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n }\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n this.initWebSocket();\n }, delay);\n }\n\n private isAuthError(message: WebSocketMessage): boolean {\n if (message.type === \"AUTH_ERROR\") return true;\n const { errorMessage, errorCode } = extractMessageError(message);\n if (errorCode === \"UNAUTHORIZED\" || errorCode === \"JWT_EXPIRED\" || errorCode === \"AUTH_ERROR\") return true;\n const lowerMessage = errorMessage.toLowerCase();\n return lowerMessage.includes(\"unauthorized\") || lowerMessage.includes(\"token expired\") || lowerMessage.includes(\"token is expired\") || lowerMessage.includes(\"invalid token\") || lowerMessage.includes(\"session expired\") || lowerMessage.includes(\"auth error\");\n }\n\n private async handleAuthFailure(): Promise<boolean> {\n if (this.refreshInProgress) {\n return this.refreshInProgress;\n }\n this.refreshInProgress = (async () => {\n this.isAuthenticated = false;\n this.authPromise = null;\n if (this.onUnauthorized) {\n try {\n const refreshed = await this.onUnauthorized();\n if (refreshed && this.getAuthToken) {\n const token = await this.getAuthToken();\n if (token) {\n await this.authenticate(token);\n return true;\n }\n }\n } catch (error) {\n console.error(\"WebSocket auth refresh failed:\", error);\n }\n }\n return false;\n })();\n try {\n return await this.refreshInProgress;\n } finally {\n this.refreshInProgress = null;\n }\n }\n\n /**\n * Shared logic for re-subscribing a collection or row subscription\n * after an auth error is resolved by refreshing credentials.\n */\n private resubscribeAfterAuthRefresh(\n message: WebSocketMessage,\n subscription: {\n backendSubscriptionId: string;\n callbacks: Map<string, { onUpdate: (...args: never[]) => void; onError?: (error: Error) => void }>;\n props: FetchCollectionProps | FetchOneProps;\n },\n subscriptionKey: string,\n idPrefix: \"collection\" | \"row\",\n backendKeyMap: Map<string, string>,\n messageType: \"subscribe_collection\" | \"subscribe_one\"\n ): void {\n this.handleAuthFailure().then(refreshed => {\n if (refreshed) {\n const oldBackendId = subscription.backendSubscriptionId;\n const newBackendId = `${idPrefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n subscription.backendSubscriptionId = newBackendId;\n backendKeyMap.delete(oldBackendId);\n backendKeyMap.set(newBackendId, subscriptionKey);\n\n this.sendMessage({\n type: messageType,\n payload: {\n ...subscription.props,\n subscriptionId: newBackendId\n }\n }).catch(error => {\n console.error(`[WS] Failed to re-subscribe ${idPrefix} after auth refresh:`, subscriptionKey, error);\n subscription.callbacks.forEach(callback => {\n if (callback.onError) callback.onError(error);\n });\n });\n } else {\n const { errorMessage, errorCode } = extractMessageError(message);\n const error = new RebaseApiError(errorMessage, { code: errorCode });\n subscription.callbacks.forEach(callback => {\n if (callback.onError) callback.onError(error);\n });\n }\n }).catch(err => {\n subscription.callbacks.forEach(callback => {\n if (callback.onError) callback.onError(err);\n });\n });\n }\n\n private handleWebSocketMessage(message: WebSocketMessage) {\n const {\n type,\n requestId,\n subscriptionId\n } = message;\n\n // Handle responses to pending requests\n if (requestId && this.pendingRequests.has(requestId)) {\n const pendingReq = this.pendingRequests.get(requestId)!;\n if (type === \"ERROR\" || type === \"AUTH_ERROR\" || message.error) {\n if (this.isAuthError(message)) {\n this.pendingRequests.delete(requestId);\n this.handleAuthFailure().then(refreshed => {\n if (refreshed && pendingReq.message) {\n this.doSendMessage(pendingReq.message, pendingReq.resolve, pendingReq.reject).catch(pendingReq.reject);\n } else {\n const { errorMessage, errorCode } = extractMessageError(message);\n pendingReq.reject(new RebaseApiError(errorMessage, { code: errorCode }));\n }\n }).catch(err => {\n pendingReq.reject(err);\n });\n } else {\n this.pendingRequests.delete(requestId);\n const { errorMessage, errorCode } = extractMessageError(message);\n pendingReq.reject(new RebaseApiError(errorMessage, { code: errorCode }));\n }\n } else {\n this.pendingRequests.delete(requestId);\n pendingReq.resolve(message.payload || message);\n }\n return;\n }\n\n // Handle subscription updates for collection subscriptions\n if (subscriptionId && type === \"collection_update\") {\n const subscriptionKey = this.backendToCollectionKey.get(subscriptionId);\n if (subscriptionKey) {\n const collectionSub = this.collectionSubscriptions.get(subscriptionKey);\n if (collectionSub) {\n const wireEntities = (message.rows || []) as unknown as Record<string, unknown>[];\n const incomingRows = wireEntities;\n\n // Structural merge: preserve cached row references for rows\n // whose values haven't changed. This prevents downstream React components\n // from re-rendering (VirtualTableCell uses deepEqual on rowData —\n // same reference = instant true, avoiding expensive deep comparison).\n const rows = this.mergeRows(collectionSub.latestData, incomingRows);\n\n // Cache the latest data with optimizations\n collectionSub.latestData = rows;\n collectionSub.lastUpdated = Date.now();\n collectionSub.isInitialDataReceived = true;\n\n // Notify all callbacks for this subscription\n collectionSub.callbacks.forEach(callback => {\n try {\n callback.onUpdate(rows);\n } catch (error) {\n console.error(\"Error in collection subscription callback:\", error);\n if (callback.onError) {\n callback.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n });\n return;\n }\n }\n }\n\n // Handle instant row-level patches for collection subscriptions.\n // These arrive before the full refetch and give immediate cross-tab feedback.\n if (subscriptionId && type === \"collection_patch\") {\n const subscriptionKey = this.backendToCollectionKey.get(subscriptionId);\n if (subscriptionKey) {\n const collectionSub = this.collectionSubscriptions.get(subscriptionKey);\n if (collectionSub && collectionSub.isInitialDataReceived && collectionSub.latestData) {\n const patchWireEntity = message.row ?? null;\n const patchEntityId = (message as unknown as { id: string }).id;\n const patchRow = patchWireEntity ? (patchWireEntity as unknown as Record<string, unknown>) : null;\n let updated: Record<string, unknown>[];\n\n if (patchRow === null) {\n // Row was deleted — remove it from the cached list\n updated = collectionSub.latestData.filter(e => String(e.id) !== String(patchEntityId));\n } else {\n // Row was created or updated — merge into the cached list\n const idx = collectionSub.latestData.findIndex(e => String(e.id) === String(patchRow.id));\n if (idx >= 0) {\n // Update in place (preserve array position)\n updated = [...collectionSub.latestData];\n updated[idx] = patchRow;\n } else {\n // New row — prepend (most recently created first)\n updated = [patchRow, ...collectionSub.latestData];\n }\n }\n\n collectionSub.latestData = updated;\n collectionSub.lastUpdated = Date.now();\n\n // Fire all callbacks with the patched data\n collectionSub.callbacks.forEach(callback => {\n try {\n callback.onUpdate(updated);\n } catch (error) {\n console.error(\"Error in collection patch callback:\", error);\n if (callback.onError) {\n callback.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n });\n return;\n }\n }\n }\n\n // Handle subscription updates for row subscriptions\n if (subscriptionId && type === \"single_update\") {\n const subscriptionKey = this.backendToEntityKey.get(subscriptionId);\n if (subscriptionKey) {\n const entitySub = this.singleSubscriptions.get(subscriptionKey);\n if (entitySub) {\n const wireEntity = message.row ?? null;\n const row = wireEntity ? (wireEntity as unknown as Record<string, unknown>) : null;\n // Cache the latest data with optimizations\n entitySub.latestData = row;\n entitySub.lastUpdated = Date.now();\n entitySub.isInitialDataReceived = true;\n\n // Notify all callbacks for this subscription\n entitySub.callbacks.forEach(callback => {\n try {\n callback.onUpdate(row);\n } catch (error) {\n console.error(\"Error in row subscription callback:\", error);\n if (callback.onError) {\n callback.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n });\n return;\n }\n }\n }\n\n // Handle subscription errors\n if (subscriptionId && (type === \"ERROR\" || message.error)) {\n const collectionKey = this.backendToCollectionKey.get(subscriptionId);\n if (collectionKey) {\n const collectionSub = this.collectionSubscriptions.get(collectionKey);\n if (collectionSub) {\n if (this.isAuthError(message)) {\n this.resubscribeAfterAuthRefresh(\n message,\n collectionSub,\n collectionKey,\n \"collection\",\n this.backendToCollectionKey,\n \"subscribe_collection\"\n );\n return;\n }\n\n const { errorMessage, errorCode } = extractMessageError(message);\n const error = new RebaseApiError(errorMessage, { code: errorCode });\n collectionSub.callbacks.forEach(callback => {\n if (callback.onError) {\n callback.onError(error);\n }\n });\n return;\n }\n }\n\n const entityKey = this.backendToEntityKey.get(subscriptionId);\n if (entityKey) {\n const entitySub = this.singleSubscriptions.get(entityKey);\n if (entitySub) {\n if (this.isAuthError(message)) {\n this.resubscribeAfterAuthRefresh(\n message,\n entitySub,\n entityKey,\n \"row\",\n this.backendToEntityKey,\n \"subscribe_one\"\n );\n return;\n }\n\n const { errorMessage, errorCode } = extractMessageError(message);\n const error = new RebaseApiError(errorMessage, { code: errorCode });\n entitySub.callbacks.forEach(callback => {\n if (callback.onError) {\n callback.onError(error);\n }\n });\n return;\n }\n }\n }\n\n // Legacy subscription handling (for backward compatibility)\n if (subscriptionId && this.subscriptions.has(subscriptionId)) {\n const callback = this.subscriptions.get(subscriptionId);\n if (!callback) {\n throw new Error(`Subscription callback not found for subscriptionId: ${subscriptionId}`);\n }\n if (message.type === \"ERROR\" || message.error) {\n if (callback.onError) {\n const { errorMessage, errorCode } = extractMessageError(message);\n callback.onError(new RebaseApiError(errorMessage, { code: errorCode }));\n }\n } else {\n callback.onUpdate(message);\n }\n }\n }\n\n private async ensureAuthenticated(retryCount = 3): Promise<void> {\n // If already authenticated or no token getter, skip\n if (this.isAuthenticated || !this.getAuthToken) return;\n\n // If auth is in progress, wait for it\n if (this.authPromise) {\n await this.authPromise;\n return;\n }\n\n // Try to authenticate with retries\n let lastError: unknown = null;\n\n for (let attempt = 0; attempt < retryCount; attempt++) {\n try {\n const token = await this.getAuthToken();\n if (!token) throw new Error(\"user not logged in\");\n this.authPromise = this.authenticate(token);\n await this.authPromise;\n this.authPromise = null;\n console.debug(\"WebSocket authenticated on demand\");\n return; // Success\n } catch (error: unknown) {\n this.authPromise = null;\n lastError = error;\n\n const errMsg = error instanceof Error ? error.message : String(error);\n // \"not logged in\" / \"Session expired\" are definitive - don't retry\n if (errMsg.includes(\"not logged in\") || errMsg.includes(\"Session expired\")) {\n console.warn(\"WebSocket auth failed: user not logged in\");\n throw error;\n }\n\n // \"still loading\" is transient - retry with backoff (auth controller\n // is restoring tokens from localStorage; it will resolve shortly)\n if (errMsg.includes(\"still loading\")) {\n if (attempt < retryCount - 1) {\n const delay = Math.min(500 * (attempt + 1), 2000);\n await new Promise(resolve => setTimeout(resolve, delay));\n continue;\n }\n }\n\n // For other errors, retry with backoff\n if (attempt < retryCount - 1) {\n const delay = Math.min(1000 * (attempt + 1), 3000);\n console.debug(`WebSocket auth attempt ${attempt + 1} failed, retrying in ${delay}ms...`);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n console.warn(\"WebSocket on-demand auth failed after retries:\", lastError);\n throw lastError;\n }\n\n async reauthenticate(): Promise<void> {\n if (!this.getAuthToken) return;\n\n this.isAuthenticated = false;\n try {\n const token = await this.getAuthToken();\n if (!token) throw new Error(\"user not logged in\");\n await this.authenticate(token);\n console.debug(\"WebSocket reauthenticated successfully\");\n } catch (error) {\n console.error(\"WebSocket reauthentication failed:\", error);\n throw error;\n }\n }\n\n private sendMessage(message: Record<string, unknown>): Promise<unknown> {\n // If already has a requestId (re-sending from queue), use the stored promise handlers\n const queuedMsg = message as Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void };\n if (queuedMsg._queuedResolve && queuedMsg._queuedReject) {\n return this.doSendMessage(message, queuedMsg._queuedResolve, queuedMsg._queuedReject);\n }\n\n if (!this.isConnected || !this.ws) {\n // Queue the message and return a promise that will be resolved when actually sent\n return new Promise<unknown>((resolve, reject) => {\n const queueable = message as Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void };\n queueable._queuedResolve = resolve;\n queueable._queuedReject = reject;\n this.messageQueue.push(message);\n });\n }\n\n return new Promise<unknown>((resolve, reject) => {\n this.doSendMessage(message, resolve, reject);\n });\n }\n\n private async doSendMessage(message: Record<string, unknown>, resolve: (value: unknown) => void, reject: (error: Error) => void): Promise<void> {\n // Ensure authenticated before sending non-auth messages\n if (message.type !== \"AUTHENTICATE\" && this.getAuthToken && !this.isAuthenticated) {\n try {\n await this.ensureAuthenticated();\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : \"Authentication required\";\n reject(new RebaseApiError(errorMessage));\n return;\n }\n }\n\n const requestId = (message.requestId as string) || `req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n message.requestId = requestId;\n\n const expectsResponse = ![\n \"subscribe_collection\",\n \"subscribe_one\",\n \"unsubscribe\",\n \"join_channel\",\n \"leave_channel\",\n \"broadcast\",\n \"presence_track\",\n \"presence_untrack\",\n \"presence_state\"\n ].includes(message.type as string);\n\n if (expectsResponse && !this.pendingRequests.has(requestId)) {\n const timeoutHandle = setTimeout(() => {\n if (this.pendingRequests.has(requestId)) {\n this.pendingRequests.delete(requestId);\n reject(new RebaseApiError(\"Request timed out\"));\n }\n }, this.requestTimeoutMs);\n\n this.pendingRequests.set(requestId, {\n resolve: (value: unknown) => {\n clearTimeout(timeoutHandle);\n resolve(value);\n },\n reject: (error: Error) => {\n clearTimeout(timeoutHandle);\n reject(error);\n },\n message: message as Record<string, unknown> & { _queuedResolve?: (p: unknown) => void; _queuedReject?: (p: Error) => void }\n });\n }\n\n try {\n this.ws!.send(JSON.stringify(message));\n if (!expectsResponse) {\n resolve(undefined);\n }\n } catch (error) {\n if (expectsResponse) {\n this.pendingRequests.delete(requestId);\n }\n reject(new RebaseApiError(\"Failed to send message\", { cause: error }));\n }\n }\n\n // Data source methods\n async fetchCollection<M extends Record<string, unknown>>(props: FetchCollectionProps<M>): Promise<Record<string, unknown>[]> {\n const response = await this.sendMessage({\n type: \"FETCH_COLLECTION\",\n payload: props\n }) as { rows?: Record<string, unknown>[] };\n return (response.rows || []);\n }\n\n async fetchOne<M extends Record<string, unknown>>(props: FetchOneProps<M>): Promise<Record<string, unknown> | undefined> {\n const response = await this.sendMessage({\n type: \"FETCH_ONE\",\n payload: props\n }) as { row?: Record<string, unknown> };\n const wireEntity = response.row;\n return wireEntity ?? undefined;\n }\n\n async save<M extends Record<string, unknown>>(props: SaveProps<M>): Promise<Record<string, unknown>> {\n const response = await this.sendMessage({\n type: \"SAVE\",\n payload: props\n }) as { row: Record<string, unknown> };\n return response.row;\n }\n\n async delete<M extends Record<string, unknown>>(props: DeleteProps<M>): Promise<void> {\n await this.sendMessage({\n type: \"DELETE\",\n payload: props\n });\n }\n\n async executeSql(sql: string, options?: { database?: string, role?: string }): Promise<Record<string, unknown>[]> {\n const response = await this.sendMessage({\n type: \"EXECUTE_SQL\",\n payload: { sql,\noptions }\n }) as { result?: Record<string, unknown>[] };\n return response.result || [];\n }\n\n async fetchAvailableDatabases(): Promise<string[]> {\n const response = await this.sendMessage({\n type: \"FETCH_DATABASES\",\n payload: {}\n }) as { databases?: string[] };\n return response.databases || [];\n }\n\n async fetchAvailableRoles(): Promise<string[]> {\n const response = await this.sendMessage({\n type: \"FETCH_ROLES\"\n }) as { roles?: string[] };\n return response.roles || [];\n }\n\n async fetchCurrentDatabase(): Promise<string | undefined> {\n const response = await this.sendMessage({\n type: \"FETCH_CURRENT_DATABASE\"\n }) as { database?: string };\n return response.database;\n }\n\n async checkUniqueField(path: string, name: string, value: unknown, id?: string, collection?: CollectionConfig): Promise<boolean> {\n const response = await this.sendMessage({\n type: \"CHECK_UNIQUE_FIELD\",\n payload: {\n path,\n name,\n value,\n id,\n collection\n }\n }) as { isUnique: boolean };\n return response.isUnique;\n }\n\n async count<M extends Record<string, unknown>>(props: FetchCollectionProps<M>): Promise<number> {\n const response = await this.sendMessage({\n type: \"COUNT\",\n payload: props\n }) as { count: number };\n return response.count;\n }\n\n async fetchUnmappedTables(mappedPaths?: string[]): Promise<string[]> {\n const response = await this.sendMessage({\n type: \"FETCH_UNMAPPED_TABLES\",\n payload: { mappedPaths }\n }) as { tables?: string[] };\n return response.tables || [];\n }\n\n async fetchTableMetadata(tableName: string): Promise<TableMetadata> {\n const response = await this.sendMessage({\n type: \"FETCH_TABLE_METADATA\",\n payload: { tableName }\n }) as { metadata?: TableMetadata };\n\n return response.metadata || ({ columns: [],\nforeignKeys: [],\njunctions: [],\npolicies: [] } as TableMetadata);\n }\n\n async createBranch(name: string, options?: { source?: string }): Promise<BranchInfo> {\n const response = await this.sendMessage({\n type: \"CREATE_BRANCH\",\n payload: { name,\noptions }\n }) as { branch: BranchInfo };\n return response.branch;\n }\n\n async deleteBranch(name: string): Promise<void> {\n await this.sendMessage({\n type: \"DELETE_BRANCH\",\n payload: { name }\n });\n }\n\n async listBranches(): Promise<BranchInfo[]> {\n const response = await this.sendMessage({\n type: \"LIST_BRANCHES\",\n payload: {}\n }) as { branches?: BranchInfo[] };\n return response.branches || [];\n }\n\n /**\n * Recursively compare two values for structural equality.\n * Handles primitives, null, undefined, Date, RegExp, arrays, and plain objects.\n */\n private deepEqual(a: unknown, b: unknown): boolean {\n // Same reference or same primitive\n if (a === b) return true;\n\n // Handle null/undefined\n if (a === null || b === null || a === undefined || b === undefined) return false;\n\n // Different types\n if (typeof a !== typeof b) return false;\n\n // Non-object primitives (number, string, boolean, bigint, symbol)\n // that weren't caught by === above (e.g. NaN !== NaN)\n if (typeof a !== \"object\") return false;\n\n // Date comparison\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n if (a instanceof Date || b instanceof Date) return false;\n\n // RegExp comparison\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.source === b.source && a.flags === b.flags;\n }\n if (a instanceof RegExp || b instanceof RegExp) return false;\n\n // Array comparison\n const aIsArray = Array.isArray(a);\n const bIsArray = Array.isArray(b);\n if (aIsArray !== bIsArray) return false;\n\n if (aIsArray && bIsArray) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!this.deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Plain object comparison\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n\n if (aKeys.length !== bKeys.length) return false;\n\n for (const key of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;\n if (!this.deepEqual(aObj[key], bObj[key])) return false;\n }\n\n return true;\n }\n\n private normalizeForComparison(val: unknown): unknown {\n if (!val) return val;\n\n if (Array.isArray(val)) {\n return val.map(item => this.normalizeForComparison(item));\n }\n\n if (typeof val === \"object\") {\n if (val instanceof Date) return val;\n if (val instanceof RegExp) return val;\n\n const obj = val as Record<string, unknown>;\n if (obj.__type === \"relation\") {\n const { data, ...rest } = obj;\n return rest;\n }\n\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n result[k] = this.normalizeForComparison(v);\n }\n return result;\n }\n\n return val;\n }\n\n /**\n * Merge incoming rows with cached data, preserving cached references\n * for rows whose values haven't changed. This avoids unnecessary\n * React re-renders when the server refetches all rows but most\n * haven't actually changed.\n */\n private mergeRows(cached: Record<string, unknown>[] | undefined, incoming: Record<string, unknown>[]): Record<string, unknown>[] {\n if (!cached || cached.length === 0) return incoming;\n\n // Build a lookup from cached rows by ID for O(1) access\n const cachedById = new Map<string | number, Record<string, unknown>>();\n for (const row of cached) {\n cachedById.set(row.id as string | number, row);\n }\n\n return incoming.map(incomingRow => {\n const cachedRow = cachedById.get(incomingRow.id as string | number);\n if (!cachedRow) return incomingRow;\n\n // Compare flat rows directly (no more path/values nesting)\n const normCached = this.normalizeForComparison(cachedRow) as Record<string, unknown>;\n const normIncoming = this.normalizeForComparison(incomingRow) as Record<string, unknown>;\n\n if (this.deepEqual(normCached, normIncoming)) {\n return cachedRow;\n } else {\n // Deep debug: Why did it fail?\n const mismatches: Record<string, { cached: unknown, incoming: unknown }> = {};\n const allKeys = new Set([...Object.keys(normCached), ...Object.keys(normIncoming)]);\n for (const key of allKeys) {\n if (!this.deepEqual(normCached[key], normIncoming[key])) {\n mismatches[key] = { cached: normCached[key],\nincoming: normIncoming[key] };\n }\n }\n console.debug(`[RebaseWS] Row ${incomingRow.id} refetch mismatch:\\n`, JSON.stringify(mismatches, null, 2));\n }\n return incomingRow;\n });\n }\n\n // Subscription methods\n listenCollection<M extends Record<string, unknown>>(\n props: FetchCollectionProps<M>,\n onUpdate: (rows: Record<string, unknown>[]) => void,\n onError?: (error: Error) => void\n ): () => void {\n const subscriptionKey = this.createCollectionSubscriptionKey(props);\n const callbackId = `callback_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n // Check if we already have a subscription for these exact parameters\n const existingSubscription = this.collectionSubscriptions.get(subscriptionKey);\n\n if (existingSubscription) {\n // Reuse existing subscription - just add the new callback\n const callbackMap = existingSubscription.callbacks as Map<string, {\n onUpdate: (rows: Record<string, unknown>[]) => void;\n onError?: (error: Error) => void;\n }>;\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n // Immediately fire the callback with cached data if available\n if (existingSubscription.latestData !== undefined && existingSubscription.isInitialDataReceived) {\n try {\n onUpdate(existingSubscription.latestData);\n } catch (error) {\n console.error(\"Error in collection subscription callback:\", error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n }\n\n // Return unsubscribe function\n return () => {\n callbackMap.delete(callbackId);\n if (callbackMap.size === 0) {\n // No more callbacks, unsubscribe from backend\n this.collectionSubscriptions.delete(subscriptionKey);\n this.backendToCollectionKey.delete(existingSubscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: existingSubscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n };\n }\n\n // Create new subscription\n const backendSubscriptionId = `collection_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const callbackMap = new Map<string, {\n onUpdate: (rows: Record<string, unknown>[]) => void;\n onError?: (error: Error) => void;\n }>();\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n this.collectionSubscriptions.set(subscriptionKey, {\n backendSubscriptionId,\n callbacks: callbackMap,\n props\n });\n\n // Add reverse lookup\n this.backendToCollectionKey.set(backendSubscriptionId, subscriptionKey);\n\n // Send subscription request to backend\n this.sendMessage({\n type: \"subscribe_collection\",\n payload: {\n ...props,\n subscriptionId: backendSubscriptionId\n }\n }).catch(error => {\n if (onError) onError(error);\n });\n\n // Return unsubscribe function\n return () => {\n const subscription = this.collectionSubscriptions.get(subscriptionKey);\n if (subscription) {\n const callbacks = subscription.callbacks;\n callbacks.delete(callbackId);\n if (callbacks.size === 0) {\n this.collectionSubscriptions.delete(subscriptionKey);\n this.backendToCollectionKey.delete(subscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: subscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n }\n };\n }\n\n listenOne<M extends Record<string, unknown>>(\n props: FetchOneProps<M>,\n onUpdate: (row: Record<string, unknown> | null) => void,\n onError?: (error: Error) => void\n ): () => void {\n const subscriptionKey = this.createSingleSubscriptionKey(props);\n const callbackId = `callback_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n // Check if we already have a subscription for these exact parameters\n const existingSubscription = this.singleSubscriptions.get(subscriptionKey);\n\n if (existingSubscription) {\n // Reuse existing subscription - just add the new callback\n const callbackMap = existingSubscription.callbacks as Map<string, {\n onUpdate: (row: Record<string, unknown> | null) => void;\n onError?: (error: Error) => void;\n }>;\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n // Immediately fire the callback with cached data if available\n if (existingSubscription.latestData !== undefined && existingSubscription.isInitialDataReceived) {\n try {\n onUpdate(existingSubscription.latestData);\n } catch (error) {\n console.error(\"Error in row subscription callback:\", error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n }\n\n // Return unsubscribe function\n return () => {\n callbackMap.delete(callbackId);\n if (callbackMap.size === 0) {\n // No more callbacks, unsubscribe from backend\n this.singleSubscriptions.delete(subscriptionKey);\n this.backendToEntityKey.delete(existingSubscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: existingSubscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n };\n }\n\n // Create new subscription\n const backendSubscriptionId = `entity_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const callbackMap = new Map<string, {\n onUpdate: (row: Record<string, unknown> | null) => void;\n onError?: (error: Error) => void;\n }>();\n callbackMap.set(callbackId, { onUpdate,\nonError });\n\n this.singleSubscriptions.set(subscriptionKey, {\n backendSubscriptionId,\n callbacks: callbackMap,\n props\n });\n\n // Add reverse lookup\n this.backendToEntityKey.set(backendSubscriptionId, subscriptionKey);\n\n // Send subscription request to backend\n this.sendMessage({\n type: \"subscribe_one\",\n payload: {\n ...props,\n subscriptionId: backendSubscriptionId\n }\n }).catch(error => {\n if (onError) onError(error);\n });\n\n // Return unsubscribe function\n return () => {\n const subscription = this.singleSubscriptions.get(subscriptionKey);\n if (subscription) {\n const callbacks = subscription.callbacks;\n callbacks.delete(callbackId);\n if (callbacks.size === 0) {\n this.singleSubscriptions.delete(subscriptionKey);\n this.backendToEntityKey.delete(subscription.backendSubscriptionId);\n if (this.isConnected && this.ws) {\n this.sendMessage({\n type: \"unsubscribe\",\n payload: { subscriptionId: subscription.backendSubscriptionId }\n }).catch(console.error);\n }\n }\n }\n };\n }\n\n /**\n * Re-send all active subscriptions to the backend after a reconnect.\n * The server wipes subscription state when a client disconnects, so\n * we need to re-register everything to resume receiving updates.\n */\n private resubscribeAll(): void {\n console.debug(`[WS] Re-subscribing: ${this.collectionSubscriptions.size} collection(s), ${this.singleSubscriptions.size} row(ies)`);\n\n // Re-subscribe collection subscriptions\n for (const [key, sub] of this.collectionSubscriptions.entries()) {\n // Generate a fresh backend ID since the old one is no longer valid on the server\n const oldBackendId = sub.backendSubscriptionId;\n const newBackendId = `collection_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n sub.backendSubscriptionId = newBackendId;\n\n // Update reverse lookup\n this.backendToCollectionKey.delete(oldBackendId);\n this.backendToCollectionKey.set(newBackendId, key);\n\n this.sendMessage({\n type: \"subscribe_collection\",\n payload: {\n ...sub.props,\n subscriptionId: newBackendId\n }\n }).catch(error => {\n console.error(\"[WS] Failed to re-subscribe collection:\", key, error);\n });\n }\n\n // Re-subscribe row subscriptions\n for (const [key, sub] of this.singleSubscriptions.entries()) {\n const oldBackendId = sub.backendSubscriptionId;\n const newBackendId = `entity_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n sub.backendSubscriptionId = newBackendId;\n\n this.backendToEntityKey.delete(oldBackendId);\n this.backendToEntityKey.set(newBackendId, key);\n\n this.sendMessage({\n type: \"subscribe_one\",\n payload: {\n ...sub.props,\n subscriptionId: newBackendId\n }\n }).catch(error => {\n console.error(\"[WS] Failed to re-subscribe row:\", key, error);\n });\n }\n }\n\n private createCollectionSubscriptionKey(props: FetchCollectionProps): string {\n // Create a deterministic key based on subscription parameters\n const key = {\n path: props.path,\n filter: props.filter,\n limit: props.limit,\n startAfter: props.startAfter,\n orderBy: props.orderBy,\n order: props.order,\n searchString: props.searchString,\n collection: props.collection?.name\n };\n // Use replacer function (not array) to sort keys at all levels for deterministic output\n return JSON.stringify(key, (_, value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value).sort().reduce((sorted: Record<string, unknown>, k) => {\n sorted[k] = value[k];\n return sorted;\n }, {});\n }\n return value;\n });\n }\n\n private createSingleSubscriptionKey(props: FetchOneProps): string {\n return `${props.path}|${props.id}`;\n }\n}\n","import { createTransport, RebaseClientConfig } from \"./transport\";\nimport { RebaseClientError } from \"./errors\";\nimport { createAuth, CreateAuthOptions } from \"./auth\";\nimport { createAdmin, CreateAdminOptions } from \"./admin\";\nimport { createCron, CreateCronOptions } from \"./cron\";\nimport { createApiKeys, CreateApiKeysOptions } from \"./api-keys\";\nimport { CollectionClient, createCollectionClient } from \"./collection\";\nimport { createFunctionsClient } from \"./functions\";\nimport { createStorage } from \"./storage\";\nimport { ClientStorageSourceRegistry } from \"./storage-registry\";\nimport { RebaseWebSocketClient } from \"./websocket\";\nimport {\n DEFAULT_STORAGE_SOURCE_KEY,\n InsertOf,\n RebaseClient,\n RebaseSdkData,\n RowOf,\n StorageSource,\n StorageSourceDefinition,\n StorageSourceRegistry,\n UpdateOf\n} from \"@rebasepro/types\";\nimport { toSnakeCase } from \"@rebasepro/utils\";\n\n// ─── Public API surface ──────────────────────────────────────────────────────\n//\n// This barrel is the public API of `@rebasepro/client`. It is an explicit,\n// curated list — NOT `export *` — so that adding an export to a module below\n// does not silently republish it to app developers. Internal factories\n// (`createTransport`, `createAuth`, `createCollectionClient`, …), the raw\n// `Transport`, the storage-source registry impl, the JSON reviver, and the\n// concrete `SDKQueryBuilder` class are intentionally NOT re-exported: they are\n// implementation details of `createRebaseClient()` and have no external\n// consumers. App developers reach them through the client instance, never by\n// importing the factory. To add something to the public surface, add it here\n// deliberately.\n\n// Errors — the single error type thrown by SDK HTTP calls, plus the\n// data-proxy's unknown-collection error.\nexport { RebaseApiError } from \"./transport\";\nexport { RebaseClientError } from \"./errors\";\n\n// Query + collection types (annotate SDK results; construct via the fluent API).\nexport type { RebaseClientConfig, FindParams, FindResponse } from \"./transport\";\nexport type { CollectionClient } from \"./collection\";\nexport type { FindResult, SDKCollectionClient, SDKQueryBuilderInterface, PaginationMeta } from \"@rebasepro/types\";\n\n// Logical-condition helpers for `.where(or(...), and(...))`.\nexport { QueryBuilder, or, and, cond } from \"@rebasepro/common\";\n\n// Auth: session/token types, config, and the pluggable storage strategies.\nexport { createCookieStorage, createMemoryStorage } from \"./auth\";\nexport type { AuthConfig, AuthStorage, CookieStorageOptions, CreateAuthOptions } from \"./auth\";\nexport type { RebaseSession, AuthTokens, AuthChangeEvent, DeviceSession } from \"@rebasepro/types\";\n/** @deprecated Import `User` / `AuthTokens` from `@rebasepro/types` instead. */\nexport type { RebaseUser, RebaseTokens } from \"./auth\";\n\n// Control-plane client option/DTO types (the client instance exposes the impls).\nexport type { CreateAdminOptions } from \"./admin\";\nexport type { AdminUser } from \"./admin\";\nexport type { CreateCronOptions } from \"./cron\";\nexport type {\n ApiKeyMasked,\n ApiKeyPermission,\n ApiKeyWithSecret,\n CreateApiKeyRequest,\n CreateApiKeysOptions,\n UpdateApiKeyRequest\n} from \"./api-keys\";\nexport type { FunctionInvokeOptions, FunctionsClient } from \"./functions\";\n\n// Realtime: the WebSocket client class is internal to `createRebaseClient()`,\n// but re-exported (see @internal on the class) because the `client-postgresql`\n// driver constructs it directly. Not a stable app-facing API.\nexport { RebaseWebSocketClient } from \"./websocket\";\n\nexport interface CreateRebaseClientOptions extends RebaseClientConfig {\n auth?: CreateAuthOptions;\n admin?: CreateAdminOptions;\n cron?: CreateCronOptions;\n apiKeys?: CreateApiKeysOptions;\n /**\n * Declared storage sources for multi-backend support. Server-transport\n * entries are auto-wired into `client.storageRegistry`; `direct` sources\n * are registered app-side (e.g. via a Firebase Storage hook). The default\n * source (`storage`) is always registered under\n * {@link DEFAULT_STORAGE_SOURCE_KEY}.\n */\n storageSources?: StorageSourceDefinition[];\n /**\n * Maps camelCase property names / safe identifiers to the actual\n * collection slugs on the server (e.g. `{ companyMembers: \"company-members\" }`).\n * If provided, the data layer proxy will resolve property accessors to their\n * correct slugs via this map before falling back to automatic snake_casing.\n */\n collections?: Record<string, string>;\n}\n\n// ─── Typed Data Proxy ────────────────────────────────────────────────────────\n// Adds typed collection accessors when `DB` is provided via the SDK generator.\n\ntype KebabToCamelCase<S extends string> =\n S extends `${infer T}-${infer U}`\n ? `${T}${Capitalize<KebabToCamelCase<U>>}`\n : S;\n\n// Resolve a generated `Database` entry from a (kebab-case) slug literal,\n// or `unknown` when the slug isn't in the schema — the extractors below\n// then fall back to the open row / partial shapes.\ntype DBEntry<DB, S extends string> =\n KebabToCamelCase<S> extends keyof DB ? DB[KebabToCamelCase<S>] : unknown;\n\ntype TypedDataLayer<DB> = {\n collection<S extends string>(slug: S): CollectionClient<\n RowOf<DBEntry<DB, S>>,\n InsertOf<DBEntry<DB, S>>,\n UpdateOf<DBEntry<DB, S>>\n >;\n} & {\n [K in keyof DB]: CollectionClient<RowOf<DB[K]>, InsertOf<DB[K]>, UpdateOf<DB[K]>>;\n} & RebaseSdkData;\n\n/**\n * The return type of `createRebaseClient<DB>()`.\n *\n * This is `RebaseClient` (from `@rebasepro/types`) with all optional\n * capabilities populated and the `data` layer narrowed to provide\n * typed collection accessors when a `DB` schema generic is supplied.\n */\nexport type CreateRebaseClientResult<DB = Record<string, unknown>> = Omit<RebaseClient<DB>, \"data\" | \"email\"> & {\n setToken: (token: string | null) => void;\n setAuthTokenGetter: (getter: () => Promise<string | null>) => void;\n setOnUnauthorized: (handler: () => Promise<boolean>) => void;\n resolveToken: () => Promise<string | null>;\n auth: ReturnType<typeof createAuth>;\n admin: ReturnType<typeof createAdmin>;\n cron: ReturnType<typeof createCron>;\n apiKeys: ReturnType<typeof createApiKeys>;\n functions: ReturnType<typeof createFunctionsClient>;\n ws?: RebaseWebSocketClient;\n storage: StorageSource;\n storageRegistry: StorageSourceRegistry;\n createStorageSource: (storageId: string) => StorageSource;\n fetchStorageSources: () => Promise<StorageSourceDefinition[]>;\n call: <T = unknown>(endpoint: string, payload?: unknown) => Promise<T>;\n data: TypedDataLayer<DB>;\n};\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\n/**\n * Derive a WebSocket URL from an HTTP base URL.\n * `http://` → `ws://`, `https://` → `wss://`.\n */\nfunction deriveWebSocketUrl(baseUrl?: string): string {\n if (typeof window !== \"undefined\") {\n let absoluteUrl = \"\";\n if (!baseUrl) {\n absoluteUrl = window.location.origin;\n } else if (/^https?:\\/\\//i.test(baseUrl) || /^wss?:\\/\\//i.test(baseUrl)) {\n absoluteUrl = baseUrl;\n } else {\n try {\n absoluteUrl = new URL(baseUrl, window.location.href).origin;\n } catch {\n absoluteUrl = window.location.origin;\n }\n }\n const protocol = absoluteUrl.startsWith(\"https:\") || absoluteUrl.startsWith(\"wss:\") ? \"wss:\" : \"ws:\";\n return absoluteUrl\n .replace(/^https?:\\/\\//i, `${protocol}//`)\n .replace(/^wss?:\\/\\//i, `${protocol}//`)\n .replace(/\\/$/, \"\");\n }\n\n if (!baseUrl) return \"\";\n if (!/^https?:\\/\\//i.test(baseUrl) && !/^wss?:\\/\\//i.test(baseUrl)) {\n return \"\";\n }\n return baseUrl\n .replace(/^https?:\\/\\//i, (match) => match.toLowerCase() === \"https://\" ? \"wss://\" : \"ws://\")\n .replace(/\\/$/, \"\");\n}\n\nexport function createRebaseClient<DB = Record<string, unknown>>(options: CreateRebaseClientOptions): CreateRebaseClientResult<DB> {\n const transport = createTransport(options);\n const auth = createAuth(transport, options.auth);\n const admin = createAdmin(transport, options.admin);\n const cron = createCron(transport, options.cron);\n const apiKeys = createApiKeys(transport, options.apiKeys);\n const storage = createStorage(transport);\n const functions = createFunctionsClient(transport);\n\n // Build a server-backed StorageSource for a given storage-source key.\n const createStorageSource = (storageId: string): StorageSource =>\n storageId === DEFAULT_STORAGE_SOURCE_KEY ? storage : createStorage(transport, storageId);\n\n // Storage registry: always holds the default source, plus any declared\n // server-transport sources. `direct` sources are registered app-side.\n const storageRegistry = new ClientStorageSourceRegistry();\n storageRegistry.register(DEFAULT_STORAGE_SOURCE_KEY, storage);\n for (const def of options.storageSources ?? []) {\n if (def.transport === \"server\" && def.key !== DEFAULT_STORAGE_SOURCE_KEY) {\n storageRegistry.register(def.key, createStorageSource(def.key));\n }\n }\n\n // Discover storage sources from the backend, making the server the single\n // source of truth. Server-transport sources are auto-wired into the\n // registry; `direct` sources are returned for the app to register. The\n // promise is cached on success and reset on failure so it can be retried\n // (e.g. once the user authenticates).\n let storageSourcesPromise: Promise<StorageSourceDefinition[]> | undefined;\n const fetchStorageSources = (): Promise<StorageSourceDefinition[]> => {\n if (storageSourcesPromise) return storageSourcesPromise;\n storageSourcesPromise = transport\n .request<{ data: StorageSourceDefinition[] }>(\"/storage/sources\")\n .then((res) => {\n const defs = res.data ?? [];\n for (const def of defs) {\n if (def.transport === \"server\"\n && def.key !== DEFAULT_STORAGE_SOURCE_KEY\n && !storageRegistry.has(def.key)) {\n storageRegistry.register(def.key, createStorageSource(def.key));\n }\n }\n return defs;\n })\n .catch((e) => {\n storageSourcesPromise = undefined; // allow retry\n throw e;\n });\n return storageSourcesPromise;\n };\n\n const resolvedWsUrl = options.websocketUrl ?? deriveWebSocketUrl(options.baseUrl);\n\n let ws: RebaseWebSocketClient | undefined;\n if (resolvedWsUrl) {\n const wsOnUnauthorized = options.onUnauthorized || (async () => {\n try {\n await auth.refreshSession();\n return true;\n } catch (e) {\n return false;\n }\n });\n\n ws = new RebaseWebSocketClient({\n websocketUrl: resolvedWsUrl,\n getAuthToken: async () => {\n let session = auth.getSession();\n if (session && session.expiresAt <= Date.now() + 10000) {\n try {\n session = await auth.refreshSession();\n } catch (e) { /* ignore */ }\n }\n return session?.accessToken || options.token || \"\";\n },\n onUnauthorized: wsOnUnauthorized\n });\n\n auth.onAuthStateChange((event, session) => {\n if (!ws) return;\n if (event === \"SIGNED_OUT\") {\n ws.disconnect();\n } else if (event === \"SIGNED_IN\" || event === \"TOKEN_REFRESHED\") {\n if (session?.accessToken) {\n ws.authenticate(session.accessToken).catch(console.warn);\n }\n }\n });\n }\n\n // Register transport callback for 401s after auth is instantiated.\n // IMPORTANT: We must use transport.setOnUnauthorized() here — NOT set\n // options.onUnauthorized — because the transport was already created above\n // and captured the (undefined) value from the config closure.\n if (!options.onUnauthorized) {\n transport.setOnUnauthorized(async () => {\n try {\n await auth.refreshSession();\n return true;\n } catch (e) {\n return false;\n }\n });\n }\n\n /**\n * Suggest the closest known collection key for a mistyped accessor.\n * Uses edit-distance-1 and prefix matching — no external dependency.\n */\n function suggestCollection(prop: string, knownKeys: string[]): string | undefined {\n // Prefix match (e.g. \"prod\" → \"products\")\n const prefixMatch = knownKeys.find(k => k.startsWith(prop) || prop.startsWith(k));\n if (prefixMatch) return prefixMatch;\n\n // Edit-distance-1: deletions, insertions, substitutions, transpositions\n for (const key of knownKeys) {\n if (Math.abs(key.length - prop.length) > 1) continue;\n let diffs = 0;\n const longer = key.length >= prop.length ? key : prop;\n const shorter = key.length >= prop.length ? prop : key;\n if (longer.length === shorter.length) {\n // Same length: allow 1 substitution or 1 transposition\n for (let i = 0; i < longer.length; i++) {\n if (longer[i] !== shorter[i]) {\n // Check for transposition\n if (\n i + 1 < longer.length &&\n longer[i] === shorter[i + 1] &&\n longer[i + 1] === shorter[i]\n ) {\n diffs++;\n i++; // skip next char (already accounted for)\n if (diffs > 1) break;\n continue;\n }\n diffs++;\n }\n if (diffs > 1) break;\n }\n } else {\n // Length differs by 1: allow 1 insertion/deletion\n let li = 0;\n let si = 0;\n while (li < longer.length) {\n if (si < shorter.length && longer[li] === shorter[si]) {\n si++;\n } else {\n diffs++;\n }\n li++;\n if (diffs > 1) break;\n }\n }\n if (diffs <= 1) return key;\n }\n\n return undefined;\n }\n\n const collectionClients = new Map<string, CollectionClient<Record<string, unknown>>>();\n let untypedWarned = false;\n\n function collection(slug: string): CollectionClient<Record<string, unknown>> {\n if (!collectionClients.has(slug)) {\n collectionClients.set(slug, createCollectionClient(transport, slug, ws));\n }\n return collectionClients.get(slug)!;\n }\n\n const dataTarget = { collection } as Record<string, unknown>;\n\n const dataProxy = new Proxy(dataTarget, {\n get(_target, prop: string | symbol) {\n if (prop === \"collection\") {\n return collection;\n }\n if (typeof prop === \"symbol\") return undefined;\n if (typeof prop === \"string\" && prop !== \"then\" && prop !== \"toJSON\" && prop !== \"$$typeof\") {\n if (options.collections) {\n if (prop in options.collections) {\n return collection(options.collections[prop]);\n }\n // Strict mode: the developer supplied a typed dictionary,\n // so we know the full set of valid accessors.\n const knownKeys = Object.keys(options.collections);\n const suggestion = suggestCollection(prop, knownKeys);\n const knownList = knownKeys.join(\", \");\n let msg = `Unknown collection accessor \"${prop}\". Known collections: ${knownList}.`;\n if (suggestion) msg += ` Did you mean \"${suggestion}\"?`;\n msg += ` Use data.collection(\"<slug>\") for dynamic slugs.`;\n throw new RebaseClientError(msg);\n }\n // Untyped fallback: convert camelCase property names to snake_case slugs.\n // e.g. `companyMembers` → `company_members`\n if (!untypedWarned) {\n untypedWarned = true;\n console.warn(\n `[Rebase] Untyped data access detected (client.data.${prop}). ` +\n `Collection names are resolved via snake_case conversion, which may cause silent 404s at request time. ` +\n `Pass a \\`collections\\` dictionary to createRebaseClient() or use the generated SDK for type-safe access.`\n );\n }\n const slug = toSnakeCase(prop);\n return collection(slug);\n }\n return undefined;\n }\n });\n\n const target = {\n auth,\n admin,\n cron,\n apiKeys,\n functions,\n storage,\n storageRegistry,\n createStorageSource,\n fetchStorageSources,\n ws,\n setToken: transport.setToken,\n setAuthTokenGetter: transport.setAuthTokenGetter,\n setOnUnauthorized: transport.setOnUnauthorized,\n resolveToken: transport.resolveToken,\n baseUrl: transport.baseUrl,\n collection,\n call: async <T = unknown>(endpoint: string, payload?: unknown): Promise<T> => {\n const prefix = endpoint.startsWith(\"/\") ? \"\" : \"/\";\n const res = await transport.request<{ data: T }>(`${prefix}${endpoint}`, {\n method: \"POST\",\n body: payload ? JSON.stringify(payload) : undefined\n });\n return res.data ?? (res as T);\n },\n data: dataProxy,\n } as unknown as CreateRebaseClientResult<DB>;\n\n return target;\n}\n\n"],"mappings":"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"}
|