import { createDemoSessionAdapter, createExternalAuthSessionAdapter, createUnavailableSessionAdapter, } from "../adapters/auth/external-session-adapter.js"; import { createHttpClient } from "../adapters/http/client.js"; import { createQueryCacheAdapter, createQueryClient, } from "../adapters/query-cache/tanstack-query-cache.js"; import { createBrowserStorageAdapter } from "../adapters/storage/browser-storage-adapter.js"; import { createTelemetryAdapter } from "../adapters/telemetry/best-effort-telemetry.js"; /** * @param {Record} host * @returns {Parameters[0] | null} */ function externalOwnerFrom(host) { const candidate = host.__CA_FRONTEND_AUTH_OWNER__; if (!candidate || typeof candidate !== "object") return null; const owner = /** @type {Record} */ (candidate); const required = [ "readState", "subscribe", "beginSignIn", "signOut", "attachCredential", "recoverSession", "notifyUnauthenticated", ]; return required.every((name) => typeof owner[name] === "function") ? /** @type {Parameters[0]} */ ( candidate ) : null; } /** @param {unknown} value */ function storageOrUndefined(value) { return typeof Storage !== "undefined" && value instanceof Storage ? value : undefined; } /** * @param {{ * runtime: Awaited>, * release: Awaited>, * host?: Record, * fetcher?: typeof fetch * }} context */ export async function createRuntimeAdapters(context) { const host = context.host ?? /** @type {Record} */ (globalThis); const config = context.runtime.config; const externalOwner = externalOwnerFrom(host); const authSession = config.AUTH_MODE === "demo" ? createDemoSessionAdapter() : externalOwner ? createExternalAuthSessionAdapter(externalOwner) : createUnavailableSessionAdapter(); const queryClient = createQueryClient(); const cache = createQueryCacheAdapter(queryClient); const storage = createBrowserStorageAdapter({ localStorage: storageOrUndefined(host.localStorage), sessionStorage: storageOrUndefined(host.sessionStorage), }); const telemetry = createTelemetryAdapter({ enabled: config.TELEMETRY_ENABLED, endpoint: config.TELEMETRY_ENDPOINT, fetcher: context.fetcher, }); const http = createHttpClient({ baseUrl: config.API_BASE_URL, authSession, fetcher: context.fetcher, }); const releaseInfo = Object.freeze({ async getCurrent() { return structuredClone(context.release); }, }); return Object.freeze({ authSession, cache, http, queryClient, releaseInfo, storage, telemetry, }); }