@basictech/react 0.7.0 → 0.8.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/sync/syncProtocol.js","../src/AuthContext.tsx","../src/sync/index.ts","../src/core/db/types.ts","../src/core/db/RemoteCollection.ts","../src/core/db/RemoteDB.ts","../package.json","../src/updater/versionUpdater.ts","../src/updater/updateMigrations.ts","../src/utils/storage.ts","../src/utils/network.ts","../src/utils/schema.ts","../src/index.ts"],"sourcesContent":["\nexport const SERVER_URL = \"https://api.basic.tech\"\n// export const SERVER_URL = \"http://localhost:3003\"\n\n\nexport const log = (...args: any[]) => {\n try { \n if (localStorage.getItem('basic_debug') === 'true') {\n console.log('[basic]', ...args)\n }\n } catch (e) {\n // console.log('error logging', e)\n }\n}\n\n// export const log = (message: string, ...args: any[]) => {\n// try {\n// if (process.env.NODE_ENV === 'development') {\n// const stack = new Error().stack;\n// const caller = stack?.split('\\n')[2]?.trim();\n// console.log(`[basic] ${message}`, ...args);\n// // console.log(`[stack] ${caller}`);\n// }\n// } catch (e) {\n// console.error('Error in logWithStack:', e);\n// }\n// }\n","\"use client\"\nimport { Dexie } from \"dexie\";\nimport { log } from \"../config\";\n\nexport const syncProtocol = function () {\n log(\"Initializing syncProtocol\");\n // Constants:\n var RECONNECT_DELAY = 5000; // Reconnect delay in case of errors such as network down.\n\n Dexie.Syncable.registerSyncProtocol(\"websocket\", {\n sync: function (\n context,\n url,\n options,\n baseRevision,\n syncedRevision,\n changes,\n partial,\n applyRemoteChanges,\n onChangesAccepted,\n onSuccess,\n onError,\n ) {\n // The following vars are needed because we must know which callback to ack when server sends it's ack to us.\n var requestId = 0;\n var acceptCallbacks = {};\n\n // Connect the WebSocket to given url:\n log(\"Connecting to\", url)\n var ws = new WebSocket(url);\n\n // console.log(\"ws OPTIONS\", options);\n\n // sendChanges() method:\n function sendChanges(changes, baseRevision, partial, onChangesAccepted) {\n log(\"sendChanges\", changes.length, baseRevision);\n ++requestId;\n acceptCallbacks[requestId.toString()] = onChangesAccepted;\n\n // In this example, the server expects the following JSON format of the request:\n // {\n // type: \"changes\"\n // baseRevision: baseRevision,\n // changes: changes,\n // partial: partial,\n // requestId: id\n // }\n // To make the sample simplified, we assume the server has the exact same specification of how changes are structured.\n // In real world, you would have to pre-process the changes array to fit the server specification.\n // However, this example shows how to deal with the WebSocket to fullfill the API.\n\n ws.send(\n JSON.stringify({\n type: \"changes\",\n changes: changes,\n partial: partial,\n baseRevision: baseRevision,\n requestId: requestId,\n }),\n );\n }\n\n\n\n // When WebSocket opens, send our changes to the server.\n ws.onopen = function (event) {\n // Initiate this socket connection by sending our clientIdentity. If we dont have a clientIdentity yet,\n // server will call back with a new client identity that we should use in future WebSocket connections.\n \n // send the schema to the server\n log(\"Opening socket - sending clientIdentity\", context.clientIdentity);\n ws.send(\n JSON.stringify({\n type: \"clientIdentity\",\n clientIdentity: context.clientIdentity || null,\n authToken: options.authToken,\n schema: options.schema\n }),\n );\n\n };\n\n // If network down or other error, tell the framework to reconnect again in some time:\n ws.onerror = function (event) {\n ws.close();\n log(\"ws.onerror\", event);\n onError(event?.message, RECONNECT_DELAY);\n };\n\n // If socket is closed (network disconnected), inform framework and make it reconnect\n ws.onclose = function (event) {\n // console.log('🙅 ws.onclose', event)\n onError(\"Socket closed: \" + event.reason, RECONNECT_DELAY);\n };\n\n // isFirstRound: Will need to call onSuccess() only when we are in sync the first time.\n // onSuccess() will unblock Dexie to be used by application code.\n // If for example app code writes: db.friends.where('shoeSize').above(40).toArray(callback), the execution of that query\n // will not run until we have called onSuccess(). This is because we want application code to get results that are as\n // accurate as possible. Specifically when connected the first time and the entire DB is being synced down to the browser,\n // it is important that queries starts running first when db is in sync.\n var isFirstRound = true;\n // When message arrive from the server, deal with the message accordingly:\n ws.onmessage = function (event) {\n try {\n // Assume we have a server that should send JSON messages of the following format:\n // {\n // type: \"clientIdentity\", \"changes\", \"ack\" or \"error\"\n // clientIdentity: unique value for our database client node to persist in the context. (Only applicable if type=\"clientIdentity\")\n // message: Error message (Only applicable if type=\"error\")\n // requestId: ID of change request that is acked by the server (Only applicable if type=\"ack\" or \"error\")\n // changes: changes from server (Only applicable if type=\"changes\")\n // lastRevision: last revision of changes sent (applicable if type=\"changes\")\n // partial: true if server has additionalChanges to send. False if these changes were the last known. (applicable if type=\"changes\")\n // }\n var requestFromServer = JSON.parse(event.data);\n log(\"requestFromServer\", requestFromServer, { acceptCallback, isFirstRound });\n\n if (requestFromServer.type == \"clientIdentity\") {\n context.clientIdentity = requestFromServer.clientIdentity;\n context.save();\n\n sendChanges(changes, baseRevision, partial, onChangesAccepted);\n\n ws.send(\n JSON.stringify({\n type: \"subscribe\",\n syncedRevision: syncedRevision,\n }),\n );\n } else if (requestFromServer.type == \"changes\") {\n applyRemoteChanges(\n requestFromServer.changes,\n requestFromServer.currentRevision,\n requestFromServer.partial,\n );\n if (isFirstRound && !requestFromServer.partial) {\n // Since this is the first sync round and server sais we've got all changes - now is the time to call onsuccess()\n onSuccess({\n // Specify a react function that will react on additional client changes\n react: function (\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n ) {\n sendChanges(\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n );\n },\n // Specify a disconnect function that will close our socket so that we dont continue to monitor changes.\n disconnect: function () {\n ws.close();\n },\n });\n isFirstRound = false;\n }\n } else if (requestFromServer.type == \"ack\") {\n var requestId = requestFromServer.requestId;\n var acceptCallback = acceptCallbacks[requestId.toString()];\n acceptCallback(); // Tell framework that server has acknowledged the changes sent.\n delete acceptCallbacks[requestId.toString()];\n } else if (requestFromServer.type == \"error\") {\n var requestId = requestFromServer.requestId;\n ws.close();\n onError(requestFromServer.message, Infinity); // Don't reconnect - an error in application level means we have done something wrong.\n } else {\n log(\"unknown message\", requestFromServer);\n ws.close();\n onError(\"unknown message\", Infinity);\n }\n } catch (e) {\n ws.close();\n log(\"caught error\", e)\n onError(e, Infinity); // Something went crazy. Server sends invalid format or our code is buggy. Dont reconnect - it would continue failing.\n }\n };\n },\n });\n};\n","import React, { createContext, useContext, useEffect, useState, useRef } from 'react'\nimport { jwtDecode } from 'jwt-decode'\n\nimport { BasicSync, initDexieExtensions } from './sync'\nimport { RemoteDB, DBMode, BasicDB } from './core/db'\n\nimport { log } from './config'\nimport { version as currentVersion } from '../package.json'\nimport { createVersionUpdater } from './updater/versionUpdater'\nimport { getMigrations } from './updater/updateMigrations'\nimport { BasicStorage, LocalStorageAdapter, STORAGE_KEYS, getCookie, setCookie, clearCookie } from './utils/storage'\nimport { isDevelopment, checkForNewVersion, cleanOAuthParamsFromUrl, getSyncStatus } from './utils/network'\nimport { getSchemaStatus, validateAndCheckSchema } from './utils/schema'\n\nexport type { BasicStorage, LocalStorageAdapter } from './utils/storage'\nexport type { DBMode, BasicDB, Collection } from './core/db'\n\nexport type AuthConfig = {\n scopes?: string | string[];\n server_url?: string;\n ws_url?: string;\n}\n\nexport type BasicProviderProps = {\n children: React.ReactNode;\n /** \n * @deprecated Project ID is now extracted from schema.project_id. \n * This prop is kept for backward compatibility but can be omitted.\n */\n project_id?: string;\n /** The Basic schema object containing project_id and table definitions */\n schema?: any;\n debug?: boolean;\n storage?: BasicStorage;\n auth?: AuthConfig;\n /**\n * Database mode - determines which implementation is used\n * - 'sync': Uses Dexie + WebSocket for local-first sync (default)\n * - 'remote': Uses REST API calls directly to server\n */\n dbMode?: DBMode;\n}\n\nconst DEFAULT_AUTH_CONFIG = {\n scopes: 'profile,email,app:admin',\n server_url: 'https://api.basic.tech',\n ws_url: 'wss://pds.basic.id/ws'\n} as const\n\n\ntype BasicSyncType = {\n basic_schema: any;\n connect: (options: { access_token: string; ws_url?: string }) => void;\n debugeroo: () => void;\n collection: (name: string) => {\n ref: {\n toArray: () => Promise<any[]>;\n count: () => Promise<number>;\n };\n };\n [key: string]: any;\n};\n\n\nenum DBStatus {\n LOADING = \"LOADING\",\n OFFLINE = \"OFFLINE\",\n CONNECTING = \"CONNECTING\",\n ONLINE = \"ONLINE\",\n SYNCING = \"SYNCING\",\n ERROR = \"ERROR\"\n}\n\ntype User = {\n name?: string,\n email?: string,\n id?: string,\n primaryEmailAddress?: {\n emailAddress: string\n },\n fullName?: string\n}\ntype Token = {\n access_token: string,\n token_type: string,\n expires_in: number,\n refresh_token: string,\n}\n\n/**\n * Auth result type for signInWithCode\n */\nexport type AuthResult = {\n success: boolean;\n error?: string;\n code?: string;\n}\n\n/**\n * Context type for useBasic hook\n */\nexport type BasicContextType = {\n // Auth state\n isReady: boolean;\n isSignedIn: boolean;\n user: User | null;\n \n // Auth actions (new camelCase naming)\n signIn: () => Promise<void>;\n signOut: () => Promise<void>;\n signInWithCode: (code: string, state?: string) => Promise<AuthResult>;\n \n // Token management\n getToken: () => Promise<string>;\n getSignInUrl: (redirectUri?: string) => Promise<string>;\n \n // DB access\n db: BasicDB;\n dbStatus: DBStatus;\n dbMode: DBMode;\n \n // Legacy aliases (deprecated - will be removed in future version)\n /** @deprecated Use isReady instead */\n isAuthReady: boolean;\n /** @deprecated Use signIn instead */\n signin: () => Promise<void>;\n /** @deprecated Use signOut instead */\n signout: () => Promise<void>;\n /** @deprecated Use signInWithCode instead */\n signinWithCode: (code: string, state?: string) => Promise<AuthResult>;\n /** @deprecated Use getSignInUrl instead */\n getSignInLink: (redirectUri?: string) => Promise<string>;\n}\n\nconst noDb: BasicDB = {\n collection: () => {\n throw new Error('no basicdb found - initialization failed. double check your schema.')\n }\n}\n\nexport const BasicContext = createContext<BasicContextType>({\n // Auth state\n isReady: false,\n isSignedIn: false,\n user: null,\n \n // Auth actions\n signIn: () => Promise.resolve(),\n signOut: () => Promise.resolve(),\n signInWithCode: () => Promise.resolve({ success: false }),\n \n // Token management\n getToken: () => Promise.reject(new Error('no token')),\n getSignInUrl: () => Promise.resolve(\"\"),\n \n // DB access\n db: noDb,\n dbStatus: DBStatus.LOADING,\n dbMode: 'sync',\n \n // Legacy aliases\n isAuthReady: false,\n signin: () => Promise.resolve(),\n signout: () => Promise.resolve(),\n signinWithCode: () => Promise.resolve({ success: false }),\n getSignInLink: () => Promise.resolve(\"\")\n});\n\ntype ErrorObject = {\n code: string;\n title: string;\n message: string;\n}\n\nexport function BasicProvider({\n children,\n project_id: project_id_prop,\n schema,\n debug = false,\n storage,\n auth,\n dbMode = 'sync'\n}: BasicProviderProps) {\n // Extract project_id from schema, fall back to prop for backward compatibility\n const project_id = schema?.project_id || project_id_prop\n \n const [isAuthReady, setIsAuthReady] = useState(false)\n const [isSignedIn, setIsSignedIn] = useState<boolean>(false)\n const [token, setToken] = useState<Token | null>(null)\n const [user, setUser] = useState<User>({})\n const [shouldConnect, setShouldConnect] = useState<boolean>(false)\n const [isReady, setIsReady] = useState<boolean>(false)\n\n const [dbStatus, setDbStatus] = useState<DBStatus>(DBStatus.OFFLINE)\n const [error, setError] = useState<ErrorObject | null>(null)\n const [isOnline, setIsOnline] = useState<boolean>(navigator.onLine)\n const [pendingRefresh, setPendingRefresh] = useState<boolean>(false)\n\n const syncRef = useRef<BasicSync | null>(null);\n const remoteDbRef = useRef<RemoteDB | null>(null);\n const storageAdapter = storage || new LocalStorageAdapter();\n \n // Merge auth config with defaults\n const authConfig = {\n scopes: auth?.scopes || DEFAULT_AUTH_CONFIG.scopes,\n server_url: auth?.server_url || DEFAULT_AUTH_CONFIG.server_url,\n ws_url: auth?.ws_url || DEFAULT_AUTH_CONFIG.ws_url\n }\n \n // Normalize scopes to space-separated string\n const scopesString = Array.isArray(authConfig.scopes) \n ? authConfig.scopes.join(' ') \n : authConfig.scopes;\n\n // Token refresh mutex to prevent concurrent refreshes\n const refreshPromiseRef = useRef<Promise<Token | null> | null>(null);\n\n const isDevMode = () => isDevelopment(debug)\n\n const cleanOAuthParams = () => cleanOAuthParamsFromUrl()\n\n useEffect(() => {\n const handleOnline = () => {\n log('Network came back online')\n setIsOnline(true)\n if (pendingRefresh) {\n log('Retrying pending token refresh')\n setPendingRefresh(false)\n if (token) {\n const refreshToken = token.refresh_token || localStorage.getItem('basic_refresh_token')\n if (refreshToken) {\n fetchToken(refreshToken, true).catch(error => {\n log('Retry refresh failed:', error)\n })\n }\n }\n }\n }\n\n const handleOffline = () => {\n log('Network went offline')\n setIsOnline(false)\n }\n\n window.addEventListener('online', handleOnline)\n window.addEventListener('offline', handleOffline)\n\n return () => {\n window.removeEventListener('online', handleOnline)\n window.removeEventListener('offline', handleOffline)\n }\n }, [pendingRefresh, token])\n\n useEffect(() => {\n async function initSyncDb(options: { shouldConnect: boolean }) {\n if (!syncRef.current) {\n log('Initializing Basic Sync DB')\n \n // Initialize Dexie extensions before creating BasicSync\n await initDexieExtensions()\n \n syncRef.current = new BasicSync('basicdb', { schema: schema });\n\n syncRef.current.syncable.on('statusChanged', (status: number, url: string) => {\n setDbStatus(getSyncStatus(status) as DBStatus)\n })\n\n if (options.shouldConnect) {\n setShouldConnect(true)\n } else {\n log('Sync is disabled')\n }\n\n setIsReady(true)\n }\n }\n\n function initRemoteDb() {\n if (!remoteDbRef.current) {\n if (!project_id) {\n setError({\n code: 'missing_project_id',\n title: 'Project ID Required',\n message: 'Remote mode requires a project_id. Provide it via schema.project_id or the project_id prop.'\n })\n setIsReady(true)\n return\n }\n\n log('Initializing Basic Remote DB')\n remoteDbRef.current = new RemoteDB({\n serverUrl: authConfig.server_url,\n projectId: project_id,\n getToken: getToken,\n schema: schema,\n debug: debug,\n onAuthError: (error) => {\n log('RemoteDB auth error:', error)\n // Sign out user when authentication fails after retry\n signout()\n }\n })\n setDbStatus(DBStatus.ONLINE)\n setIsReady(true)\n }\n }\n\n async function checkSchema() {\n const result = await validateAndCheckSchema(schema)\n\n if (!result.isValid) {\n let errorMessage = ''\n if (result.errors) {\n result.errors.forEach((error, index) => {\n errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}\\n`\n })\n }\n setError({\n code: 'schema_invalid',\n title: 'Basic Schema is invalid!',\n message: errorMessage\n })\n setIsReady(true)\n return null\n }\n\n // Initialize the appropriate DB based on mode\n if (dbMode === 'remote') {\n initRemoteDb()\n } else {\n // Sync mode\n if (result.schemaStatus.valid) {\n await initSyncDb({ shouldConnect: true })\n } else {\n log('Schema is invalid!', result.schemaStatus)\n await initSyncDb({ shouldConnect: false })\n }\n }\n\n checkForNewVersion()\n }\n\n if (schema) {\n checkSchema()\n } else {\n // No schema - still initialize remote DB if in remote mode\n if (dbMode === 'remote' && project_id) {\n initRemoteDb()\n } else {\n setIsReady(true)\n }\n }\n }, []);\n\n useEffect(() => {\n async function connectToDb() {\n if (token && syncRef.current && isSignedIn && shouldConnect) {\n const tok = await getToken()\n if (!tok) {\n log('no token found')\n return\n }\n\n log('connecting to db...')\n\n syncRef.current?.connect({ \n access_token: tok,\n ws_url: authConfig.ws_url \n })\n .catch((e) => {\n log('error connecting to db', e)\n })\n }\n }\n connectToDb()\n\n }, [isSignedIn, shouldConnect])\n\n useEffect(() => {\n const initializeAuth = async () => {\n await storageAdapter.set(STORAGE_KEYS.DEBUG, debug ? 'true' : 'false')\n\n // Check if server URL has changed - if so, clear tokens\n const storedServerUrl = await storageAdapter.get(STORAGE_KEYS.SERVER_URL)\n if (storedServerUrl && storedServerUrl !== authConfig.server_url) {\n log('Server URL changed, clearing stored tokens')\n await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN)\n await storageAdapter.remove(STORAGE_KEYS.USER_INFO)\n await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE)\n await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI)\n clearCookie('basic_token')\n clearCookie('basic_access_token')\n }\n await storageAdapter.set(STORAGE_KEYS.SERVER_URL, authConfig.server_url)\n\n try {\n const versionUpdater = createVersionUpdater(storageAdapter, currentVersion, getMigrations())\n const updateResult = await versionUpdater.checkAndUpdate()\n\n if (updateResult.updated) {\n log(`App updated from ${updateResult.fromVersion} to ${updateResult.toVersion}`)\n } else {\n log(`App version ${updateResult.toVersion} is current`)\n }\n } catch (error) {\n log('Version update failed:', error)\n }\n\n try {\n if (window.location.search.includes('code')) {\n let code = window.location?.search?.split('code=')[1]?.split('&')[0]\n if (!code) return\n\n const state = await storageAdapter.get(STORAGE_KEYS.AUTH_STATE)\n const urlState = window.location.search.split('state=')[1]?.split('&')[0]\n if (!state || state !== urlState) {\n log('error: auth state does not match')\n setIsAuthReady(true)\n\n await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE)\n cleanOAuthParams()\n return\n }\n\n await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE)\n cleanOAuthParams()\n\n fetchToken(code, false).catch((error) => {\n log('Error fetching token:', error)\n })\n } else {\n const refreshToken = await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n log('Found refresh token in storage, attempting to refresh access token')\n fetchToken(refreshToken, true).catch((error) => {\n log('Error fetching refresh token:', error)\n })\n } else {\n let cookie_token = getCookie('basic_token')\n if (cookie_token !== '') {\n const tokenData = JSON.parse(cookie_token)\n setToken(tokenData)\n if (tokenData.refresh_token) {\n await storageAdapter.set(STORAGE_KEYS.REFRESH_TOKEN, tokenData.refresh_token)\n }\n } else {\n const cachedUserInfo = await storageAdapter.get(STORAGE_KEYS.USER_INFO)\n if (cachedUserInfo) {\n try {\n const userData = JSON.parse(cachedUserInfo)\n setUser(userData)\n setIsSignedIn(true)\n log('Loaded cached user info for offline mode')\n } catch (error) {\n log('Error parsing cached user info:', error)\n }\n }\n setIsAuthReady(true)\n }\n }\n }\n\n } catch (e) {\n log('error getting token', e)\n }\n }\n\n initializeAuth()\n }, [])\n\n useEffect(() => {\n async function fetchUser(acc_token: string) {\n console.info('fetching user')\n try {\n const response = await fetch(`${authConfig.server_url}/auth/userInfo`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${acc_token}`\n }\n })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch user info: ${response.status}`)\n }\n\n const user = await response.json()\n\n if (user.error) {\n log('error fetching user', user.error)\n throw new Error(`User info error: ${user.error}`)\n }\n\n if (token?.refresh_token) {\n await storageAdapter.set(STORAGE_KEYS.REFRESH_TOKEN, token.refresh_token)\n }\n\n await storageAdapter.set(STORAGE_KEYS.USER_INFO, JSON.stringify(user))\n log('Cached user info in storage')\n\n setCookie('basic_access_token', token?.access_token || '', { httpOnly: false });\n setCookie('basic_token', JSON.stringify(token));\n\n setUser(user)\n setIsSignedIn(true)\n setIsAuthReady(true)\n } catch (error) {\n log('Failed to fetch user info:', error)\n // Don't clear tokens here - may be temporary network issue\n setIsAuthReady(true)\n }\n }\n\n async function checkToken() {\n if (!token) {\n log('error: no user token found')\n\n setIsAuthReady(true)\n return\n }\n\n const decoded = jwtDecode(token?.access_token)\n // Add 5 second buffer to prevent edge cases\n const expirationBuffer = 5\n const isExpired = decoded.exp && decoded.exp < (Date.now() / 1000) + expirationBuffer\n\n if (isExpired) {\n log('token is expired - refreshing ...')\n const refreshToken = token?.refresh_token\n if (!refreshToken) {\n log('Error: No refresh token available for expired token')\n setIsAuthReady(true)\n return\n }\n try {\n const newToken = await fetchToken(refreshToken, true)\n fetchUser(newToken?.access_token || '')\n } catch (error) {\n log('Failed to refresh token in checkToken:', error)\n\n if ((error as Error).message.includes('offline') || (error as Error).message.includes('Network')) {\n log('Network issue - continuing with expired token until online')\n fetchUser(token?.access_token || '')\n } else {\n setIsAuthReady(true)\n }\n }\n } else {\n fetchUser(token?.access_token || '')\n }\n }\n\n if (token) {\n checkToken()\n }\n }, [token])\n\n const getSignInLink = async (redirectUri?: string) => {\n try {\n log('getting sign in link...')\n\n if (!project_id) {\n throw new Error('Project ID is required to generate sign-in link')\n }\n\n const randomState = Math.random().toString(36).substring(6);\n await storageAdapter.set(STORAGE_KEYS.AUTH_STATE, randomState)\n\n const redirectUrl = redirectUri || window.location.href\n\n if (!redirectUrl || (!redirectUrl.startsWith('http://') && !redirectUrl.startsWith('https://'))) {\n throw new Error('Invalid redirect URI provided')\n }\n\n // Store redirect_uri for token exchange\n await storageAdapter.set(STORAGE_KEYS.REDIRECT_URI, redirectUrl)\n log('Stored redirect_uri for token exchange:', redirectUrl)\n\n let baseUrl = `${authConfig.server_url}/auth/authorize`\n baseUrl += `?client_id=${project_id}`\n baseUrl += `&redirect_uri=${encodeURIComponent(redirectUrl)}`\n baseUrl += `&response_type=code`\n baseUrl += `&scope=${encodeURIComponent(scopesString)}`\n baseUrl += `&state=${randomState}`\n\n log('Generated sign-in link successfully with scopes:', scopesString)\n return baseUrl;\n\n } catch (error) {\n log('Error generating sign-in link:', error)\n throw error\n }\n }\n\n const signin = async () => {\n try {\n log('signing in...')\n\n if (!project_id) {\n log('Error: project_id is required for sign-in')\n throw new Error('Project ID is required for authentication')\n }\n\n const signInLink = await getSignInLink()\n log('Generated sign-in link:', signInLink)\n\n // Validate URL format (supports https://, http://, and custom URI schemes)\n try {\n new URL(signInLink)\n } catch {\n log('Error: Invalid sign-in link generated')\n throw new Error('Failed to generate valid sign-in URL')\n }\n\n window.location.href = signInLink\n\n } catch (error) {\n log('Error during sign-in:', error)\n\n if (isDevMode()) {\n setError({\n code: 'signin_error',\n title: 'Sign-in Failed',\n message: (error as Error).message || 'An error occurred during sign-in. Please try again.'\n })\n }\n\n throw error\n }\n }\n\n const signinWithCode = async (code: string, state?: string): Promise<{ success: boolean, error?: string }> => {\n try {\n log('signinWithCode called with code:', code)\n\n if (!code || typeof code !== 'string') {\n return { success: false, error: 'Invalid authorization code' }\n }\n\n if (state) {\n const storedState = await storageAdapter.get(STORAGE_KEYS.AUTH_STATE)\n if (storedState && storedState !== state) {\n log('State parameter mismatch:', { provided: state, stored: storedState })\n return { success: false, error: 'State parameter mismatch' }\n }\n }\n\n await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE)\n cleanOAuthParams()\n\n const token = await fetchToken(code, false)\n\n if (token) {\n log('signinWithCode successful')\n return { success: true }\n } else {\n return { success: false, error: 'Failed to exchange code for token' }\n }\n } catch (error) {\n log('signinWithCode error:', error)\n return {\n success: false,\n error: (error as Error).message || 'Authentication failed'\n }\n }\n }\n\n const signout = async () => {\n log('signing out!')\n setUser({})\n setIsSignedIn(false)\n setToken(null)\n\n clearCookie('basic_token');\n clearCookie('basic_access_token');\n await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE)\n await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN)\n await storageAdapter.remove(STORAGE_KEYS.USER_INFO)\n await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI)\n await storageAdapter.remove(STORAGE_KEYS.SERVER_URL)\n if (syncRef.current) {\n (async () => {\n try {\n await syncRef.current?.close()\n await syncRef.current?.delete({ disableAutoOpen: false })\n syncRef.current = null\n window?.location?.reload()\n } catch (error) {\n console.error('Error during database cleanup:', error)\n }\n })()\n }\n }\n\n const getToken = async (): Promise<string> => {\n log('getting token...')\n\n if (!token) {\n // Try to recover from storage refresh token\n const refreshToken = await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n log('No token in memory, attempting to refresh from storage')\n \n // Check if refresh is already in progress\n if (refreshPromiseRef.current) {\n log('Token refresh already in progress, waiting...')\n try {\n const newToken = await refreshPromiseRef.current\n if (newToken?.access_token) {\n return newToken.access_token\n }\n } catch (error) {\n log('In-flight refresh failed:', error)\n throw error\n }\n }\n \n try {\n const newToken = await fetchToken(refreshToken, true)\n if (newToken?.access_token) {\n return newToken.access_token\n }\n } catch (error) {\n log('Failed to refresh token from storage:', error)\n\n if ((error as Error).message.includes('offline') || (error as Error).message.includes('Network')) {\n log('Network issue - continuing with potentially expired token')\n const lastToken = localStorage.getItem('basic_access_token')\n if (lastToken) {\n return lastToken\n }\n throw new Error('Network offline - authentication will be retried when online')\n }\n\n throw new Error('Authentication expired. Please sign in again.')\n }\n }\n log('no token found')\n throw new Error('no token found')\n }\n\n const decoded = jwtDecode(token?.access_token)\n // Add 5 second buffer to prevent edge cases where token expires during request\n const expirationBuffer = 5\n const isExpired = decoded.exp && decoded.exp < (Date.now() / 1000) + expirationBuffer\n\n if (isExpired) {\n log('token is expired - refreshing ...')\n \n // Check if refresh is already in progress\n if (refreshPromiseRef.current) {\n log('Token refresh already in progress, waiting...')\n try {\n const newToken = await refreshPromiseRef.current\n return newToken?.access_token || ''\n } catch (error) {\n log('In-flight refresh failed:', error)\n \n if ((error as Error).message.includes('offline') || (error as Error).message.includes('Network')) {\n log('Network issue - using expired token until network is restored')\n return token.access_token\n }\n \n throw error\n }\n }\n \n const refreshToken = token?.refresh_token || await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n try {\n const newToken = await fetchToken(refreshToken, true)\n return newToken?.access_token || ''\n } catch (error) {\n log('Failed to refresh expired token:', error)\n\n if ((error as Error).message.includes('offline') || (error as Error).message.includes('Network')) {\n log('Network issue - using expired token until network is restored')\n return token.access_token\n }\n\n throw new Error('Authentication expired. Please sign in again.')\n }\n } else {\n throw new Error('no refresh token available')\n }\n }\n\n return token?.access_token || ''\n }\n\n const fetchToken = async (codeOrRefreshToken: string, isRefreshToken: boolean = false): Promise<Token | null> => {\n // Validate input\n if (!codeOrRefreshToken || codeOrRefreshToken.trim() === '') {\n const errorMsg = isRefreshToken ? 'Refresh token is empty or undefined' : 'Authorization code is empty or undefined'\n log('Error:', errorMsg)\n throw new Error(errorMsg)\n }\n\n // If this is a refresh token request and one is already in progress, return that promise\n if (isRefreshToken && refreshPromiseRef.current) {\n log('Reusing in-flight refresh token request')\n return refreshPromiseRef.current\n }\n\n // Create new promise for this refresh attempt\n const refreshPromise = (async (): Promise<Token | null> => {\n try {\n if (!isOnline) {\n log('Network is offline, marking refresh as pending')\n setPendingRefresh(true)\n throw new Error('Network offline - refresh will be retried when online')\n }\n\n let requestBody: any\n\n if (isRefreshToken) {\n // Refresh token request\n requestBody = { \n grant_type: 'refresh_token',\n refresh_token: codeOrRefreshToken\n }\n // Include client_id if available for validation\n if (project_id) {\n requestBody.client_id = project_id\n }\n } else {\n // Authorization code exchange\n requestBody = { \n grant_type: 'authorization_code',\n code: codeOrRefreshToken\n }\n \n // Retrieve stored redirect_uri (required by OAuth2 spec)\n const storedRedirectUri = await storageAdapter.get(STORAGE_KEYS.REDIRECT_URI)\n if (storedRedirectUri) {\n requestBody.redirect_uri = storedRedirectUri\n log('Including redirect_uri in token exchange:', storedRedirectUri)\n } else {\n log('Warning: No redirect_uri found in storage for token exchange')\n }\n \n // Include client_id for validation\n if (project_id) {\n requestBody.client_id = project_id\n }\n }\n\n log('Token exchange request body:', { ...requestBody, refresh_token: isRefreshToken ? '[REDACTED]' : undefined, code: !isRefreshToken ? '[REDACTED]' : undefined })\n\n const token = await fetch(`${authConfig.server_url}/auth/token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestBody)\n })\n .then(response => response.json())\n .catch(error => {\n log('Network error fetching token:', error)\n if (!isOnline) {\n setPendingRefresh(true)\n throw new Error('Network offline - refresh will be retried when online')\n }\n throw new Error('Network error during token refresh')\n })\n\n if (token.error) {\n log('error fetching token', token.error)\n\n if (token.error.includes('network') || token.error.includes('timeout')) {\n setPendingRefresh(true)\n throw new Error('Network issue - refresh will be retried when online')\n }\n\n await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN)\n await storageAdapter.remove(STORAGE_KEYS.USER_INFO)\n await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI)\n await storageAdapter.remove(STORAGE_KEYS.SERVER_URL)\n clearCookie('basic_token');\n clearCookie('basic_access_token');\n\n setUser({})\n setIsSignedIn(false)\n setToken(null)\n setIsAuthReady(true)\n\n throw new Error(`Token refresh failed: ${token.error}`)\n } else {\n setToken(token)\n setPendingRefresh(false)\n\n if (token.refresh_token) {\n await storageAdapter.set(STORAGE_KEYS.REFRESH_TOKEN, token.refresh_token)\n log('Updated refresh token in storage')\n }\n\n // Clean up redirect_uri after successful token exchange\n if (!isRefreshToken) {\n await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI)\n log('Cleaned up redirect_uri from storage after successful exchange')\n }\n\n setCookie('basic_access_token', token.access_token, { httpOnly: false });\n setCookie('basic_token', JSON.stringify(token));\n log('Updated access token and full token in cookies')\n }\n return token\n } catch (error) {\n log('Token refresh error:', error)\n\n if (!(error as Error).message.includes('offline') && !(error as Error).message.includes('Network')) {\n await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN)\n await storageAdapter.remove(STORAGE_KEYS.USER_INFO)\n await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI)\n await storageAdapter.remove(STORAGE_KEYS.SERVER_URL)\n clearCookie('basic_token');\n clearCookie('basic_access_token');\n\n setUser({})\n setIsSignedIn(false)\n setToken(null)\n setIsAuthReady(true)\n }\n\n throw error\n }\n })()\n\n // Store promise if this is a refresh token request\n if (isRefreshToken) {\n refreshPromiseRef.current = refreshPromise\n \n // Clear the promise reference when done (success or failure)\n refreshPromise.finally(() => {\n if (refreshPromiseRef.current === refreshPromise) {\n refreshPromiseRef.current = null\n log('Cleared refresh promise reference')\n }\n })\n }\n\n return refreshPromise\n }\n\n // Get the current DB instance based on mode\n const getCurrentDb = (): BasicDB => {\n if (dbMode === 'remote') {\n return remoteDbRef.current || noDb\n }\n return syncRef.current || noDb\n }\n\n // Create context value with new names and legacy aliases\n const contextValue: BasicContextType = {\n // Auth state (new naming)\n isReady: isAuthReady,\n isSignedIn,\n user,\n \n // Auth actions (new camelCase naming)\n signIn: signin,\n signOut: signout,\n signInWithCode: signinWithCode,\n \n // Token management\n getToken,\n getSignInUrl: getSignInLink,\n \n // DB access\n db: getCurrentDb(),\n dbStatus,\n dbMode,\n \n // Legacy aliases (deprecated)\n isAuthReady,\n signin,\n signout,\n signinWithCode,\n getSignInLink,\n }\n\n return (\n <BasicContext.Provider value={contextValue}>\n {error && isDevMode() && <ErrorDisplay error={error} />}\n {isReady && children}\n </BasicContext.Provider>\n )\n}\n\nfunction ErrorDisplay({ error }: { error: ErrorObject }) {\n return <div style={{\n position: 'absolute',\n top: 20,\n left: 20,\n color: 'black',\n backgroundColor: '#f8d7da',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n padding: '20px',\n maxWidth: '400px',\n margin: '20px auto',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',\n fontFamily: 'monospace',\n }}>\n <h3 style={{ fontSize: '0.8rem', opacity: 0.8 }}>code: {error.code}</h3>\n <h1 style={{ fontSize: '1.2rem', lineHeight: '1.5' }}>{error.title}</h1>\n <p>{error.message}</p>\n </div>\n}\n\n\nexport function useBasic() {\n return useContext(BasicContext);\n}\n","\"use client\"\n\nimport { v7 as uuidv7 } from 'uuid';\nimport { Dexie } from 'dexie';\n\nimport { log } from '../config'\nimport { validateSchema, validateData } from '@basictech/schema'\n\n// Track initialization state\nlet dexieExtensionsLoaded = false;\nlet initPromise: Promise<void> | null = null;\n\n/**\n * Initialize Dexie extensions (syncable and observable)\n * This must be called before creating a BasicSync instance\n * Safe to call multiple times - will only load once\n */\nexport async function initDexieExtensions(): Promise<void> {\n // Return early if already loaded or not in browser\n if (dexieExtensionsLoaded) return;\n if (typeof window === 'undefined') return;\n \n // If already initializing, wait for that promise\n if (initPromise) return initPromise;\n \n initPromise = (async () => {\n try {\n // Dynamic imports - only loaded in browser\n await import('dexie-syncable');\n await import('dexie-observable');\n \n // Import and register sync protocol\n const { syncProtocol } = await import('./syncProtocol');\n syncProtocol();\n \n dexieExtensionsLoaded = true;\n log('Dexie extensions loaded successfully');\n } catch (error) {\n console.error('Failed to load Dexie extensions:', error);\n throw error;\n }\n })();\n \n return initPromise;\n}\n\n/**\n * Check if Dexie extensions are loaded\n */\nexport function isDexieReady(): boolean {\n return dexieExtensionsLoaded;\n}\n\n\nexport class BasicSync extends Dexie {\n basic_schema: any\n\n constructor(name: string, options: any) {\n super(name, options);\n\n // --- INIT SCHEMA --- // \n\n //todo: handle versions?\n\n // TODO: validate schema\n this.basic_schema = options.schema\n this.version(1).stores(this._convertSchemaToDxSchema(this.basic_schema))\n\n this.version(2).stores({})\n // this.verssion\n\n\n // create an alias for toArray\n // @ts-ignore\n this.Collection.prototype.get = this.Collection.prototype.toArray\n\n\n // --- SYNC --- // \n\n // this.syncable.on(\"statusChanged\", (status, url) => { \n // console.log(\"statusChanged\", status, url)\n // })\n\n }\n\n async connect({ access_token, ws_url }: { access_token: string, ws_url?: string }) {\n const WS_URL = ws_url || 'wss://pds.basic.id/ws'\n\n log('Connecting to', WS_URL)\n\n await this.updateSyncNodes();\n \n log('Starting connection...')\n return this.syncable.connect(\"websocket\", WS_URL, { authToken: access_token, schema: this.basic_schema });\n }\n\n async disconnect({ ws_url }: { ws_url?: string } = {}) {\n const WS_URL = ws_url || 'wss://pds.basic.id/ws'\n\n return this.syncable.disconnect(WS_URL) \n }\n\n private async updateSyncNodes() {\n try {\n const syncNodes = await this.table('_syncNodes').toArray();\n const localSyncNodes = syncNodes.filter(node => node.type === 'local');\n log('Local sync nodes:', localSyncNodes);\n\n if (localSyncNodes.length > 1) {\n\n \n const largestNodeId = Math.max(...localSyncNodes.map(node => node.id));\n // Check if the largest node is already the master\n const largestNode = localSyncNodes.find(node => node.id === largestNodeId);\n if (largestNode && largestNode.isMaster === 1) {\n log('Largest node is already the master. No changes needed.');\n return; // Exit the function early as no changes are needed\n }\n\n\n log('Largest node id:', largestNodeId);\n log('HEISENBUG: More than one local sync node found.')\n\n for (const node of localSyncNodes) {\n log(`Local sync node keys:`, node.id, node.isMaster);\n await this.table('_syncNodes').update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });\n\n log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? 'master' : '0'}`);\n }\n\n // add delay to ensure sync nodes are updated // i dont think this helps?\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n if (typeof window !== 'undefined') {\n window.location.reload();\n }\n }\n\n log('Sync nodes updated');\n } catch (error) {\n console.error('Error updating _syncNodes table:', error);\n }\n }\n\n handleStatusChange(fn: any) {\n this.syncable.on(\"statusChanged\", fn)\n }\n\n\n _convertSchemaToDxSchema(schema: any) {\n const stores = Object.entries(schema.tables).map(([key, table]: any) => {\n\n const indexedFields = Object.entries(table.fields).filter(([key, field]: any) => field.indexed).map(([key, field]: any) => `,${key}`).join('')\n return {\n [key]: 'id' + indexedFields\n }\n })\n\n return Object.assign({}, ...stores)\n }\n\n debugeroo() {\n // console.log(\"debugeroo\", this.syncable)\n\n // this.syncable.list().then(x => console.log(x))\n\n // this.syncable\n return this.syncable\n }\n\n collection<T extends { id: string } = Record<string, any> & { id: string }>(name: string) {\n // Validate table exists in schema\n if (this.basic_schema?.tables && !this.basic_schema.tables[name]) {\n throw new Error(`Table \"${name}\" not found in schema`)\n }\n\n const table = this.table(name)\n\n return {\n /**\n * Returns the underlying Dexie table\n * @type {Dexie.Table}\n */\n ref: table,\n\n // --- WRITE ---- // \n\n /**\n * Add a new record - returns the full object with generated id\n */\n add: async (data: Omit<T, 'id'>): Promise<T> => {\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n throw new Error(valid.message || 'Data validation failed')\n }\n\n const id = uuidv7()\n const fullData = { id, ...data } as T\n \n await table.add(fullData)\n return fullData\n },\n\n /**\n * Put (upsert) a record - returns the full object\n */\n put: async (data: T): Promise<T> => {\n if (!data.id) {\n throw new Error('put() requires an id field')\n }\n\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n throw new Error(valid.message || 'Data validation failed')\n }\n\n await table.put(data)\n return data\n },\n\n /**\n * Update an existing record - returns updated object or null\n */\n update: async (id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null> => {\n if (!id) {\n throw new Error('update() requires an id')\n }\n\n const valid = validateData(this.basic_schema, name, data, false)\n if (!valid.valid) {\n log('Invalid data', valid)\n throw new Error(valid.message || 'Data validation failed')\n }\n\n const updated = await table.update(id, data)\n if (updated === 0) {\n return null\n }\n\n // Fetch and return the updated record\n const record = await table.get(id)\n return (record as T) || null\n },\n\n /**\n * Delete a record - returns true if deleted, false if not found\n */\n delete: async (id: string): Promise<boolean> => {\n if (!id) {\n throw new Error('delete() requires an id')\n }\n\n // Check if record exists first\n const exists = await table.get(id)\n if (!exists) {\n return false\n }\n\n await table.delete(id)\n return true\n },\n\n // --- READ ---- // \n\n /**\n * Get a single record by id - returns null if not found\n */\n get: async (id: string): Promise<T | null> => {\n if (!id) {\n throw new Error('get() requires an id')\n }\n\n const record = await table.get(id)\n return (record as T) || null\n },\n\n /**\n * Get all records in the collection\n */\n getAll: async (): Promise<T[]> => {\n return table.toArray() as Promise<T[]>\n },\n\n // --- QUERY ---- // \n\n /**\n * Filter records using a predicate function\n */\n filter: async (fn: (item: T) => boolean): Promise<T[]> => {\n return table.filter(fn).toArray() as Promise<T[]>\n },\n\n /**\n * Get the raw Dexie table for advanced queries\n * @deprecated Use ref instead\n */\n query: () => table,\n }\n }\n}\n","/**\n * Core DB types for Basic SDK\n * These interfaces are implemented by both SyncDB (Dexie-based) and RemoteDB (REST-based)\n */\n\n/**\n * Collection interface for CRUD operations on a table\n * All write operations return the full object (not just the id)\n */\nexport interface Collection<T extends { id: string } = Record<string, any> & { id: string }> {\n /**\n * Add a new record to the collection\n * @param data - The data to add (without id, which will be generated)\n * @returns The created object with its generated id\n */\n add(data: Omit<T, 'id'>): Promise<T>\n\n /**\n * Put (upsert) a record - requires id\n * @param data - The full object including id\n * @returns The upserted object\n */\n put(data: T): Promise<T>\n\n /**\n * Update an existing record by id\n * @param id - The record id to update\n * @param data - Partial data to merge\n * @returns The updated object, or null if not found\n */\n update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null>\n\n /**\n * Delete a record by id\n * @param id - The record id to delete\n * @returns true if deleted, false if not found\n */\n delete(id: string): Promise<boolean>\n\n /**\n * Get a single record by id\n * @param id - The record id to fetch\n * @returns The object or null if not found\n */\n get(id: string): Promise<T | null>\n\n /**\n * Get all records in the collection\n * @returns Array of all objects\n */\n getAll(): Promise<T[]>\n\n /**\n * Filter records using a predicate function\n * @param fn - Filter function that returns true for matches\n * @returns Array of matching objects\n */\n filter(fn: (item: T) => boolean): Promise<T[]>\n\n /**\n * Direct access to underlying storage (optional)\n * For sync mode: Dexie table reference\n * For remote mode: undefined\n */\n ref?: any\n}\n\n/**\n * BasicDB interface - factory for creating collections\n */\nexport interface BasicDB {\n /**\n * Get a collection by name\n * @param name - The table/collection name (must match schema)\n * @returns A Collection instance for CRUD operations\n */\n collection<T extends { id: string } = Record<string, any> & { id: string }>(name: string): Collection<T>\n}\n\n/**\n * Database mode - determines which implementation is used\n * - 'sync': Uses Dexie + WebSocket for local-first sync (default)\n * - 'remote': Uses REST API calls directly to server\n */\nexport type DBMode = 'sync' | 'remote'\n\n/**\n * Auth error information passed to onAuthError callback\n */\nexport interface AuthError {\n status: number\n message: string\n response?: any\n}\n\n/**\n * Custom error class for Remote DB API errors\n * Includes HTTP status code for reliable error handling\n */\nexport class RemoteDBError extends Error {\n status: number\n response?: any\n\n constructor(message: string, status: number, response?: any) {\n super(message)\n this.name = 'RemoteDBError'\n this.status = status\n this.response = response\n }\n}\n\n/**\n * Configuration for RemoteDB\n */\nexport interface RemoteDBConfig {\n serverUrl: string\n projectId: string\n getToken: () => Promise<string>\n schema?: any\n /** Enable debug logging (default: false) */\n debug?: boolean\n /**\n * Optional callback when authentication fails (401 error after retry)\n * Use this to show login UI or redirect to sign-in\n */\n onAuthError?: (error: AuthError) => void\n}\n\n","import { Collection, RemoteDBConfig, RemoteDBError } from './types'\nimport { validateData } from '@basictech/schema'\n\n/**\n * Error thrown when user is not authenticated\n */\nexport class NotAuthenticatedError extends Error {\n constructor(message: string = 'Not authenticated') {\n super(message)\n this.name = 'NotAuthenticatedError'\n }\n}\n\n/**\n * RemoteCollection - REST API based implementation of the Collection interface\n * All operations make HTTP calls to the Basic API server\n */\nexport class RemoteCollection<T extends { id: string } = Record<string, any> & { id: string }> implements Collection<T> {\n private tableName: string\n private config: RemoteDBConfig\n\n constructor(tableName: string, config: RemoteDBConfig) {\n this.tableName = tableName\n this.config = config\n }\n\n private log(...args: any[]) {\n if (this.config.debug) {\n console.log('[RemoteDB]', ...args)\n }\n }\n\n /**\n * Check if an error is a \"not authenticated\" error\n */\n private isNotAuthenticatedError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase()\n return message.includes('no token') || \n message.includes('not authenticated') ||\n message.includes('please sign in')\n }\n return false\n }\n\n /**\n * Helper to make authenticated API requests\n * Automatically retries once on 401 (token expired) by refreshing the token\n */\n private async request<R>(\n method: string,\n path: string,\n body?: any,\n isRetry: boolean = false\n ): Promise<R> {\n // Try to get token - may throw if not authenticated\n const token = await this.config.getToken()\n const url = `${this.config.serverUrl}${path}`\n\n this.log(`${method} ${url}`, body ? JSON.stringify(body) : '')\n\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n },\n ...(body ? { body: JSON.stringify(body) } : {})\n })\n\n const responseData = await response.json().catch(() => ({}))\n\n if (!response.ok) {\n // Handle 401 Unauthorized - token may have expired\n if (response.status === 401 && !isRetry) {\n this.log('Got 401, retrying with fresh token...')\n // getToken() should refresh the token if expired\n // Retry the request once\n return this.request<R>(method, path, body, true)\n }\n\n if (this.config.debug) {\n console.error(`[RemoteDB] Error ${response.status}:`, responseData)\n }\n \n // Call onAuthError callback if provided and this is an auth error\n if (response.status === 401 && this.config.onAuthError) {\n this.config.onAuthError({\n status: response.status,\n message: 'Authentication failed',\n response: responseData\n })\n }\n\n // Try different error message fields that APIs commonly use\n const errorMessage = responseData.message || responseData.error || responseData.detail || \n (typeof responseData === 'string' ? responseData : `API request failed: ${response.status}`)\n throw new RemoteDBError(errorMessage, response.status, responseData)\n }\n\n this.log('Response:', responseData)\n return responseData\n }\n\n /**\n * Validate data against schema if available\n */\n private validateData(data: any, checkRequired: boolean = true): void {\n if (this.config.schema) {\n const result = validateData(this.config.schema, this.tableName, data, checkRequired)\n if (!result.valid) {\n throw new Error(result.message || 'Data validation failed')\n }\n }\n }\n\n /**\n * Get the base path for this collection\n */\n private get basePath(): string {\n return `/account/${this.config.projectId}/db/${this.tableName}`\n }\n\n /**\n * Add a new record to the collection\n * The server generates the ID\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async add(data: Omit<T, 'id'>): Promise<T> {\n this.validateData(data, true)\n\n try {\n const result = await this.request<{ data: T }>(\n 'POST',\n this.basePath,\n { value: data }\n )\n // Server returns the created record with the generated ID\n return result.data\n } catch (error) {\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to add items')\n }\n throw error\n }\n }\n\n /**\n * Put (upsert) a record - requires id\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async put(data: T): Promise<T> {\n if (!data.id) {\n throw new Error('put() requires an id field')\n }\n\n // Extract id from data, send the rest in the body\n const { id, ...rest } = data\n this.validateData(rest, true)\n\n try {\n const result = await this.request<{ data: T }>(\n 'PUT',\n `${this.basePath}/${id}`,\n { value: rest }\n )\n return result.data || data\n } catch (error) {\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to update items')\n }\n throw error\n }\n }\n\n /**\n * Update an existing record by id\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null> {\n if (!id) {\n throw new Error('update() requires an id')\n }\n\n this.validateData(data, false)\n\n try {\n const result = await this.request<{ data: T }>(\n 'PATCH',\n `${this.basePath}/${id}`,\n { value: data }\n )\n\n return result.data || null\n } catch (error) {\n // If record not found, return null instead of throwing\n if (error instanceof RemoteDBError && error.status === 404) {\n return null\n }\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to update items')\n }\n throw error\n }\n }\n\n /**\n * Delete a record by id\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async delete(id: string): Promise<boolean> {\n if (!id) {\n throw new Error('delete() requires an id')\n }\n\n try {\n await this.request<any>(\n 'DELETE',\n `${this.basePath}/${id}`\n )\n return true\n } catch (error) {\n // If record not found, return false instead of throwing\n if (error instanceof RemoteDBError && error.status === 404) {\n return false\n }\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to delete items')\n }\n throw error\n }\n }\n\n /**\n * Get a single record by id\n * Returns null if not authenticated (graceful degradation for read operations)\n */\n async get(id: string): Promise<T | null> {\n if (!id) {\n throw new Error('get() requires an id')\n }\n\n try {\n // Use the API's id query parameter for efficient single-record fetch\n const result = await this.request<{ data: T[] }>(\n 'GET',\n `${this.basePath}?id=${id}`\n )\n return result.data?.[0] || null\n } catch (error) {\n // For get(), return null on any error (not found, not authenticated, etc.)\n if (this.isNotAuthenticatedError(error)) {\n this.log('Not authenticated - returning null for get()')\n }\n return null\n }\n }\n\n /**\n * Get all records in the collection\n * Returns empty array if not authenticated (graceful degradation for read operations)\n */\n async getAll(): Promise<T[]> {\n try {\n const result = await this.request<{ data: T[] }>(\n 'GET',\n this.basePath\n )\n return result.data || []\n } catch (error) {\n // If not authenticated, return empty array gracefully\n if (this.isNotAuthenticatedError(error)) {\n this.log('Not authenticated - returning empty array for getAll()')\n return []\n }\n throw error\n }\n }\n\n /**\n * Filter records using a predicate function\n * Note: This fetches all records and filters client-side\n * Returns empty array if not authenticated (graceful degradation for read operations)\n */\n async filter(fn: (item: T) => boolean): Promise<T[]> {\n const all = await this.getAll()\n return all.filter(fn)\n }\n\n /**\n * ref is not available for remote collections\n */\n ref = undefined\n}\n","import { BasicDB, Collection, RemoteDBConfig } from './types'\nimport { RemoteCollection } from './RemoteCollection'\n\n/**\n * RemoteDB - REST API based implementation of BasicDB\n * Creates RemoteCollection instances for each table\n */\nexport class RemoteDB implements BasicDB {\n private config: RemoteDBConfig\n private collections: Map<string, RemoteCollection<any>> = new Map()\n\n constructor(config: RemoteDBConfig) {\n this.config = config\n }\n\n /**\n * Get a collection by name\n * Collections are cached for reuse\n */\n collection<T extends { id: string } = Record<string, any> & { id: string }>(\n name: string\n ): Collection<T> {\n // Return cached collection if exists\n if (this.collections.has(name)) {\n return this.collections.get(name) as RemoteCollection<T>\n }\n\n // Validate table exists in schema if schema is provided\n if (this.config.schema?.tables && !this.config.schema.tables[name]) {\n throw new Error(`Table \"${name}\" not found in schema`)\n }\n\n // Create and cache new collection\n const collection = new RemoteCollection<T>(name, this.config)\n this.collections.set(name, collection)\n\n return collection\n }\n}\n\n","{\n \"name\": \"@basictech/react\",\n \"version\": \"0.7.0-beta.6\",\n \"description\": \"\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"ajv\": \"^8.17.1\",\n \"dexie\": \"^4.2.1\",\n \"dexie-observable\": \"^4.0.1-beta.13\",\n \"dexie-react-hooks\": \"^4.2.0\",\n \"dexie-syncable\": \"^4.0.1-beta.13\",\n \"jwt-decode\": \"^4.0.0\",\n \"uuid\": \"^10.0.0\",\n \"@basictech/schema\": \"0.6.0\"\n },\n \"devDependencies\": {\n \"@repo/typescript-config\": \"*\",\n \"tsup\": \"^7.2.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"peerDependencies\": {\n \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\n }\n}\n","import { BasicStorage } from '../utils/storage'\n\nexport interface VersionInfo {\n version: string\n lastUpdated: number\n}\n\nexport interface Migration {\n fromVersion: string\n toVersion: string\n migrate: (storage: BasicStorage) => Promise<void>\n}\n\nexport class VersionUpdater {\n private storage: BasicStorage\n private currentVersion: string\n private migrations: Migration[]\n private versionKey = 'basic_app_version'\n\n constructor(storage: BasicStorage, currentVersion: string, migrations: Migration[] = []) {\n this.storage = storage\n this.currentVersion = currentVersion\n this.migrations = migrations.sort((a, b) => this.compareVersions(a.fromVersion, b.fromVersion))\n }\n\n /**\n * Check current stored version and run migrations if needed\n * Only compares major.minor versions, ignoring beta/prerelease parts\n * Example: \"0.7.0-beta.1\" and \"0.7.0\" are treated as the same version\n */\n async checkAndUpdate(): Promise<{ updated: boolean; fromVersion?: string; toVersion: string }> {\n const storedVersion = await this.getStoredVersion()\n \n if (!storedVersion) {\n // First time setup\n await this.setStoredVersion(this.currentVersion)\n return { updated: false, toVersion: this.currentVersion }\n }\n\n if (storedVersion === this.currentVersion) {\n return { updated: false, toVersion: this.currentVersion }\n }\n\n // Need to run migrations\n const migrationsToRun = this.getMigrationsToRun(storedVersion, this.currentVersion)\n \n if (migrationsToRun.length === 0) {\n // No migrations needed, just update version\n await this.setStoredVersion(this.currentVersion)\n return { updated: true, fromVersion: storedVersion, toVersion: this.currentVersion }\n }\n\n // Run migrations\n for (const migration of migrationsToRun) {\n try {\n console.log(`Running migration from ${migration.fromVersion} to ${migration.toVersion}`)\n await migration.migrate(this.storage)\n } catch (error) {\n console.error(`Migration failed from ${migration.fromVersion} to ${migration.toVersion}:`, error)\n throw new Error(`Migration failed: ${error}`)\n }\n }\n\n // Update to current version\n await this.setStoredVersion(this.currentVersion)\n return { updated: true, fromVersion: storedVersion, toVersion: this.currentVersion }\n }\n\n private async getStoredVersion(): Promise<string | null> {\n try {\n const versionData = await this.storage.get(this.versionKey)\n if (!versionData) return null\n \n const versionInfo: VersionInfo = JSON.parse(versionData)\n return versionInfo.version\n } catch (error) {\n console.warn('Failed to get stored version:', error)\n return null\n }\n }\n\n private async setStoredVersion(version: string): Promise<void> {\n const versionInfo: VersionInfo = {\n version,\n lastUpdated: Date.now()\n }\n await this.storage.set(this.versionKey, JSON.stringify(versionInfo))\n }\n\n private getMigrationsToRun(fromVersion: string, toVersion: string): Migration[] {\n return this.migrations.filter(migration => {\n // Migration should run if we're crossing the version boundary\n // i.e., stored version is less than migration.toVersion AND current version is >= migration.toVersion\n const storedLessThanMigrationTo = this.compareVersions(fromVersion, migration.toVersion) < 0\n const currentGreaterThanOrEqualMigrationTo = this.compareVersions(toVersion, migration.toVersion) >= 0\n \n console.log(`Checking migration ${migration.fromVersion} → ${migration.toVersion}:`)\n console.log(` stored ${fromVersion} < migration.to ${migration.toVersion}: ${storedLessThanMigrationTo}`)\n console.log(` current ${toVersion} >= migration.to ${migration.toVersion}: ${currentGreaterThanOrEqualMigrationTo}`)\n \n const shouldRun = storedLessThanMigrationTo && currentGreaterThanOrEqualMigrationTo\n console.log(` Should run: ${shouldRun}`)\n \n return shouldRun\n })\n }\n\n /**\n * Simple semantic version comparison (major.minor only, ignoring beta/prerelease)\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\n private compareVersions(a: string, b: string): number {\n // Extract major.minor from version strings, ignoring beta/prerelease parts\n const aMajorMinor = this.extractMajorMinor(a)\n const bMajorMinor = this.extractMajorMinor(b)\n \n // Compare major version first\n if (aMajorMinor.major !== bMajorMinor.major) {\n return aMajorMinor.major - bMajorMinor.major\n }\n \n // Then compare minor version\n return aMajorMinor.minor - bMajorMinor.minor\n }\n\n /**\n * Extract major.minor from version string, ignoring beta/prerelease\n * Examples: \"0.7.0-beta.1\" -> {major: 0, minor: 7}\n * \"1.2.3\" -> {major: 1, minor: 2}\n */\n private extractMajorMinor(version: string): { major: number, minor: number } {\n // Remove beta/prerelease parts and split by dots\n const cleanVersion = version.split('-')[0]?.split('+')[0] || version\n const parts = cleanVersion.split('.').map(Number)\n \n return {\n major: parts[0] || 0,\n minor: parts[1] || 0\n }\n }\n\n /**\n * Add a migration to the updater\n */\n addMigration(migration: Migration): void {\n this.migrations.push(migration)\n this.migrations.sort((a, b) => this.compareVersions(a.fromVersion, b.fromVersion))\n }\n}\n\n/**\n * Create a simple version updater instance\n */\nexport function createVersionUpdater(\n storage: BasicStorage, \n currentVersion: string, \n migrations: Migration[] = []\n): VersionUpdater {\n return new VersionUpdater(storage, currentVersion, migrations)\n}\n","import { BasicStorage } from '../utils/storage'\nimport { Migration } from './versionUpdater'\n\n\nexport const addMigrationTimestamp: Migration = {\n fromVersion: '0.6.0', \n toVersion: '0.7.0',\n async migrate(storage: BasicStorage) {\n console.log('Running test migration')\n storage.set('test_migration', 'true')\n }\n}\n\n\n/**\n * Get all available migrations\n */\nexport function getMigrations(): Migration[] {\n return [\n addMigrationTimestamp\n ]\n}\n","// Storage utilities for Basic React package\nexport interface BasicStorage {\n get(key: string): Promise<string | null>\n set(key: string, value: string): Promise<void>\n remove(key: string): Promise<void>\n}\n\nexport class LocalStorageAdapter implements BasicStorage {\n async get(key: string): Promise<string | null> {\n return localStorage.getItem(key)\n }\n \n async set(key: string, value: string): Promise<void> {\n localStorage.setItem(key, value)\n }\n \n async remove(key: string): Promise<void> {\n localStorage.removeItem(key)\n }\n}\n\nexport const STORAGE_KEYS = {\n REFRESH_TOKEN: 'basic_refresh_token',\n USER_INFO: 'basic_user_info',\n AUTH_STATE: 'basic_auth_state',\n REDIRECT_URI: 'basic_redirect_uri',\n SERVER_URL: 'basic_server_url',\n DEBUG: 'basic_debug'\n} as const\n\nexport function getCookie(name: string): string {\n let cookieValue = '';\n if (document.cookie && document.cookie !== '') {\n const cookies = document.cookie.split(';');\n for (let i = 0; i < cookies.length; i++) {\n const cookie = cookies[i]?.trim();\n if (cookie && cookie.substring(0, name.length + 1) === (name + '=')) {\n cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\n break;\n }\n }\n }\n return cookieValue;\n}\n\nexport function setCookie(name: string, value: string, options?: { secure?: boolean, sameSite?: string, httpOnly?: boolean }): void {\n const opts = {\n secure: true,\n sameSite: 'Strict',\n httpOnly: false,\n ...options\n };\n \n let cookieString = `${name}=${value}`;\n if (opts.secure) cookieString += '; Secure';\n if (opts.sameSite) cookieString += `; SameSite=${opts.sameSite}`;\n if (opts.httpOnly) cookieString += '; HttpOnly';\n \n document.cookie = cookieString;\n}\n\nexport function clearCookie(name: string): void {\n document.cookie = `${name}=; Secure; SameSite=Strict`;\n}\n","// Network utilities for Basic React package\nimport { log } from '../config'\nimport { version as currentVersion } from '../../package.json'\n\nexport function isDevelopment(debug?: boolean): boolean {\n return (\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.hostname.includes('localhost') ||\n window.location.hostname.includes('127.0.0.1') ||\n window.location.hostname.includes('.local') ||\n process.env.NODE_ENV === 'development' ||\n debug === true\n )\n}\n\nexport async function checkForNewVersion(): Promise<{ \n hasNewVersion: boolean, \n latestVersion: string | null, \n currentVersion: string | null \n}> {\n try {\n const isBeta = currentVersion.includes('beta')\n\n const response = await fetch(`https://registry.npmjs.org/@basictech/react/${isBeta ? 'beta' : 'latest'}`);\n if (!response.ok) {\n throw new Error('Failed to fetch version from npm');\n }\n\n const data = await response.json();\n const latestVersion = data.version;\n\n if (latestVersion !== currentVersion) {\n console.warn('[basic] New version available:', latestVersion, `\\nrun \"npm install @basictech/react@${latestVersion}\" to update`);\n }\n if (isBeta) {\n log('thank you for being on basictech/react beta :)')\n }\n \n return {\n hasNewVersion: currentVersion !== latestVersion,\n latestVersion,\n currentVersion\n };\n } catch (error) {\n log('Error checking for new version:', error);\n return {\n hasNewVersion: false,\n latestVersion: null, \n currentVersion: null\n };\n }\n}\n\nexport function cleanOAuthParamsFromUrl(): void {\n if (window.location.search.includes('code') || window.location.search.includes('state')) {\n const url = new URL(window.location.href)\n url.searchParams.delete('code')\n url.searchParams.delete('state')\n window.history.pushState({}, document.title, url.pathname + url.search)\n log('Cleaned OAuth parameters from URL')\n }\n}\n\nexport function getSyncStatus(statusCode: number): string {\n switch (statusCode) {\n case -1:\n return \"ERROR\";\n case 0:\n return \"OFFLINE\";\n case 1:\n return \"CONNECTING\";\n case 2:\n return \"ONLINE\";\n case 3:\n return \"SYNCING\";\n case 4:\n return \"ERROR_WILL_RETRY\";\n default:\n return \"UNKNOWN\";\n }\n}\n","// Schema utilities for Basic React package\nimport { validateSchema, compareSchemas } from '@basictech/schema'\nimport { log } from '../config'\n\nexport async function getSchemaStatus(schema: any): Promise<{\n valid: boolean,\n status: string,\n latest: any\n}> {\n const projectId = schema.project_id\n const valid = validateSchema(schema)\n\n if (!valid.valid) {\n console.warn('BasicDB Error: your local schema is invalid. Please fix errors and try again - sync is disabled')\n return { \n valid: false, \n status: 'invalid',\n latest: null\n }\n }\n\n const latestSchema = await fetch(`https://api.basic.tech/project/${projectId}/schema`)\n .then(res => res.json())\n .then(data => data.data[0].schema)\n .catch(err => {\n return { \n valid: false, \n status: 'error',\n latest: null\n }\n })\n\n console.log('latestSchema', latestSchema)\n\n if (!latestSchema.version) {\n return { \n valid: false, \n status: 'error',\n latest: null\n }\n }\n\n if (latestSchema.version > schema.version) {\n // error_code: schema_behind\n console.warn('BasicDB Error: your local schema version is behind the latest. Found version:', schema.version, 'but expected', latestSchema.version, \" - sync is disabled\")\n return { \n valid: false, \n status: 'behind', \n latest: latestSchema\n }\n } else if (latestSchema.version < schema.version) {\n // error_code: schema_ahead\n console.warn('BasicDB Error: your local schema version is ahead of the latest. Found version:', schema.version, 'but expected', latestSchema.version, \" - sync is disabled\")\n return { \n valid: false, \n status: 'ahead', \n latest: latestSchema\n }\n } else if (latestSchema.version === schema.version) {\n const changes = compareSchemas(schema, latestSchema)\n if (changes.valid) {\n return { \n valid: true,\n status: 'current',\n latest: latestSchema\n }\n } else {\n // error_code: schema_conflict\n console.warn('BasicDB Error: your local schema is conflicting with the latest. Your version:', schema.version, 'does not match origin version', latestSchema.version, \" - sync is disabled\")\n return { \n valid: false, \n status: 'conflict',\n latest: latestSchema\n }\n }\n } else { \n return { \n valid: false, \n status: 'error',\n latest: null\n }\n }\n}\n\nexport async function validateAndCheckSchema(schema: any): Promise<{\n isValid: boolean,\n schemaStatus: { valid: boolean, status?: string, latest?: any },\n errors?: any[]\n}> {\n const valid = validateSchema(schema)\n if (!valid.valid) {\n log('Basic Schema is invalid!', valid.errors)\n console.group('Schema Errors')\n let errorMessage = ''\n valid.errors.forEach((error, index) => {\n log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`)\n errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}\\n`\n })\n console.groupEnd()\n \n return {\n isValid: false,\n schemaStatus: { valid: false },\n errors: valid.errors\n }\n }\n\n let schemaStatus = { valid: false }\n if (schema.version !== 0) {\n schemaStatus = await getSchemaStatus(schema)\n log('schemaStatus', schemaStatus)\n } else { \n log(\"schema not published - at version 0\")\n }\n\n return {\n isValid: true,\n schemaStatus\n }\n}\n","import { useBasic, BasicProvider } from \"./AuthContext\";\nimport { useLiveQuery as useQuery } from \"dexie-react-hooks\";\n\n// Re-export from AuthContext\nexport { useBasic, BasicProvider, useQuery }\n\n// Type exports\nexport type { \n AuthConfig, \n BasicStorage, \n LocalStorageAdapter, \n BasicProviderProps,\n BasicContextType,\n AuthResult\n} from \"./AuthContext\"\n\n// Core DB exports\nexport type { \n DBMode, \n BasicDB, \n Collection, \n RemoteDBConfig,\n AuthError\n} from \"./core/db\"\n\nexport { RemoteDB, RemoteCollection, RemoteDBError, NotAuthenticatedError } from \"./core/db\"\n\n// Storage utilities\nexport { STORAGE_KEYS } from \"./utils/storage\""],"mappings":"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","names":["changes","baseRevision","partial","onChangesAccepted","requestId","Dexie","syncProtocol","Dexie","key","validateData","version","validateSchema","error","user","token"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/sync/tokenRegistry.ts","../src/sync/syncProtocol.js","../package.json","../src/utils/network.ts","../src/context.tsx","../src/dev/BasicDevToolbar.tsx","../src/AuthContext.tsx","../src/sync/index.ts","../src/core/db/types.ts","../src/core/db/RemoteCollection.ts","../src/core/db/RemoteDB.ts","../src/core/auth/AuthManager.ts","../src/utils/storage.ts","../src/utils/normalizeClientId.ts","../src/utils/resolveDid.ts","../src/updater/versionUpdater.ts","../src/updater/updateMigrations.ts","../src/utils/schema.ts","../src/index.ts"],"sourcesContent":["export const log = (...args: any[]) => {\n try { \n if (localStorage.getItem('basic_debug') === 'true') {\n console.log('[basic]', ...args)\n }\n } catch (e) {\n // silently fail if localStorage is unavailable (SSR)\n }\n}\n","/**\n * Module-level registry for token getter functions, keyed by WebSocket URL.\n *\n * dexie-syncable serializes the `options` object into IndexedDB via\n * structured clone, which cannot handle functions. This registry keeps\n * the getToken function out of `options` so it survives serialization\n * while remaining accessible to the sync protocol on every (re)connect.\n */\n\ntype GetTokenFn = (options?: { forceRefresh?: boolean }) => Promise<string>\n\nconst registry = new Map<string, GetTokenFn>()\n\nexport function setTokenGetter(url: string, fn: GetTokenFn): void {\n registry.set(url, fn)\n}\n\nexport function getTokenGetter(url: string): GetTokenFn | undefined {\n return registry.get(url)\n}\n","\"use client\"\nimport { Dexie } from \"dexie\";\nimport { log } from \"../config\";\nimport { getTokenGetter } from \"./tokenRegistry\";\n\nfunction decodeJwtExp(token) {\n try {\n var parts = token.split(\".\");\n if (parts.length !== 3) return null;\n var payload = JSON.parse(atob(parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\")));\n return typeof payload.exp === \"number\" ? payload.exp : null;\n } catch (_) {\n return null;\n }\n}\n\nexport const syncProtocol = function () {\n log(\"Initializing syncProtocol\");\n // Constants:\n var RECONNECT_DELAY = 5000; // Reconnect delay in case of errors such as network down.\n var TOKEN_REFRESH_BUFFER = 60; // Refresh token this many seconds before exp\n\n Dexie.Syncable.registerSyncProtocol(\"websocket\", {\n sync: function (\n context,\n url,\n options,\n baseRevision,\n syncedRevision,\n changes,\n partial,\n applyRemoteChanges,\n onChangesAccepted,\n onSuccess,\n onError,\n ) {\n // The following vars are needed because we must know which callback to ack when server sends it's ack to us.\n var requestId = 0;\n var acceptCallbacks = {};\n var refreshTimer = null;\n\n // Connect the WebSocket to given url:\n log(\"Connecting to\", url)\n var ws = new WebSocket(url);\n\n // sendChanges() method:\n function sendChanges(changes, baseRevision, partial, onChangesAccepted) {\n log(\"sendChanges\", changes.length, baseRevision);\n ++requestId;\n acceptCallbacks[requestId.toString()] = onChangesAccepted;\n\n // In this example, the server expects the following JSON format of the request:\n // {\n // type: \"changes\"\n // baseRevision: baseRevision,\n // changes: changes,\n // partial: partial,\n // requestId: id\n // }\n // To make the sample simplified, we assume the server has the exact same specification of how changes are structured.\n // In real world, you would have to pre-process the changes array to fit the server specification.\n // However, this example shows how to deal with the WebSocket to fullfill the API.\n\n ws.send(\n JSON.stringify({\n type: \"changes\",\n changes: changes,\n partial: partial,\n baseRevision: baseRevision,\n requestId: requestId,\n }),\n );\n }\n\n\n\n function clearRefreshTimer() {\n if (refreshTimer) {\n clearTimeout(refreshTimer);\n refreshTimer = null;\n }\n }\n\n // Resolve the getToken function from the module-level registry.\n // It's stored there (not in options) because dexie-syncable serializes\n // options into IndexedDB, and functions can't survive structured clone.\n function resolveGetToken() {\n var fn = getTokenGetter(url);\n if (!fn) throw new Error(\"No token getter registered for \" + url);\n return fn;\n }\n\n // Schedule a proactive token refresh before the JWT expires.\n // Sends a tokenUpdate message on the existing WebSocket so the\n // server can accept the new token without dropping the connection.\n function scheduleTokenRefresh(tokenStr) {\n clearRefreshTimer();\n var exp = decodeJwtExp(tokenStr);\n if (!exp) return;\n var msUntilRefresh = (exp - TOKEN_REFRESH_BUFFER) * 1000 - Date.now();\n if (msUntilRefresh <= 0) return;\n log(\"Scheduling proactive token refresh in\", Math.round(msUntilRefresh / 1000), \"s\");\n refreshTimer = setTimeout(async function () {\n try {\n var newToken = await resolveGetToken()({ forceRefresh: true });\n if (ws.readyState === WebSocket.OPEN) {\n log(\"Sending tokenUpdate on existing WebSocket\");\n ws.send(JSON.stringify({ type: \"tokenUpdate\", authToken: newToken }));\n scheduleTokenRefresh(newToken);\n }\n } catch (err) {\n log(\"Proactive token refresh failed (non-fatal):\", err);\n }\n }, msUntilRefresh);\n }\n\n // When WebSocket opens, get a fresh token and send our identity to the server.\n // This runs on every open, including reconnects after ERROR_WILL_RETRY,\n // so each attempt gets a fresh token via getToken().\n ws.onopen = async function (event) {\n try {\n var token = await resolveGetToken()();\n log(\"Opening socket - sending clientIdentity\", context.clientIdentity);\n ws.send(\n JSON.stringify({\n type: \"clientIdentity\",\n clientIdentity: context.clientIdentity || null,\n authToken: token,\n schema: options.schema\n }),\n );\n scheduleTokenRefresh(token);\n } catch (err) {\n log(\"Failed to get token for WebSocket:\", err);\n ws.close();\n onError(\"Authentication failed: \" + (err.message || err), RECONNECT_DELAY);\n }\n };\n\n // If network down or other error, tell the framework to reconnect again in some time:\n ws.onerror = function (event) {\n clearRefreshTimer();\n ws.close();\n log(\"ws.onerror\", event);\n onError(event?.message, RECONNECT_DELAY);\n };\n\n // If socket is closed (network disconnected), inform framework and make it reconnect\n ws.onclose = function (event) {\n clearRefreshTimer();\n onError(\"Socket closed: \" + event.reason, RECONNECT_DELAY);\n };\n\n // isFirstRound: Will need to call onSuccess() only when we are in sync the first time.\n // onSuccess() will unblock Dexie to be used by application code.\n // If for example app code writes: db.friends.where('shoeSize').above(40).toArray(callback), the execution of that query\n // will not run until we have called onSuccess(). This is because we want application code to get results that are as\n // accurate as possible. Specifically when connected the first time and the entire DB is being synced down to the browser,\n // it is important that queries starts running first when db is in sync.\n var isFirstRound = true;\n // When message arrive from the server, deal with the message accordingly:\n ws.onmessage = function (event) {\n try {\n // Assume we have a server that should send JSON messages of the following format:\n // {\n // type: \"clientIdentity\", \"changes\", \"ack\" or \"error\"\n // clientIdentity: unique value for our database client node to persist in the context. (Only applicable if type=\"clientIdentity\")\n // message: Error message (Only applicable if type=\"error\")\n // requestId: ID of change request that is acked by the server (Only applicable if type=\"ack\" or \"error\")\n // changes: changes from server (Only applicable if type=\"changes\")\n // lastRevision: last revision of changes sent (applicable if type=\"changes\")\n // partial: true if server has additionalChanges to send. False if these changes were the last known. (applicable if type=\"changes\")\n // }\n var requestFromServer = JSON.parse(event.data);\n log(\"requestFromServer\", requestFromServer, { isFirstRound });\n\n if (requestFromServer.type == \"clientIdentity\") {\n context.clientIdentity = requestFromServer.clientIdentity;\n context.save();\n\n sendChanges(changes, baseRevision, partial, onChangesAccepted);\n\n ws.send(\n JSON.stringify({\n type: \"subscribe\",\n syncedRevision: syncedRevision,\n }),\n );\n } else if (requestFromServer.type == \"changes\") {\n applyRemoteChanges(\n requestFromServer.changes,\n requestFromServer.currentRevision,\n requestFromServer.partial,\n );\n if (isFirstRound && !requestFromServer.partial) {\n // Since this is the first sync round and server sais we've got all changes - now is the time to call onsuccess()\n onSuccess({\n // Specify a react function that will react on additional client changes\n react: function (\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n ) {\n sendChanges(\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n );\n },\n disconnect: function () {\n clearRefreshTimer();\n ws.close();\n },\n });\n isFirstRound = false;\n }\n } else if (requestFromServer.type == \"ack\") {\n var requestId = requestFromServer.requestId;\n var acceptCallback = acceptCallbacks[requestId.toString()];\n acceptCallback(); // Tell framework that server has acknowledged the changes sent.\n delete acceptCallbacks[requestId.toString()];\n } else if (requestFromServer.type == \"error\") {\n ws.close();\n if (requestFromServer.code === \"TOKEN_EXPIRED\" || requestFromServer.code === \"UNAUTHORIZED\") {\n log(\"Auth error from server, will reconnect with fresh token:\", requestFromServer.message);\n onError(requestFromServer.message, RECONNECT_DELAY);\n } else {\n onError(requestFromServer.message, Infinity);\n }\n } else {\n log(\"unknown message\", requestFromServer);\n ws.close();\n onError(\"unknown message\", Infinity);\n }\n } catch (e) {\n ws.close();\n log(\"caught error\", e)\n onError(e, Infinity); // Something went crazy. Server sends invalid format or our code is buggy. Dont reconnect - it would continue failing.\n }\n };\n },\n });\n};\n","{\n \"name\": \"@basictech/react\",\n \"version\": \"0.8.0-beta.2\",\n \"description\": \"\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"semver\": \"^7.7.2\",\n \"ajv\": \"^8.17.1\",\n \"dexie\": \"^4.2.1\",\n \"dexie-observable\": \"^4.0.1-beta.13\",\n \"dexie-react-hooks\": \"^4.2.0\",\n \"dexie-syncable\": \"^4.0.1-beta.13\",\n \"jwt-decode\": \"^4.0.0\",\n \"uuid\": \"^10.0.0\",\n \"@basictech/schema\": \"0.7.0-beta.0\"\n },\n \"devDependencies\": {\n \"@repo/typescript-config\": \"*\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"peerDependencies\": {\n \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\n }\n}\n","// Network utilities for Basic React package\nimport semver from 'semver'\nimport { log } from '../config'\nimport { version as pkgVersion } from '../../package.json'\n\nexport function isDevelopment(debug?: boolean): boolean {\n if (debug === true) return true\n if (typeof process !== 'undefined' && process.env.NODE_ENV === 'development') return true\n if (typeof window === 'undefined' || !window.location) return false\n const host = window.location.hostname\n return (\n host === 'localhost' ||\n host === '127.0.0.1' ||\n host.includes('localhost') ||\n host.includes('127.0.0.1') ||\n host.includes('.local')\n )\n}\n\nfunction normalizeVersion(v: string | null | undefined): string | null {\n if (v == null) return null\n const t = String(v).trim()\n return t.length ? t : null\n}\n\nfunction versionsMatch(a: string, b: string): boolean {\n const na = a.trim()\n const nb = b.trim()\n if (na === nb) return true\n const va = semver.valid(na)\n const vb = semver.valid(nb)\n if (va && vb) return semver.eq(va, vb)\n return false\n}\n\n/** Use npm `beta` dist-tag when the installed version is a semver prerelease whose first id is `beta`. */\nfunction usesBetaDistTag(version: string): boolean {\n const pre = semver.prerelease(version)\n const id = pre?.[0]\n return typeof id === 'string' && id.toLowerCase() === 'beta'\n}\n\ntype NpmInstallMeta = {\n 'dist-tags'?: { latest?: string; beta?: string }\n}\n\nexport async function checkForNewVersion(): Promise<{ \n hasNewVersion: boolean, \n latestVersion: string | null, \n currentVersion: string | null \n}> {\n try {\n const currentVersion = normalizeVersion(pkgVersion)\n if (!currentVersion) {\n return { hasNewVersion: false, latestVersion: null, currentVersion: null }\n }\n\n const response = await fetch('https://registry.npmjs.org/@basictech/react', {\n headers: { Accept: 'application/vnd.npm.install-v1+json' },\n })\n if (!response.ok) {\n throw new Error('Failed to fetch version from npm');\n }\n\n const data = (await response.json()) as NpmInstallMeta\n const distTags = data['dist-tags'] ?? {}\n const rawRegistry =\n usesBetaDistTag(currentVersion)\n ? distTags.beta ?? distTags.latest\n : distTags.latest\n const latestVersion = normalizeVersion(rawRegistry ?? null)\n if (!latestVersion) {\n throw new Error('Missing dist-tags from npm registry')\n }\n\n const same = versionsMatch(currentVersion, latestVersion)\n\n if (!same && isDevelopment()) {\n log('[basic] version check mismatch:', {\n currentVersion,\n registryVersion: latestVersion,\n channel: usesBetaDistTag(currentVersion) ? 'beta' : 'latest',\n })\n }\n\n if (!same) {\n console.warn('[basic] New version available:', latestVersion, `\\nrun \"npm install @basictech/react@${latestVersion}\" to update`);\n }\n if (usesBetaDistTag(currentVersion)) {\n log('thank you for being on basictech/react beta :)')\n }\n \n return {\n hasNewVersion: !same,\n latestVersion,\n currentVersion\n };\n } catch (error) {\n log('Error checking for new version:', error);\n return {\n hasNewVersion: false,\n latestVersion: null, \n currentVersion: null\n };\n }\n}\n\nexport function cleanOAuthParamsFromUrl(): void {\n if (window.location.search.includes('code') || window.location.search.includes('state')) {\n const url = new URL(window.location.href)\n url.searchParams.delete('code')\n url.searchParams.delete('state')\n window.history.pushState({}, document.title, url.pathname + url.search)\n log('Cleaned OAuth parameters from URL')\n }\n}\n\nexport function getSyncStatus(statusCode: number): string {\n switch (statusCode) {\n case -1:\n return \"ERROR\";\n case 0:\n return \"OFFLINE\";\n case 1:\n return \"CONNECTING\";\n case 2:\n return \"ONLINE\";\n case 3:\n return \"SYNCING\";\n case 4:\n return \"ERROR_WILL_RETRY\";\n default:\n return \"UNKNOWN\";\n }\n}\n","import { createContext, useContext } from 'react'\nimport type { BasicDB } from './core/db'\nimport type { User, AuthResult, GetTokenOptions } from './core/auth/AuthManager'\nimport type { DBMode } from './core/db'\n\nexport enum DBStatus {\n LOADING = 'LOADING',\n OFFLINE = 'OFFLINE',\n CONNECTING = 'CONNECTING',\n ONLINE = 'ONLINE',\n SYNCING = 'SYNCING',\n ERROR = 'ERROR',\n ERROR_WILL_RETRY = 'ERROR_WILL_RETRY',\n ERROR_TOKEN_EXPIRED = 'ERROR_TOKEN_EXPIRED',\n}\n\n/** Snapshot of local schema vs server (for dev toolbar and debugging). */\nexport type BasicSchemaDevInfo = {\n projectId: string | null\n localVersion: number | undefined\n status: string\n valid: boolean\n lastCheckedAt: number\n error?: string\n}\n\n/**\n * Context type for useBasic hook\n */\nexport type BasicContextType = {\n isReady: boolean\n isSignedIn: boolean\n user: User | null\n did: string | null\n scope: string | null\n hasScope: (scope: string) => boolean\n missingScopes: () => string[]\n\n signIn: () => Promise<void>\n signInWithHandle: (handle: string) => Promise<void>\n signOut: () => Promise<void>\n signInWithCode: (code: string, state?: string) => Promise<AuthResult>\n\n getToken: (options?: GetTokenOptions) => Promise<string>\n getSignInUrl: (redirectUri?: string) => Promise<string>\n\n db: BasicDB\n dbStatus: DBStatus\n dbMode: DBMode\n\n /** Local schema vs server status; null if no schema on the provider. */\n devInfo: BasicSchemaDevInfo | null\n /** Re-run remote schema check (dev toolbar). */\n refreshSchemaStatus: () => Promise<void>\n\n isAuthReady: boolean\n signin: () => Promise<void>\n signout: () => Promise<void>\n signinWithCode: (code: string, state?: string) => Promise<AuthResult>\n getSignInLink: (redirectUri?: string) => Promise<string>\n}\n\nconst noDb: BasicDB = {\n collection: () => {\n throw new Error('no basicdb found - initialization failed. double check your schema.')\n },\n}\n\nexport const BasicContext = createContext<BasicContextType>({\n isReady: false,\n isSignedIn: false,\n user: null,\n did: null,\n scope: null,\n hasScope: () => false,\n missingScopes: () => [],\n\n signIn: () => Promise.resolve(),\n signInWithHandle: () => Promise.resolve(),\n signOut: () => Promise.resolve(),\n signInWithCode: () => Promise.resolve({ success: false }),\n\n getToken: (_options?: GetTokenOptions) => Promise.reject(new Error('no token')),\n getSignInUrl: () => Promise.resolve(''),\n\n db: noDb,\n dbStatus: DBStatus.LOADING,\n dbMode: 'sync',\n\n devInfo: null,\n refreshSchemaStatus: async () => {},\n\n isAuthReady: false,\n signin: () => Promise.resolve(),\n signout: () => Promise.resolve(),\n signinWithCode: () => Promise.resolve({ success: false }),\n getSignInLink: () => Promise.resolve(''),\n})\n\nexport function useBasic() {\n return useContext(BasicContext)\n}\n\nexport { noDb }\n","'use client'\n\nimport React, { useCallback, useMemo, useState } from 'react'\nimport { useBasic, DBStatus } from '../context'\nimport type { BasicSchemaDevInfo } from '../context'\nimport { version as sdkVersion } from '../../package.json'\nimport { isDevelopment } from '../utils/network'\n\nconst INDEXED_DB_NAME = 'basicdb'\nconst PANEL_PAD_X = 12\n\ntype ChipTone = 'ok' | 'warn' | 'bad' | 'muted'\n\nfunction toneForAuth(isReady: boolean, isSignedIn: boolean): ChipTone {\n if (!isReady) return 'muted'\n if (isSignedIn) return 'ok'\n return 'warn'\n}\n\nfunction toneForDb(dbMode: string, dbStatus: DBStatus): ChipTone {\n if (dbMode === 'remote') return dbStatus === DBStatus.ONLINE ? 'ok' : 'warn'\n if (dbStatus === DBStatus.ONLINE || dbStatus === DBStatus.SYNCING) return 'ok'\n if (dbStatus === DBStatus.CONNECTING || dbStatus === DBStatus.LOADING) return 'warn'\n if (dbStatus === DBStatus.OFFLINE) return 'muted'\n return 'bad'\n}\n\nfunction toneForSchema(info: BasicSchemaDevInfo | null): ChipTone {\n if (!info) return 'muted'\n if (info.valid && info.status === 'current') return 'ok'\n if (info.status === 'unpublished') return 'warn'\n if (info.status === 'no_schema') return 'muted'\n return 'bad'\n}\n\nfunction dbStatusLabel(status: DBStatus): string {\n switch (status) {\n case DBStatus.LOADING:\n return 'Initializing'\n case DBStatus.OFFLINE:\n return 'Offline'\n case DBStatus.CONNECTING:\n return 'Connecting'\n case DBStatus.ONLINE:\n return 'Connected'\n case DBStatus.SYNCING:\n return 'Syncing'\n case DBStatus.ERROR:\n return 'Error'\n case DBStatus.ERROR_WILL_RETRY:\n return 'Retrying'\n case DBStatus.ERROR_TOKEN_EXPIRED:\n return 'Token refresh'\n default:\n return String(status)\n }\n}\n\nfunction chipColor(tone: ChipTone): string {\n switch (tone) {\n case 'ok':\n return '#22c55e'\n case 'warn':\n return '#eab308'\n case 'bad':\n return '#ef4444'\n default:\n return '#71717a'\n }\n}\n\n/** Full value for display in dev panel (wraps; no truncation). */\nfunction displayDid(did: string | null): string {\n return did || '—'\n}\n\nfunction displayUserLine(user: { sub?: string; email?: string; name?: string; picture?: string }): string {\n const parts: string[] = []\n if (user.sub) parts.push(`sub: ${user.sub}`)\n if (user.email) parts.push(`email: ${user.email}`)\n if (user.name) parts.push(`name: ${user.name}`)\n return parts.length ? parts.join(' · ') : '—'\n}\n\nfunction ClipboardIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n )\n}\n\nexport type BasicDevToolbarProps = {\n /** When false, toolbar does not render. Defaults to true when used standalone. */\n enabled?: boolean\n /** Same as BasicProvider `debug` — when true, toolbar shows even off localhost. */\n debug?: boolean\n}\n\ntype CopyableRowProps = {\n rowKey: string\n label: string\n copyText: string\n copiedKey: string | null\n onCopied: (key: string) => void\n children: React.ReactNode\n}\n\nfunction SectionHeader({ children }: { children: React.ReactNode }) {\n return (\n <div\n style={{\n fontSize: 10,\n fontWeight: 700,\n color: '#e4e4e7',\n letterSpacing: '0.07em',\n textTransform: 'uppercase',\n marginBottom: 8,\n }}\n >\n {children}\n </div>\n )\n}\n\n/** Full-bleed horizontal rule: only above a section (not under the header). */\nfunction SectionRule() {\n const bleed = PANEL_PAD_X\n return (\n <div\n role=\"separator\"\n style={{\n height: 1,\n background: 'rgba(255, 255, 255, 0.055)',\n marginLeft: -bleed,\n marginRight: -bleed,\n marginTop: 14,\n marginBottom: 10,\n width: `calc(100% + ${bleed * 2}px)`,\n }}\n />\n )\n}\n\nfunction CopyableRow({\n rowKey,\n label,\n copyText,\n copiedKey,\n onCopied,\n children,\n}: CopyableRowProps) {\n const [hover, setHover] = useState(false)\n const canCopy = copyText.length > 0\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (!canCopy) return\n void navigator.clipboard.writeText(copyText).then(() => onCopied(rowKey))\n },\n [canCopy, copyText, onCopied, rowKey],\n )\n\n return (\n <div\n role={canCopy ? 'button' : undefined}\n tabIndex={canCopy ? 0 : undefined}\n onClick={canCopy ? handleClick : undefined}\n onKeyDown={\n canCopy\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick(e as unknown as React.MouseEvent)\n }\n }\n : undefined\n }\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n display: 'flex',\n gap: 8,\n marginBottom: 6,\n alignItems: 'flex-start',\n borderRadius: 6,\n padding: '4px 6px',\n marginLeft: -6,\n marginRight: -6,\n cursor: canCopy ? 'pointer' : 'default',\n background: hover && canCopy ? 'rgba(255,255,255,0.06)' : 'transparent',\n transition: 'background 0.12s ease',\n }}\n >\n <span style={{ color: '#a1a1aa', minWidth: 88, flexShrink: 0, paddingTop: 2 }}>{label}</span>\n <span\n style={{\n flex: 1,\n minWidth: 0,\n wordBreak: 'break-all',\n paddingTop: 2,\n lineHeight: 1.35,\n }}\n >\n {children}\n </span>\n {canCopy && (\n <span\n style={{\n flexShrink: 0,\n color: copiedKey === rowKey ? '#22c55e' : '#71717a',\n opacity: hover || copiedKey === rowKey ? 1 : 0,\n transition: 'opacity 0.12s ease, color 0.12s ease',\n paddingTop: 2,\n display: 'flex',\n alignItems: 'flex-start',\n }}\n title=\"Copy value\"\n >\n {copiedKey === rowKey ? (\n <span style={{ fontSize: 10 }}>✓</span>\n ) : (\n <ClipboardIcon />\n )}\n </span>\n )}\n </div>\n )\n}\n\n/**\n * Floating dev-only toolbar: auth, DB/sync, and schema status. Requires `BasicProvider` with `debug` or localhost / NODE_ENV=development for visibility unless `enabled` is forced.\n */\nexport function BasicDevToolbar({ enabled = true, debug }: BasicDevToolbarProps) {\n const {\n isReady,\n isSignedIn,\n user,\n did,\n scope,\n missingScopes,\n dbMode,\n dbStatus,\n devInfo,\n refreshSchemaStatus,\n } = useBasic()\n\n const [open, setOpen] = useState(false)\n const [refreshing, setRefreshing] = useState(false)\n const [copied, setCopied] = useState(false)\n const [rowCopied, setRowCopied] = useState<string | null>(null)\n\n const show =\n enabled && typeof window !== 'undefined' && isDevelopment(debug)\n\n const authTone = toneForAuth(isReady, isSignedIn)\n const dbTone = toneForDb(dbMode, dbStatus)\n const schemaTone = toneForSchema(devInfo)\n\n const syncTone: ChipTone =\n dbMode === 'remote'\n ? 'muted'\n : dbTone === 'ok' || dbStatus === DBStatus.SYNCING\n ? 'ok'\n : dbTone === 'warn'\n ? 'warn'\n : dbTone === 'bad'\n ? 'bad'\n : 'muted'\n\n const handleRefreshSchema = useCallback(async () => {\n setRefreshing(true)\n try {\n await refreshSchemaStatus()\n } finally {\n setRefreshing(false)\n }\n }, [refreshSchemaStatus])\n\n const missingList = missingScopes()\n\n const debugPayload = useMemo(() => {\n return {\n sdkVersion,\n isReady,\n isSignedIn,\n did: did ?? null,\n user: user\n ? {\n sub: user.sub,\n email: user.email,\n name: user.name,\n picture: user.picture,\n }\n : null,\n scope,\n missingScopes: missingList,\n dbMode,\n dbStatus,\n indexedDbName: dbMode === 'sync' ? INDEXED_DB_NAME : null,\n schema: devInfo,\n }\n }, [isReady, isSignedIn, did, user, scope, dbMode, dbStatus, devInfo, missingList])\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(JSON.stringify(debugPayload, null, 2))\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch {\n /* ignore */\n }\n }, [debugPayload])\n\n const onRowCopied = useCallback((key: string) => {\n setRowCopied(key)\n setTimeout(() => setRowCopied((k) => (k === key ? null : k)), 1500)\n }, [])\n\n if (!show) return null\n\n const shell: React.CSSProperties = {\n position: 'fixed',\n bottom: 12,\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 99999,\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontSize: 11,\n color: '#e4e4e7',\n pointerEvents: 'auto',\n }\n\n const bar: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '8px 12px',\n borderRadius: 999,\n background: 'rgba(24, 24, 27, 0.92)',\n border: '1px solid rgba(63, 63, 70, 0.9)',\n boxShadow: '0 8px 32px rgba(0,0,0,0.35)',\n cursor: 'pointer',\n userSelect: 'none',\n }\n\n /** Fixed box so flex line-height / strut cannot stretch dots when the pill width changes. */\n const dot = (tone: ChipTone) => (\n <span\n style={{\n display: 'block',\n boxSizing: 'border-box',\n width: 6,\n height: 6,\n minWidth: 6,\n minHeight: 6,\n maxWidth: 6,\n maxHeight: 6,\n borderRadius: '50%',\n background: chipColor(tone),\n flexShrink: 0,\n }}\n />\n )\n\n const dotSlot = (title: string, tone: ChipTone) => (\n <span\n title={title}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 6,\n height: 6,\n flexShrink: 0,\n lineHeight: 0,\n }}\n >\n {dot(tone)}\n </span>\n )\n\n const panel: React.CSSProperties = {\n marginBottom: 8,\n maxHeight: '50vh',\n overflow: 'auto',\n padding: PANEL_PAD_X,\n borderRadius: 10,\n background: 'rgba(24, 24, 27, 0.96)',\n border: '1px solid rgba(63, 63, 70, 0.9)',\n boxShadow: '0 8px 32px rgba(0,0,0,0.35)',\n minWidth: 300,\n maxWidth: 'min(560px, calc(100vw - 24px))',\n }\n\n const syncStatusText = dbStatusLabel(dbStatus)\n\n return (\n <div style={shell}>\n {open && (\n <div style={panel}>\n <div style={{ marginBottom: 12 }}>\n <div style={{ fontWeight: 600, fontSize: 12 }}>Basic SDK</div>\n <div style={{ color: '#71717a', fontSize: 10, marginTop: 2 }}>v{sdkVersion}</div>\n </div>\n\n <SectionHeader>Auth</SectionHeader>\n <CopyableRow\n rowKey=\"ready\"\n label=\"Ready\"\n copyText={String(isReady)}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {String(isReady)}\n </CopyableRow>\n <CopyableRow\n rowKey=\"signedIn\"\n label=\"Signed in\"\n copyText={String(isSignedIn)}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {String(isSignedIn)}\n </CopyableRow>\n <CopyableRow\n rowKey=\"did\"\n label=\"DID\"\n copyText={did || ''}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {displayDid(did)}\n </CopyableRow>\n <CopyableRow\n rowKey=\"user\"\n label=\"User\"\n copyText={user ? displayUserLine(user) : ''}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {user ? displayUserLine(user) : '—'}\n </CopyableRow>\n <CopyableRow\n rowKey=\"scopes\"\n label=\"Scopes\"\n copyText={scope || ''}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {scope || '—'}\n </CopyableRow>\n <CopyableRow\n rowKey=\"missingScopes\"\n label=\"Missing scopes\"\n copyText={missingList.length ? missingList.join(', ') : ''}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {missingList.length ? missingList.join(', ') : '—'}\n </CopyableRow>\n\n <SectionRule />\n <SectionHeader>Database</SectionHeader>\n <CopyableRow\n rowKey=\"dbMode\"\n label=\"Mode\"\n copyText={dbMode}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {dbMode}\n </CopyableRow>\n <CopyableRow\n rowKey=\"indexedDb\"\n label=\"IndexedDB\"\n copyText={dbMode === 'sync' ? INDEXED_DB_NAME : ''}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {dbMode === 'sync' ? INDEXED_DB_NAME : '—'}\n </CopyableRow>\n <CopyableRow\n rowKey=\"syncStatus\"\n label=\"Sync / status\"\n copyText={syncStatusText}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {syncStatusText}\n </CopyableRow>\n\n <SectionRule />\n <SectionHeader>Schema</SectionHeader>\n {devInfo ? (\n <>\n <CopyableRow\n rowKey=\"schemaProject\"\n label=\"Project\"\n copyText={devInfo.projectId ?? ''}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {devInfo.projectId ?? '—'}\n </CopyableRow>\n <CopyableRow\n rowKey=\"schemaLocalVer\"\n label=\"Local version\"\n copyText={\n devInfo.localVersion !== undefined && devInfo.localVersion !== null\n ? String(devInfo.localVersion)\n : ''\n }\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {devInfo.localVersion ?? '—'}\n </CopyableRow>\n <CopyableRow\n rowKey=\"schemaRemote\"\n label=\"Remote check\"\n copyText={devInfo.status}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {devInfo.status}\n </CopyableRow>\n <CopyableRow\n rowKey=\"schemaValid\"\n label=\"Valid\"\n copyText={String(devInfo.valid)}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {String(devInfo.valid)}\n </CopyableRow>\n <CopyableRow\n rowKey=\"schemaChecked\"\n label=\"Checked\"\n copyText={\n devInfo.lastCheckedAt\n ? new Date(devInfo.lastCheckedAt).toISOString()\n : ''\n }\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {devInfo.lastCheckedAt\n ? new Date(devInfo.lastCheckedAt).toLocaleString()\n : '—'}\n </CopyableRow>\n {devInfo.error ? (\n <CopyableRow\n rowKey=\"schemaError\"\n label=\"Error\"\n copyText={devInfo.error}\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n {devInfo.error}\n </CopyableRow>\n ) : null}\n </>\n ) : (\n <CopyableRow\n rowKey=\"schemaStatus\"\n label=\"Status\"\n copyText=\"No schema on provider\"\n copiedKey={rowCopied}\n onCopied={onRowCopied}\n >\n No schema on provider\n </CopyableRow>\n )}\n\n <div style={{ display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap' }}>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n void handleRefreshSchema()\n }}\n disabled={refreshing}\n style={{\n padding: '6px 10px',\n borderRadius: 6,\n border: '1px solid #3f3f46',\n background: '#27272a',\n color: '#e4e4e7',\n cursor: refreshing ? 'wait' : 'pointer',\n fontSize: 11,\n fontFamily: 'inherit',\n }}\n >\n {refreshing ? 'Refreshing…' : 'Refresh schema'}\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n void handleCopy()\n }}\n style={{\n padding: '6px 10px',\n borderRadius: 6,\n border: '1px solid #3f3f46',\n background: '#27272a',\n color: '#e4e4e7',\n cursor: 'pointer',\n fontSize: 11,\n fontFamily: 'inherit',\n }}\n >\n {copied ? 'Copied' : 'Copy debug info'}\n </button>\n </div>\n </div>\n )}\n\n <button\n type=\"button\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n style={{\n ...bar,\n border: 'none',\n width: '100%',\n cursor: 'pointer',\n }}\n >\n <span style={{ fontWeight: 600, letterSpacing: 0.02 }}>Basic</span>\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n marginLeft: 8,\n height: 6,\n flexShrink: 0,\n lineHeight: 0,\n }}\n >\n {dotSlot('Auth', authTone)}\n {dotSlot('DB', dbTone)}\n {dotSlot('Sync', syncTone)}\n {dotSlot('Schema', schemaTone)}\n </span>\n <span style={{ color: '#71717a', marginLeft: 4 }}>{open ? '▾' : '▴'}</span>\n </button>\n </div>\n )\n}\n","import React, { useCallback, useEffect, useRef, useState, Suspense, lazy } from 'react'\n\nimport { BasicSync, initDexieExtensions } from './sync'\nimport { RemoteDB, DBMode, BasicDB } from './core/db'\nimport { AuthManager } from './core/auth/AuthManager'\nimport type { User, AuthResult, GetTokenOptions, PdsEndpoints } from './core/auth/AuthManager'\n\nimport { log } from './config'\nimport { version as currentVersion } from '../package.json'\nimport { createVersionUpdater } from './updater/versionUpdater'\nimport { getMigrations } from './updater/updateMigrations'\nimport { BasicStorage, LocalStorageAdapter } from './utils/storage'\nimport { isDevelopment, checkForNewVersion, getSyncStatus } from './utils/network'\nimport { validateAndCheckSchema } from './utils/schema'\nimport { BasicContext, DBStatus, noDb, type BasicSchemaDevInfo } from './context'\n\nconst BasicDevToolbar = lazy(() =>\n import('./dev/BasicDevToolbar').then((m) => ({ default: m.BasicDevToolbar }))\n)\n\nexport type { BasicStorage, LocalStorageAdapter } from './utils/storage'\nexport type { DBMode, BasicDB, Collection } from './core/db'\nexport type { Token, User, AuthResult, GetTokenOptions, PdsEndpoints } from './core/auth/AuthManager'\nexport type { BasicContextType, BasicSchemaDevInfo } from './context'\nexport { DBStatus, useBasic, BasicContext } from './context'\n\nexport type AuthConfig = {\n scopes?: string | string[]\n /** @deprecated Use pds_url instead */\n server_url?: string\n /** PDS URL for auth and data (default: https://pds.basic.id) */\n pds_url?: string\n /** Admin server URL for connect reporting (default: https://api.basic.tech) */\n admin_url?: string\n ws_url?: string\n}\n\nexport type BasicProviderProps = {\n children: React.ReactNode\n /**\n * @deprecated Project ID is now extracted from schema.project_id.\n * This prop is kept for backward compatibility but can be omitted.\n */\n project_id?: string\n /** The Basic schema object containing project_id and table definitions */\n schema?: any\n debug?: boolean\n storage?: BasicStorage\n auth?: AuthConfig\n /**\n * Database mode - determines which implementation is used\n * - 'sync': Uses Dexie + WebSocket for local-first sync (default)\n * - 'remote': Uses REST API calls directly to server\n */\n dbMode?: DBMode\n /** Show floating dev toolbar (localhost, NODE_ENV=development, or debug=true). */\n devToolbar?: boolean\n}\n\nconst DEFAULT_AUTH_CONFIG = {\n scopes: 'profile,email,app:admin',\n pds_url: 'https://pds.basic.id',\n admin_url: 'https://api.basic.tech',\n ws_url: 'wss://pds.basic.id/ws',\n} as const\n\ntype ErrorObject = {\n code: string\n title: string\n message: string\n}\n\ntype AuthSnapshot = {\n isSignedIn: boolean\n hasToken: boolean\n isAuthReady: boolean\n user: User | null\n did: string | null\n tokenScope: string | null\n}\n\nfunction snapshotAuth(mgr: AuthManager): AuthSnapshot {\n return {\n isSignedIn: mgr.isSignedIn,\n hasToken: !!mgr.token,\n isAuthReady: mgr.isAuthReady,\n user: mgr.user,\n did: mgr.did,\n tokenScope: mgr.tokenScope,\n }\n}\n\nexport function BasicProvider({\n children,\n project_id: project_id_prop,\n schema,\n debug = false,\n storage,\n auth,\n dbMode = 'sync',\n devToolbar = false,\n}: BasicProviderProps) {\n const project_id = schema?.project_id || project_id_prop\n\n if (auth?.server_url && !auth?.pds_url) {\n log('Warning: auth.server_url is deprecated, use auth.pds_url instead')\n }\n const authConfig = {\n scopes: auth?.scopes || DEFAULT_AUTH_CONFIG.scopes,\n pds_url: auth?.pds_url || auth?.server_url || DEFAULT_AUTH_CONFIG.pds_url,\n admin_url: auth?.admin_url || DEFAULT_AUTH_CONFIG.admin_url,\n ws_url: auth?.ws_url || DEFAULT_AUTH_CONFIG.ws_url,\n }\n\n const scopesString = Array.isArray(authConfig.scopes)\n ? authConfig.scopes.join(' ')\n : authConfig.scopes\n\n const storageRef = useRef<BasicStorage>(storage || new LocalStorageAdapter())\n const storageAdapter = storageRef.current\n\n const schemaRef = useRef(schema)\n schemaRef.current = schema\n\n const [authState, setAuthState] = useState<AuthSnapshot>({\n isSignedIn: false,\n hasToken: false,\n isAuthReady: false,\n user: null,\n did: null,\n tokenScope: null,\n })\n\n const authRef = useRef<AuthManager>(null!)\n if (!authRef.current) {\n authRef.current = new AuthManager(\n {\n projectId: project_id,\n scopes: scopesString,\n pdsUrl: authConfig.pds_url,\n adminUrl: authConfig.admin_url,\n debug,\n },\n storageAdapter,\n () => setAuthState(snapshotAuth(authRef.current)),\n )\n }\n\n const syncRef = useRef<BasicSync | null>(null)\n const remoteDbRef = useRef<RemoteDB | null>(null)\n const [shouldConnect, setShouldConnect] = useState(false)\n const [dbStatus, setDbStatus] = useState<DBStatus>(DBStatus.OFFLINE)\n const [isReady, setIsReady] = useState(false)\n const [error, setError] = useState<ErrorObject | null>(null)\n const [schemaDevInfo, setSchemaDevInfo] = useState<BasicSchemaDevInfo | null>(null)\n\n const isDevMode = () => isDevelopment(debug)\n\n const refreshSchemaStatus = useCallback(async () => {\n const s = schemaRef.current\n if (!s) {\n setSchemaDevInfo(\n project_id\n ? {\n projectId: project_id,\n localVersion: undefined,\n status: 'no_schema',\n valid: false,\n lastCheckedAt: Date.now(),\n }\n : null,\n )\n return\n }\n const result = await validateAndCheckSchema(s)\n if (!result.isValid) {\n const errText =\n result.errors?.map((e: { message?: string }) => e.message || '').join('; ') || 'invalid'\n setSchemaDevInfo({\n projectId: s.project_id ?? null,\n localVersion: s.version,\n status: 'invalid',\n valid: false,\n lastCheckedAt: Date.now(),\n error: errText,\n })\n return\n }\n setSchemaDevInfo({\n projectId: s.project_id ?? null,\n localVersion: s.version,\n status: result.schemaStatus.status ?? 'unknown',\n valid: result.schemaStatus.valid,\n lastCheckedAt: Date.now(),\n })\n }, [project_id])\n\n useEffect(() => {\n const runVersionUpdater = async () => {\n try {\n const versionUpdater = createVersionUpdater(storageAdapter, currentVersion, getMigrations())\n const updateResult = await versionUpdater.checkAndUpdate()\n\n if (updateResult.updated) {\n log(`App updated from ${updateResult.fromVersion} to ${updateResult.toVersion}`)\n } else {\n log(`App version ${updateResult.toVersion} is current`)\n }\n } catch (error) {\n log('Version update failed:', error)\n }\n }\n\n runVersionUpdater()\n authRef.current.initialize()\n\n return authRef.current.setupNetworkListeners()\n }, [])\n\n useEffect(() => {\n async function initSyncDb(options: { shouldConnect: boolean }) {\n if (!syncRef.current) {\n log('Initializing Basic Sync DB')\n\n await initDexieExtensions()\n\n syncRef.current = new BasicSync('basicdb', { schema: schema })\n\n syncRef.current.syncable.on('statusChanged', (status: number) => {\n const newStatus = getSyncStatus(status) as DBStatus\n setDbStatus(newStatus)\n\n if (newStatus === DBStatus.ERROR_WILL_RETRY) {\n log('Sync entered ERROR_WILL_RETRY - proactively refreshing token')\n authRef.current.getToken({ forceRefresh: true }).catch(() => {})\n }\n })\n\n if (options.shouldConnect) {\n setShouldConnect(true)\n } else {\n log('Sync is disabled')\n }\n\n setIsReady(true)\n }\n }\n\n function initRemoteDb() {\n if (!remoteDbRef.current) {\n if (!project_id) {\n setError({\n code: 'missing_project_id',\n title: 'Project ID Required',\n message:\n 'Remote mode requires a project_id. Provide it via schema.project_id or the project_id prop.',\n })\n setIsReady(true)\n return\n }\n\n log('Initializing Basic Remote DB')\n remoteDbRef.current = new RemoteDB({\n serverUrl: authConfig.pds_url,\n projectId: project_id,\n getToken: (opts) => authRef.current.getToken(opts),\n schema: schema,\n debug: debug,\n onAuthError: (error) => {\n log('RemoteDB auth error:', error)\n handleSignOut()\n },\n })\n setDbStatus(DBStatus.ONLINE)\n setIsReady(true)\n }\n }\n\n async function checkSchema() {\n const result = await validateAndCheckSchema(schema)\n\n if (!result.isValid) {\n let errorMessage = ''\n if (result.errors) {\n result.errors.forEach((err: any, index: number) => {\n errorMessage += `${index + 1}: ${err.message} - at ${err.instancePath}\\n`\n })\n }\n setSchemaDevInfo({\n projectId: schema?.project_id ?? null,\n localVersion: schema?.version,\n status: 'invalid',\n valid: false,\n lastCheckedAt: Date.now(),\n error: errorMessage.trim() || undefined,\n })\n setError({\n code: 'schema_invalid',\n title: 'Basic Schema is invalid!',\n message: errorMessage,\n })\n setIsReady(true)\n return null\n }\n\n setSchemaDevInfo({\n projectId: schema?.project_id ?? null,\n localVersion: schema?.version,\n status: result.schemaStatus.status ?? 'unknown',\n valid: result.schemaStatus.valid,\n lastCheckedAt: Date.now(),\n })\n\n if (dbMode === 'remote') {\n initRemoteDb()\n } else {\n if (result.schemaStatus.valid) {\n await initSyncDb({ shouldConnect: true })\n } else {\n if (result.schemaStatus.status === 'unpublished') {\n log('Schema not published yet (version 0) - sync is disabled. Publish your schema to enable sync.')\n } else {\n log('Schema is invalid!', result.schemaStatus)\n }\n await initSyncDb({ shouldConnect: false })\n }\n }\n\n checkForNewVersion()\n }\n\n if (schema) {\n checkSchema()\n } else {\n setSchemaDevInfo(\n project_id\n ? {\n projectId: project_id,\n localVersion: undefined,\n status: 'no_schema',\n valid: false,\n lastCheckedAt: Date.now(),\n }\n : null,\n )\n if (dbMode === 'remote' && project_id) {\n initRemoteDb()\n } else {\n setIsReady(true)\n }\n }\n }, [])\n\n useEffect(() => {\n if (authState.hasToken && syncRef.current && authState.isSignedIn && shouldConnect) {\n log('connecting to db...')\n\n syncRef.current\n ?.connect({\n getToken: (opts?: GetTokenOptions) => authRef.current.getToken(opts),\n ws_url: authConfig.ws_url,\n })\n .catch((e: any) => {\n log('error connecting to db', e)\n })\n }\n }, [authState.isSignedIn, authState.hasToken, shouldConnect])\n\n const handleSignOut = async () => {\n await authRef.current.signOut()\n if (syncRef.current) {\n try {\n await syncRef.current.close()\n await syncRef.current.delete({ disableAutoOpen: false })\n syncRef.current = null\n window?.location?.reload()\n } catch (error) {\n console.error('Error during database cleanup:', error)\n }\n }\n }\n\n const handleSignIn = async () => {\n try {\n await authRef.current.signIn()\n } catch (error) {\n if (isDevMode()) {\n setError({\n code: 'signin_error',\n title: 'Sign-in Failed',\n message:\n (error as Error).message || 'An error occurred during sign-in. Please try again.',\n })\n }\n throw error\n }\n }\n\n const handleSignInWithHandle = async (handle: string) => {\n try {\n await authRef.current.signInWithHandle(handle)\n } catch (error) {\n if (isDevMode()) {\n setError({\n code: 'signin_error',\n title: 'Sign-in Failed',\n message:\n (error as Error).message || 'An error occurred during sign-in. Please try again.',\n })\n }\n throw error\n }\n }\n\n const getCurrentDb = (): BasicDB => {\n if (dbMode === 'remote') {\n return remoteDbRef.current || noDb\n }\n return syncRef.current || noDb\n }\n\n const contextValue = {\n isReady: authState.isAuthReady,\n isSignedIn: authState.isSignedIn,\n user: authState.user,\n did: authState.did,\n scope: authState.tokenScope,\n hasScope: (s: string) => authRef.current.hasScope(s),\n missingScopes: () => authRef.current.missingScopes(),\n\n signIn: handleSignIn,\n signInWithHandle: handleSignInWithHandle,\n signOut: handleSignOut,\n signInWithCode: (code: string, state?: string) => authRef.current.signInWithCode(code, state),\n\n getToken: (opts?: GetTokenOptions) => authRef.current.getToken(opts),\n getSignInUrl: (redirectUri?: string) => authRef.current.getSignInUrl(redirectUri),\n\n db: getCurrentDb(),\n dbStatus,\n dbMode,\n\n devInfo: schemaDevInfo,\n refreshSchemaStatus,\n\n isAuthReady: authState.isAuthReady,\n signin: handleSignIn,\n signout: handleSignOut,\n signinWithCode: (code: string, state?: string) => authRef.current.signInWithCode(code, state),\n getSignInLink: (redirectUri?: string) => authRef.current.getSignInUrl(redirectUri),\n }\n\n return (\n <BasicContext.Provider value={contextValue}>\n {error && isDevMode() && <ErrorDisplay error={error} />}\n {devToolbar && isDevMode() && (\n <Suspense fallback={null}>\n <BasicDevToolbar debug={debug} />\n </Suspense>\n )}\n {isReady && children}\n </BasicContext.Provider>\n )\n}\n\nfunction ErrorDisplay({ error }: { error: ErrorObject }) {\n return (\n <div\n style={{\n position: 'absolute',\n top: 20,\n left: 20,\n color: 'black',\n backgroundColor: '#f8d7da',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n padding: '20px',\n maxWidth: '400px',\n margin: '20px auto',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',\n fontFamily: 'monospace',\n }}\n >\n <h3 style={{ fontSize: '0.8rem', opacity: 0.8 }}>code: {error.code}</h3>\n <h1 style={{ fontSize: '1.2rem', lineHeight: 1.5 }}>{error.title}</h1>\n <p>{error.message}</p>\n </div>\n )\n}\n","\"use client\"\n\nimport { v7 as uuidv7 } from 'uuid';\nimport { Dexie } from 'dexie';\n\nimport { log } from '../config'\nimport { validateData } from '@basictech/schema'\nimport { setTokenGetter } from './tokenRegistry'\n\n// Track initialization state\nlet dexieExtensionsLoaded = false;\nlet initPromise: Promise<void> | null = null;\n\n/**\n * Initialize Dexie extensions (syncable and observable)\n * This must be called before creating a BasicSync instance\n * Safe to call multiple times - will only load once\n */\nexport async function initDexieExtensions(): Promise<void> {\n // Return early if already loaded or not in browser\n if (dexieExtensionsLoaded) return;\n if (typeof window === 'undefined') return;\n \n // If already initializing, wait for that promise\n if (initPromise) return initPromise;\n \n initPromise = (async () => {\n try {\n // Dynamic imports - only loaded in browser\n await import('dexie-syncable');\n await import('dexie-observable');\n \n // Import and register sync protocol\n const { syncProtocol } = await import('./syncProtocol');\n syncProtocol();\n \n dexieExtensionsLoaded = true;\n log('Dexie extensions loaded successfully');\n } catch (error) {\n console.error('Failed to load Dexie extensions:', error);\n throw error;\n }\n })();\n \n return initPromise;\n}\n\n/**\n * Check if Dexie extensions are loaded\n */\nexport function isDexieReady(): boolean {\n return dexieExtensionsLoaded;\n}\n\n\nexport class BasicSync extends Dexie {\n basic_schema: any\n\n constructor(name: string, options: any) {\n super(name, options);\n\n // --- INIT SCHEMA --- //\n this.basic_schema = options.schema\n this.version(1).stores(this._convertSchemaToDxSchema(this.basic_schema))\n this.version(2).stores({})\n\n // @ts-ignore - alias for toArray\n this.Collection.prototype.get = this.Collection.prototype.toArray\n }\n\n async connect({ getToken, ws_url }: { getToken: (opts?: { forceRefresh?: boolean }) => Promise<string>, ws_url?: string }) {\n const WS_URL = ws_url || 'wss://pds.basic.id/ws'\n\n log('Connecting to', WS_URL)\n\n // Store getToken in module-level registry (not in options) because\n // dexie-syncable serializes options into IndexedDB via structured clone,\n // which cannot handle functions.\n setTokenGetter(WS_URL, getToken)\n\n await this.updateSyncNodes();\n \n log('Starting connection...')\n return this.syncable.connect(\"websocket\", WS_URL, { schema: this.basic_schema });\n }\n\n async disconnect({ ws_url }: { ws_url?: string } = {}) {\n const WS_URL = ws_url || 'wss://pds.basic.id/ws'\n\n return this.syncable.disconnect(WS_URL) \n }\n\n private async updateSyncNodes() {\n try {\n const syncNodes = await this.table('_syncNodes').toArray();\n const localSyncNodes = syncNodes.filter(node => node.type === 'local');\n log('Local sync nodes:', localSyncNodes);\n\n if (localSyncNodes.length > 1) {\n\n \n const largestNodeId = Math.max(...localSyncNodes.map(node => node.id));\n // Check if the largest node is already the master\n const largestNode = localSyncNodes.find(node => node.id === largestNodeId);\n if (largestNode && largestNode.isMaster === 1) {\n log('Largest node is already the master. No changes needed.');\n return; // Exit the function early as no changes are needed\n }\n\n\n log('Largest node id:', largestNodeId);\n log('HEISENBUG: More than one local sync node found.')\n\n for (const node of localSyncNodes) {\n log(`Local sync node keys:`, node.id, node.isMaster);\n await this.table('_syncNodes').update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });\n\n log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? 'master' : '0'}`);\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n if (typeof window !== 'undefined') {\n window.location.reload();\n }\n }\n\n log('Sync nodes updated');\n } catch (error) {\n console.error('Error updating _syncNodes table:', error);\n }\n }\n\n handleStatusChange(fn: any) {\n this.syncable.on(\"statusChanged\", fn)\n }\n\n\n _convertSchemaToDxSchema(schema: any) {\n const stores = Object.entries(schema.tables).map(([key, table]: any) => {\n const indexedFields = Object.entries(table.fields)\n .filter(([, field]: any) => field.indexed)\n .map(([fieldKey]: any) => `,${fieldKey}`)\n .join('')\n return {\n [key]: 'id' + indexedFields\n }\n })\n\n return Object.assign({}, ...stores)\n }\n\n debugeroo() {\n return this.syncable\n }\n\n collection<T extends { id: string } = Record<string, any> & { id: string }>(name: string) {\n // Validate table exists in schema\n if (this.basic_schema?.tables && !this.basic_schema.tables[name]) {\n throw new Error(`Table \"${name}\" not found in schema`)\n }\n\n const table = this.table(name)\n\n return {\n /**\n * Returns the underlying Dexie table\n * @type {Dexie.Table}\n */\n ref: table,\n\n // --- WRITE ---- // \n\n /**\n * Add a new record - returns the full object with generated id\n */\n add: async (data: Omit<T, 'id'>): Promise<T> => {\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n throw new Error(valid.message || 'Data validation failed')\n }\n\n const id = uuidv7()\n const fullData = { id, ...data } as T\n \n await table.add(fullData)\n return fullData\n },\n\n /**\n * Put (upsert) a record - returns the full object\n */\n put: async (data: T): Promise<T> => {\n if (!data.id) {\n throw new Error('put() requires an id field')\n }\n\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n throw new Error(valid.message || 'Data validation failed')\n }\n\n await table.put(data)\n return data\n },\n\n /**\n * Update an existing record - returns updated object or null\n */\n update: async (id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null> => {\n if (!id) {\n throw new Error('update() requires an id')\n }\n\n const valid = validateData(this.basic_schema, name, data, false)\n if (!valid.valid) {\n log('Invalid data', valid)\n throw new Error(valid.message || 'Data validation failed')\n }\n\n const updated = await table.update(id, data)\n if (updated === 0) {\n return null\n }\n\n // Fetch and return the updated record\n const record = await table.get(id)\n return (record as T) || null\n },\n\n /**\n * Delete a record - returns true if deleted, false if not found\n */\n delete: async (id: string): Promise<boolean> => {\n if (!id) {\n throw new Error('delete() requires an id')\n }\n\n // Check if record exists first\n const exists = await table.get(id)\n if (!exists) {\n return false\n }\n\n await table.delete(id)\n return true\n },\n\n // --- READ ---- // \n\n /**\n * Get a single record by id - returns null if not found\n */\n get: async (id: string): Promise<T | null> => {\n if (!id) {\n throw new Error('get() requires an id')\n }\n\n const record = await table.get(id)\n return (record as T) || null\n },\n\n /**\n * Get all records in the collection\n */\n getAll: async (): Promise<T[]> => {\n return table.toArray() as Promise<T[]>\n },\n\n // --- QUERY ---- // \n\n /**\n * Filter records using a predicate function\n */\n filter: async (fn: (item: T) => boolean): Promise<T[]> => {\n return table.filter(fn).toArray() as Promise<T[]>\n },\n\n /**\n * Get the raw Dexie table for advanced queries\n * @deprecated Use ref instead\n */\n query: () => table,\n }\n }\n}\n","/**\n * Core DB types for Basic SDK\n * These interfaces are implemented by both SyncDB (Dexie-based) and RemoteDB (REST-based)\n */\n\n/**\n * Collection interface for CRUD operations on a table\n * All write operations return the full object (not just the id)\n */\nexport interface Collection<T extends { id: string } = Record<string, any> & { id: string }> {\n /**\n * Add a new record to the collection\n * @param data - The data to add (without id, which will be generated)\n * @returns The created object with its generated id\n */\n add(data: Omit<T, 'id'>): Promise<T>\n\n /**\n * Put (upsert) a record - requires id\n * @param data - The full object including id\n * @returns The upserted object\n */\n put(data: T): Promise<T>\n\n /**\n * Update an existing record by id\n * @param id - The record id to update\n * @param data - Partial data to merge\n * @returns The updated object, or null if not found\n */\n update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null>\n\n /**\n * Delete a record by id\n * @param id - The record id to delete\n * @returns true if deleted, false if not found\n */\n delete(id: string): Promise<boolean>\n\n /**\n * Get a single record by id\n * @param id - The record id to fetch\n * @returns The object or null if not found\n */\n get(id: string): Promise<T | null>\n\n /**\n * Get all records in the collection\n * @returns Array of all objects\n */\n getAll(): Promise<T[]>\n\n /**\n * Filter records using a predicate function\n * @param fn - Filter function that returns true for matches\n * @returns Array of matching objects\n */\n filter(fn: (item: T) => boolean): Promise<T[]>\n\n /**\n * Direct access to underlying storage (optional)\n * For sync mode: Dexie table reference\n * For remote mode: undefined\n */\n ref?: any\n}\n\n/**\n * BasicDB interface - factory for creating collections\n */\nexport interface BasicDB {\n /**\n * Get a collection by name\n * @param name - The table/collection name (must match schema)\n * @returns A Collection instance for CRUD operations\n */\n collection<T extends { id: string } = Record<string, any> & { id: string }>(name: string): Collection<T>\n}\n\n/**\n * Database mode - determines which implementation is used\n * - 'sync': Uses Dexie + WebSocket for local-first sync (default)\n * - 'remote': Uses REST API calls directly to server\n */\nexport type DBMode = 'sync' | 'remote'\n\n/**\n * Auth error information passed to onAuthError callback\n */\nexport interface AuthError {\n status: number\n message: string\n response?: any\n /** Classifies the error for UI display (e.g. \"session expired\" vs \"forbidden\") */\n errorType: 'expired' | 'forbidden' | 'revoked' | 'network' | 'unknown'\n /** True if this error occurred after a retry with a refreshed token */\n afterRetry: boolean\n}\n\n/**\n * Custom error class for Remote DB API errors\n * Includes HTTP status code for reliable error handling\n */\nexport class RemoteDBError extends Error {\n status: number\n response?: any\n\n constructor(message: string, status: number, response?: any) {\n super(message)\n this.name = 'RemoteDBError'\n this.status = status\n this.response = response\n }\n}\n\n/**\n * Options for getToken (e.g. force refresh after 401)\n */\nexport interface GetTokenOptions {\n /** When true, refresh the access token before returning (e.g. after server returned 401) */\n forceRefresh?: boolean\n}\n\n/**\n * Configuration for RemoteDB\n */\nexport interface RemoteDBConfig {\n serverUrl: string\n projectId: string\n getToken: (options?: GetTokenOptions) => Promise<string>\n schema?: any\n /** Enable debug logging (default: false) */\n debug?: boolean\n /**\n * Optional callback when authentication fails (401 error after retry)\n * Use this to show login UI or redirect to sign-in\n */\n onAuthError?: (error: AuthError) => void\n}\n\n","import { Collection, RemoteDBConfig, RemoteDBError } from './types'\nimport { validateData } from '@basictech/schema'\n\n/**\n * Error thrown when user is not authenticated\n */\nexport class NotAuthenticatedError extends Error {\n constructor(message: string = 'Not authenticated') {\n super(message)\n this.name = 'NotAuthenticatedError'\n }\n}\n\n/**\n * RemoteCollection - REST API based implementation of the Collection interface\n * All operations make HTTP calls to the Basic API server\n */\nexport class RemoteCollection<T extends { id: string } = Record<string, any> & { id: string }> implements Collection<T> {\n private tableName: string\n private config: RemoteDBConfig\n\n constructor(tableName: string, config: RemoteDBConfig) {\n this.tableName = tableName\n this.config = config\n }\n\n private log(...args: any[]) {\n if (this.config.debug) {\n console.log('[RemoteDB]', ...args)\n }\n }\n\n /**\n * Check if an error is a \"not authenticated\" error\n */\n private isNotAuthenticatedError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase()\n return message.includes('no token') || \n message.includes('not authenticated') ||\n message.includes('please sign in')\n }\n return false\n }\n\n /**\n * Helper to make authenticated API requests\n * Automatically retries once on 401 (token expired) by refreshing the token\n */\n private async request<R>(\n method: string,\n path: string,\n body?: any,\n isRetry: boolean = false\n ): Promise<R> {\n // Try to get token - may throw if not authenticated\n const token = await this.config.getToken()\n const url = `${this.config.serverUrl}${path}`\n\n this.log(`${method} ${url}`, body ? JSON.stringify(body) : '')\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${token}`\n }\n if (body) {\n headers['Content-Type'] = 'application/json'\n }\n\n const response = await fetch(url, {\n method,\n headers,\n ...(body ? { body: JSON.stringify(body) } : {})\n })\n\n const responseData = await response.json().catch(() => ({}))\n\n if (!response.ok) {\n // Handle 401 Unauthorized - force refresh then retry once\n if (response.status === 401 && !isRetry) {\n this.log('Got 401, forcing token refresh and retrying...')\n await this.config.getToken({ forceRefresh: true })\n return this.request<R>(method, path, body, true)\n }\n\n if (this.config.debug) {\n console.error(`[RemoteDB] Error ${response.status}:`, responseData)\n }\n \n // Call onAuthError callback for auth/authz errors\n if (this.config.onAuthError) {\n if (response.status === 401) {\n this.config.onAuthError({\n status: response.status,\n message: 'Authentication failed',\n response: responseData,\n errorType: 'expired',\n afterRetry: isRetry,\n })\n } else if (response.status === 403) {\n this.config.onAuthError({\n status: response.status,\n message: responseData.message || 'Forbidden - insufficient permissions or missing scope',\n response: responseData,\n errorType: 'forbidden',\n afterRetry: isRetry,\n })\n }\n }\n\n const errorMessage = responseData.message || responseData.error || responseData.detail || \n (typeof responseData === 'string' ? responseData : `API request failed: ${response.status}`)\n throw new RemoteDBError(errorMessage, response.status, responseData)\n }\n\n this.log('Response:', responseData)\n return responseData\n }\n\n /**\n * Validate data against schema if available\n */\n private validateData(data: any, checkRequired: boolean = true): void {\n if (this.config.schema) {\n const result = validateData(this.config.schema, this.tableName, data, checkRequired)\n if (!result.valid) {\n throw new Error(result.message || 'Data validation failed')\n }\n }\n }\n\n /**\n * Get the base path for this collection\n */\n private get basePath(): string {\n return `/account/${this.config.projectId}/db/${this.tableName}`\n }\n\n /**\n * Add a new record to the collection\n * The server generates the ID\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async add(data: Omit<T, 'id'>): Promise<T> {\n this.validateData(data, true)\n\n try {\n const result = await this.request<{ data: T }>(\n 'POST',\n this.basePath,\n { value: data }\n )\n // Server returns the created record with the generated ID\n return result.data\n } catch (error) {\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to add items')\n }\n throw error\n }\n }\n\n /**\n * Put (upsert) a record - requires id\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async put(data: T): Promise<T> {\n if (!data.id) {\n throw new Error('put() requires an id field')\n }\n\n // Extract id from data, send the rest in the body\n const { id, ...rest } = data\n this.validateData(rest, true)\n\n try {\n const result = await this.request<{ data: T }>(\n 'PUT',\n `${this.basePath}/${id}`,\n { value: rest }\n )\n return result.data || data\n } catch (error) {\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to update items')\n }\n throw error\n }\n }\n\n /**\n * Update an existing record by id\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async update(id: string, data: Partial<Omit<T, 'id'>>): Promise<T | null> {\n if (!id) {\n throw new Error('update() requires an id')\n }\n\n this.validateData(data, false)\n\n try {\n const result = await this.request<{ data: T }>(\n 'PATCH',\n `${this.basePath}/${id}`,\n { value: data }\n )\n\n return result.data || null\n } catch (error) {\n // If record not found, return null instead of throwing\n if (error instanceof RemoteDBError && error.status === 404) {\n return null\n }\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to update items')\n }\n throw error\n }\n }\n\n /**\n * Delete a record by id\n * Requires authentication - throws NotAuthenticatedError if not signed in\n */\n async delete(id: string): Promise<boolean> {\n if (!id) {\n throw new Error('delete() requires an id')\n }\n\n try {\n await this.request<any>(\n 'DELETE',\n `${this.basePath}/${id}`\n )\n return true\n } catch (error) {\n // If record not found, return false instead of throwing\n if (error instanceof RemoteDBError && error.status === 404) {\n return false\n }\n if (this.isNotAuthenticatedError(error)) {\n throw new NotAuthenticatedError('Sign in required to delete items')\n }\n throw error\n }\n }\n\n /**\n * Get a single record by id\n * Returns null if not authenticated (graceful degradation for read operations)\n */\n async get(id: string): Promise<T | null> {\n if (!id) {\n throw new Error('get() requires an id')\n }\n\n try {\n // Use the API's id query parameter for efficient single-record fetch\n const result = await this.request<{ data: T[] }>(\n 'GET',\n `${this.basePath}?id=${id}`\n )\n return result.data?.[0] || null\n } catch (error) {\n // For get(), return null on any error (not found, not authenticated, etc.)\n if (this.isNotAuthenticatedError(error)) {\n this.log('Not authenticated - returning null for get()')\n }\n return null\n }\n }\n\n /**\n * Get all records in the collection\n * Returns empty array if not authenticated (graceful degradation for read operations)\n */\n async getAll(): Promise<T[]> {\n try {\n const result = await this.request<{ data: T[] }>(\n 'GET',\n this.basePath\n )\n return result.data || []\n } catch (error) {\n // If not authenticated, return empty array gracefully\n if (this.isNotAuthenticatedError(error)) {\n this.log('Not authenticated - returning empty array for getAll()')\n return []\n }\n throw error\n }\n }\n\n /**\n * Filter records using a predicate function\n * Note: This fetches all records and filters client-side\n * Returns empty array if not authenticated (graceful degradation for read operations)\n */\n async filter(fn: (item: T) => boolean): Promise<T[]> {\n const all = await this.getAll()\n return all.filter(fn)\n }\n\n /**\n * ref is not available for remote collections\n */\n ref = undefined\n}\n","import { BasicDB, Collection, RemoteDBConfig } from './types'\nimport { RemoteCollection } from './RemoteCollection'\n\n/**\n * RemoteDB - REST API based implementation of BasicDB\n * Creates RemoteCollection instances for each table\n */\nexport class RemoteDB implements BasicDB {\n private config: RemoteDBConfig\n private collections: Map<string, RemoteCollection<any>> = new Map()\n\n constructor(config: RemoteDBConfig) {\n this.config = config\n }\n\n /**\n * Get a collection by name\n * Collections are cached for reuse\n */\n collection<T extends { id: string } = Record<string, any> & { id: string }>(\n name: string\n ): Collection<T> {\n // Return cached collection if exists\n if (this.collections.has(name)) {\n return this.collections.get(name) as RemoteCollection<T>\n }\n\n // Validate table exists in schema if schema is provided\n if (this.config.schema?.tables && !this.config.schema.tables[name]) {\n throw new Error(`Table \"${name}\" not found in schema`)\n }\n\n // Create and cache new collection\n const collection = new RemoteCollection<T>(name, this.config)\n this.collections.set(name, collection)\n\n return collection\n }\n}\n\n","import { jwtDecode } from 'jwt-decode'\nimport { BasicStorage, STORAGE_KEYS } from '../../utils/storage'\nimport { normalizeClientId } from '../../utils/normalizeClientId'\nimport { resolveHandle } from '../../utils/resolveDid'\nimport { cleanOAuthParamsFromUrl } from '../../utils/network'\nimport { log } from '../../config'\n\n// --- PKCE helpers (RFC 7636) ---\n\nfunction generateCodeVerifier(): string {\n const array = new Uint8Array(32)\n crypto.getRandomValues(array)\n return base64UrlEncode(array)\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<{ challenge: string; method: 'S256' | 'plain' }> {\n if (typeof crypto === 'undefined' || !crypto.subtle) {\n log('crypto.subtle unavailable (non-secure context?) -- falling back to plain PKCE challenge')\n return { challenge: verifier, method: 'plain' }\n }\n const encoder = new TextEncoder()\n const data = encoder.encode(verifier)\n const digest = await crypto.subtle.digest('SHA-256', data)\n return { challenge: base64UrlEncode(new Uint8Array(digest)), method: 'S256' }\n}\n\nfunction base64UrlEncode(buffer: Uint8Array): string {\n let str = ''\n for (let i = 0; i < buffer.length; i++) {\n str += String.fromCharCode(buffer[i]!)\n }\n return btoa(str).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport type Token = {\n access_token: string\n token_type: string\n expires_in: number\n refresh_token: string\n}\n\nexport type User = {\n sub?: string\n name?: string\n email?: string\n picture?: string\n}\n\nexport type AuthResult = {\n success: boolean\n error?: string\n code?: string\n}\n\nexport type GetTokenOptions = {\n forceRefresh?: boolean\n}\n\nexport type PdsEndpoints = {\n pds_url: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint: string\n}\n\nexport type AuthManagerConfig = {\n projectId: string | undefined\n scopes: string\n pdsUrl: string\n adminUrl: string\n debug: boolean\n}\n\n/**\n * Framework-agnostic auth manager. Holds token state, handles OAuth flow,\n * token refresh (with mutex), and user info fetching.\n *\n * React integration: pass a state-setter as `notify` so the component\n * re-renders whenever auth state changes.\n */\nexport class AuthManager {\n // --- Public state (read by the UI layer) ---\n token: Token | null = null\n user: User | null = null\n isSignedIn: boolean = false\n isAuthReady: boolean = false\n did: string | null = null\n /** Space-separated scopes granted in the current access token */\n tokenScope: string | null = null\n /** Space-separated scopes originally requested in the auth config */\n requestedScopes: string\n\n readonly config: AuthManagerConfig\n readonly storage: BasicStorage\n\n /** True only during a user-initiated OAuth code exchange (not session restore) */\n private freshSignIn: boolean = false\n\n // --- Private ---\n private notify: () => void\n private refreshPromise: Promise<Token | null> | null = null\n private codeExchangePromise: Promise<Token | null> | null = null\n private pendingRefresh: boolean = false\n private isOnline: boolean = typeof navigator !== 'undefined' ? navigator.onLine : true\n private channel: BroadcastChannel | null = null\n\n constructor(config: AuthManagerConfig, storage: BasicStorage, notify: () => void) {\n this.config = config\n this.storage = storage\n this.notify = notify\n this.requestedScopes = config.scopes\n this.initCrossTabSync()\n }\n\n private initCrossTabSync(): void {\n if (typeof BroadcastChannel === 'undefined') return\n\n try {\n this.channel = new BroadcastChannel('basic-auth')\n this.channel.onmessage = (event) => {\n if (event.data?.type === 'token_refreshed') {\n log('Received token refresh from another tab')\n if (event.data.accessToken && this.token) {\n this.token = { ...this.token, access_token: event.data.accessToken }\n }\n if (event.data.did) this.did = event.data.did\n if (event.data.tokenScope) this.tokenScope = event.data.tokenScope\n this.notify()\n }\n if (event.data?.type === 'signed_in') {\n log('Received sign-in from another tab, reloading')\n // The signing-in tab already stored refresh_token and user_info\n // in localStorage. Reload so initialize() bootstraps the session.\n if (typeof window !== 'undefined') {\n window.location.reload()\n }\n }\n if (event.data?.type === 'signed_out') {\n log('Received sign-out from another tab, reloading')\n this.user = null\n this.isSignedIn = false\n this.token = null\n this.did = null\n this.tokenScope = null\n this.notify()\n // Storage and IndexedDB are already cleaned by the tab that initiated\n // sign-out. Reload so this tab picks up the clean slate.\n if (typeof window !== 'undefined') {\n window.location.reload()\n }\n }\n }\n } catch {\n log('BroadcastChannel not available for cross-tab sync')\n }\n }\n\n private broadcastTokenRefresh(): void {\n this.channel?.postMessage({\n type: 'token_refreshed',\n accessToken: this.token?.access_token,\n did: this.did,\n tokenScope: this.tokenScope,\n })\n }\n\n private broadcastSignIn(): void {\n this.channel?.postMessage({ type: 'signed_in' })\n }\n\n private broadcastSignOut(): void {\n this.channel?.postMessage({ type: 'signed_out' })\n }\n\n // ------------------------------------------------------------------\n // Public API\n // ------------------------------------------------------------------\n\n /**\n * Bootstrap auth: handle OAuth callback (?code=), restore session\n * from refresh token, or load cached user for offline mode.\n */\n async initialize(): Promise<void> {\n await this.storage.set(STORAGE_KEYS.DEBUG, this.config.debug ? 'true' : 'false')\n\n const storedServerUrl = await this.storage.get(STORAGE_KEYS.SERVER_URL)\n if (storedServerUrl && storedServerUrl !== this.config.pdsUrl) {\n log('PDS URL changed, clearing stored tokens')\n await this.clearStoredAuth()\n }\n await this.storage.set(STORAGE_KEYS.SERVER_URL, this.config.pdsUrl)\n\n try {\n const params = new URLSearchParams(window.location.search)\n\n if (params.has('code')) {\n const code = params.get('code')\n if (!code) {\n this.isAuthReady = true\n this.notify()\n return\n }\n\n const state = await this.storage.get(STORAGE_KEYS.AUTH_STATE)\n const urlState = params.get('state')\n if (!state || state !== urlState) {\n log('error: auth state does not match')\n this.isAuthReady = true\n this.notify()\n await this.storage.remove(STORAGE_KEYS.AUTH_STATE)\n cleanOAuthParamsFromUrl()\n return\n }\n\n await this.storage.remove(STORAGE_KEYS.AUTH_STATE)\n cleanOAuthParamsFromUrl()\n\n this.freshSignIn = true\n this.exchangeToken(code, false).catch((error) => {\n log('Error fetching token:', error)\n })\n } else {\n const refreshToken = await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n log('Found refresh token in storage, attempting to refresh access token')\n this.exchangeToken(refreshToken, true).catch((error) => {\n log('Error fetching refresh token:', error)\n })\n } else {\n const cachedUserInfo = await this.storage.get(STORAGE_KEYS.USER_INFO)\n if (cachedUserInfo) {\n try {\n this.user = JSON.parse(cachedUserInfo)\n this.isSignedIn = true\n log('Loaded cached user info for offline mode')\n } catch (error) {\n log('Error parsing cached user info:', error)\n }\n }\n this.isAuthReady = true\n this.notify()\n }\n }\n } catch (e) {\n log('error getting token', e)\n }\n }\n\n /**\n * Get a valid access token string. Refreshes proactively (5s buffer)\n * or on demand (forceRefresh). Mutex prevents concurrent refreshes.\n */\n async getToken(options?: GetTokenOptions): Promise<string> {\n log('getting token...')\n\n if (!this.token) {\n const refreshToken = await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n log('No token in memory, attempting to refresh from storage')\n\n if (this.refreshPromise) {\n log('Token refresh already in progress, waiting...')\n try {\n const newToken = await this.refreshPromise\n if (newToken?.access_token) {\n return newToken.access_token\n }\n } catch (error) {\n log('In-flight refresh failed:', error)\n throw error\n }\n }\n\n try {\n const newToken = await this.exchangeToken(refreshToken, true)\n if (newToken?.access_token) {\n return newToken.access_token\n }\n } catch (error) {\n log('Failed to refresh token from storage:', error)\n if (this.isNetworkError(error)) {\n throw new Error('Network offline - authentication will be retried when online')\n }\n throw new Error('Authentication expired. Please sign in again.')\n }\n }\n log('no token found')\n throw new Error('no token found')\n }\n\n const decoded = jwtDecode(this.token.access_token)\n const expirationBuffer = 5\n const isExpired = decoded.exp && decoded.exp < (Date.now() / 1000) + expirationBuffer\n const shouldRefresh = isExpired || options?.forceRefresh === true\n\n if (shouldRefresh) {\n log(options?.forceRefresh ? 'force refreshing token...' : 'token is expired - refreshing ...')\n\n if (this.refreshPromise) {\n log('Token refresh already in progress, waiting...')\n try {\n const newToken = await this.refreshPromise\n return newToken?.access_token || ''\n } catch (error) {\n log('In-flight refresh failed:', error)\n if (this.isNetworkError(error)) {\n log('Network issue - using expired token until network is restored')\n return this.token.access_token\n }\n throw error\n }\n }\n\n const refreshToken = this.token.refresh_token || await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n try {\n const newToken = await this.exchangeToken(refreshToken, true)\n return newToken?.access_token || ''\n } catch (error) {\n log('Failed to refresh expired token:', error)\n if (this.isNetworkError(error)) {\n log('Network issue - using expired token until network is restored')\n return this.token.access_token\n }\n throw new Error('Authentication expired. Please sign in again.')\n }\n } else {\n throw new Error('no refresh token available')\n }\n }\n\n return this.token.access_token || ''\n }\n\n async getSignInUrl(redirectUri?: string, endpoints?: PdsEndpoints): Promise<string> {\n log('getting sign in link...')\n\n if (!this.config.projectId) {\n throw new Error('Project ID is required to generate sign-in link')\n }\n\n const pdsEndpoints = endpoints || this.defaultPdsEndpoints()\n await this.storage.set(STORAGE_KEYS.PDS_ENDPOINTS, JSON.stringify(pdsEndpoints))\n\n const randomState = Math.random().toString(36).substring(6)\n await this.storage.set(STORAGE_KEYS.AUTH_STATE, randomState)\n\n const redirectUrl = redirectUri || window.location.href\n if (!redirectUrl || (!redirectUrl.startsWith('http://') && !redirectUrl.startsWith('https://'))) {\n throw new Error('Invalid redirect URI provided')\n }\n\n await this.storage.set(STORAGE_KEYS.REDIRECT_URI, redirectUrl)\n log('Stored redirect_uri for token exchange:', redirectUrl)\n\n // PKCE: generate code_verifier and code_challenge (RFC 7636)\n const codeVerifier = generateCodeVerifier()\n const { challenge: codeChallenge, method: challengeMethod } = await generateCodeChallenge(codeVerifier)\n await this.storage.set(STORAGE_KEYS.CODE_VERIFIER, codeVerifier)\n\n let baseUrl = pdsEndpoints.authorization_endpoint\n baseUrl += `?client_id=${encodeURIComponent(normalizeClientId(this.config.projectId, this.adminHostname))}`\n baseUrl += `&redirect_uri=${encodeURIComponent(redirectUrl)}`\n baseUrl += `&response_type=code`\n baseUrl += `&scope=${encodeURIComponent(this.config.scopes)}`\n baseUrl += `&state=${randomState}`\n baseUrl += `&code_challenge=${encodeURIComponent(codeChallenge)}`\n baseUrl += `&code_challenge_method=${challengeMethod}`\n\n log('Generated sign-in link successfully with scopes:', this.config.scopes)\n return baseUrl\n }\n\n async signIn(redirectUri?: string): Promise<void> {\n log('signing in...')\n\n if (!this.config.projectId) {\n log('Error: project_id is required for sign-in')\n throw new Error('Project ID is required for authentication')\n }\n\n const signInLink = await this.getSignInUrl(redirectUri)\n log('Generated sign-in link:', signInLink)\n\n try { new URL(signInLink) } catch {\n log('Error: Invalid sign-in link generated')\n throw new Error('Failed to generate valid sign-in URL')\n }\n\n window.location.href = signInLink\n }\n\n async signInWithHandle(handle: string): Promise<void> {\n log('signing in with handle:', handle)\n\n if (!this.config.projectId) {\n throw new Error('Project ID is required for authentication')\n }\n\n const resolved = await resolveHandle(handle)\n log('Resolved handle to PDS:', resolved.pdsUrl)\n\n const endpoints: PdsEndpoints = {\n pds_url: resolved.pdsUrl,\n authorization_endpoint: resolved.authorization_endpoint,\n token_endpoint: resolved.token_endpoint,\n userinfo_endpoint: resolved.userinfo_endpoint\n }\n\n const signInLink = await this.getSignInUrl(undefined, endpoints)\n log('Generated federated sign-in link:', signInLink)\n\n try { new URL(signInLink) } catch {\n throw new Error('Failed to generate valid sign-in URL')\n }\n\n window.location.href = signInLink\n }\n\n async signInWithCode(code: string, state?: string): Promise<AuthResult> {\n try {\n log('signInWithCode called with code:', code)\n\n if (!code || typeof code !== 'string') {\n return { success: false, error: 'Invalid authorization code' }\n }\n\n if (state) {\n const storedState = await this.storage.get(STORAGE_KEYS.AUTH_STATE)\n if (storedState && storedState !== state) {\n log('State parameter mismatch:', { provided: state, stored: storedState })\n return { success: false, error: 'State parameter mismatch' }\n }\n }\n\n await this.storage.remove(STORAGE_KEYS.AUTH_STATE)\n cleanOAuthParamsFromUrl()\n\n this.freshSignIn = true\n const token = await this.exchangeToken(code, false)\n if (token) {\n log('signInWithCode successful')\n return { success: true }\n } else {\n return { success: false, error: 'Failed to exchange code for token' }\n }\n } catch (error) {\n log('signInWithCode error:', error)\n return {\n success: false,\n error: (error as Error).message || 'Authentication failed'\n }\n }\n }\n\n /**\n * Clear auth state and storage. Does NOT handle sync/DB cleanup —\n * the UI layer (BasicProvider) wraps this to add sync teardown.\n */\n async signOut(): Promise<void> {\n log('signing out!')\n this.resetAuthState()\n\n await this.storage.remove(STORAGE_KEYS.AUTH_STATE)\n await this.storage.remove(STORAGE_KEYS.LAST_CONNECT_REPORT)\n await this.clearStoredAuth()\n\n this.broadcastSignOut()\n this.notify()\n }\n\n hasScope(scope: string): boolean {\n if (!this.tokenScope) return false\n return this.tokenScope.split(/[\\s,]+/).filter(Boolean).includes(scope)\n }\n\n /**\n * Returns scopes that were requested but not granted in the current token.\n * Useful after login or when a 403 is returned.\n */\n missingScopes(): string[] {\n const requested = this.requestedScopes.split(/[\\s,]+/).filter(Boolean)\n if (!this.tokenScope) return requested\n const granted = new Set(this.tokenScope.split(/[\\s,]+/).filter(Boolean))\n return requested.filter(s => !granted.has(s))\n }\n\n /**\n * Register online/offline handlers that retry pending refreshes.\n * Returns a cleanup function for useEffect teardown.\n */\n setupNetworkListeners(): () => void {\n const handleOnline = async () => {\n log('Network came back online')\n this.isOnline = true\n if (this.pendingRefresh && this.token) {\n log('Retrying pending token refresh')\n this.pendingRefresh = false\n const refreshToken = this.token.refresh_token || await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN)\n if (refreshToken) {\n this.exchangeToken(refreshToken, true).catch(error => {\n log('Retry refresh failed:', error)\n })\n }\n }\n }\n\n const handleOffline = () => {\n log('Network went offline')\n this.isOnline = false\n }\n\n window.addEventListener('online', handleOnline)\n window.addEventListener('offline', handleOffline)\n\n return () => {\n window.removeEventListener('online', handleOnline)\n window.removeEventListener('offline', handleOffline)\n }\n }\n\n // ------------------------------------------------------------------\n // Private\n // ------------------------------------------------------------------\n\n private get adminHostname(): string {\n try { return new URL(this.config.adminUrl).hostname }\n catch { return 'api.basic.tech' }\n }\n\n private defaultPdsEndpoints(): PdsEndpoints {\n return {\n pds_url: this.config.pdsUrl,\n authorization_endpoint: `${this.config.pdsUrl}/auth/authorize`,\n token_endpoint: `${this.config.pdsUrl}/auth/token`,\n userinfo_endpoint: `${this.config.pdsUrl}/auth/userinfo`\n }\n }\n\n private async getActivePdsEndpoints(): Promise<PdsEndpoints> {\n const stored = await this.storage.get(STORAGE_KEYS.PDS_ENDPOINTS)\n if (stored) {\n try { return JSON.parse(stored) as PdsEndpoints } catch { /* fall through */ }\n }\n return this.defaultPdsEndpoints()\n }\n\n private async reportConnection(accessToken: string): Promise<void> {\n if (!this.config.projectId || !this.config.adminUrl) return\n const lastReport = await this.storage.get(STORAGE_KEYS.LAST_CONNECT_REPORT)\n if (lastReport) {\n const elapsed = Date.now() - parseInt(lastReport, 10)\n if (elapsed < 24 * 60 * 60 * 1000) return\n }\n try {\n await fetch(`${this.config.adminUrl}/project/${this.config.projectId}/user/connect`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: accessToken })\n })\n await this.storage.set(STORAGE_KEYS.LAST_CONNECT_REPORT, Date.now().toString())\n log('Reported connection to admin server')\n } catch (err) {\n log('Failed to report connection (non-blocking):', err)\n }\n }\n\n /**\n * After a new token is stored, decode JWT claims and fetch user info.\n */\n private async processNewToken(): Promise<void> {\n if (!this.token) {\n this.isAuthReady = true\n this.notify()\n return\n }\n\n try {\n const decoded = jwtDecode<{ sub?: string; scope?: string; typ?: string; exp?: number }>(this.token.access_token)\n\n if (decoded.sub) this.did = decoded.sub\n if (decoded.scope) this.tokenScope = decoded.scope\n\n const expirationBuffer = 5\n const isExpired = decoded.exp && decoded.exp < (Date.now() / 1000) + expirationBuffer\n\n if (isExpired) {\n log('token is expired - refreshing ...')\n const refreshToken = this.token.refresh_token\n if (!refreshToken) {\n log('Error: No refresh token available for expired token')\n this.isAuthReady = true\n this.notify()\n return\n }\n try {\n const newToken = await this.exchangeToken(refreshToken, true)\n await this.fetchUser(newToken?.access_token || '')\n } catch (error) {\n log('Failed to refresh token in processNewToken:', error)\n if (this.isNetworkError(error)) {\n log('Network issue - continuing with expired token until online')\n await this.fetchUser(this.token.access_token)\n } else {\n this.isAuthReady = true\n this.notify()\n }\n }\n } else {\n await this.fetchUser(this.token.access_token)\n }\n } catch (error) {\n log('Error processing token:', error)\n this.isAuthReady = true\n this.notify()\n }\n }\n\n private async fetchUser(accessToken: string): Promise<void> {\n log('fetching user')\n try {\n const endpoints = await this.getActivePdsEndpoints()\n const response = await fetch(endpoints.userinfo_endpoint, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${accessToken}` }\n })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch user info: ${response.status}`)\n }\n\n const user = await response.json()\n\n if (user.error) {\n log('error fetching user', user.error)\n throw new Error(`User info error: ${user.error}`)\n }\n\n if (this.token?.refresh_token) {\n await this.storage.set(STORAGE_KEYS.REFRESH_TOKEN, this.token.refresh_token)\n }\n\n await this.storage.set(STORAGE_KEYS.USER_INFO, JSON.stringify(user))\n log('Cached user info in storage')\n\n this.user = user\n this.isSignedIn = true\n this.isAuthReady = true\n\n if (this.freshSignIn) {\n this.freshSignIn = false\n this.broadcastSignIn()\n } else {\n this.broadcastTokenRefresh()\n }\n\n this.notify()\n } catch (error) {\n log('Failed to fetch user info:', error)\n this.isAuthReady = true\n this.notify()\n }\n }\n\n /**\n * Exchange an auth code or refresh token for an access token.\n * Handles mutex (one in-flight refresh), token validation, and\n * triggers processNewToken on success.\n */\n private async exchangeToken(codeOrRefreshToken: string, isRefreshToken: boolean): Promise<Token | null> {\n if (!codeOrRefreshToken || codeOrRefreshToken.trim() === '') {\n const errorMsg = isRefreshToken ? 'Refresh token is empty or undefined' : 'Authorization code is empty or undefined'\n log('Error:', errorMsg)\n throw new Error(errorMsg)\n }\n\n if (isRefreshToken && this.refreshPromise) {\n log('Reusing in-flight refresh token request')\n return this.refreshPromise\n }\n\n if (!isRefreshToken && this.codeExchangePromise) {\n log('Reusing in-flight code exchange request')\n return this.codeExchangePromise\n }\n\n const tokenPromise = (async (): Promise<Token | null> => {\n try {\n if (!this.isOnline) {\n log('Network is offline, marking refresh as pending')\n this.pendingRefresh = true\n throw new Error('Network offline - refresh will be retried when online')\n }\n\n const endpoints = await this.getActivePdsEndpoints()\n let requestBody: any\n\n if (isRefreshToken) {\n requestBody = {\n grant_type: 'refresh_token',\n refresh_token: codeOrRefreshToken\n }\n if (this.config.projectId) {\n requestBody.client_id = normalizeClientId(this.config.projectId, this.adminHostname)\n }\n } else {\n requestBody = {\n grant_type: 'authorization_code',\n code: codeOrRefreshToken\n }\n\n const storedRedirectUri = await this.storage.get(STORAGE_KEYS.REDIRECT_URI)\n if (storedRedirectUri) {\n requestBody.redirect_uri = storedRedirectUri\n log('Including redirect_uri in token exchange:', storedRedirectUri)\n } else {\n log('Warning: No redirect_uri found in storage for token exchange')\n }\n\n // PKCE: include code_verifier from the authorization request\n const codeVerifier = await this.storage.get(STORAGE_KEYS.CODE_VERIFIER)\n if (codeVerifier) {\n requestBody.code_verifier = codeVerifier\n }\n\n if (this.config.projectId) {\n requestBody.client_id = normalizeClientId(this.config.projectId, this.adminHostname)\n }\n }\n\n log('Token exchange request body:', {\n ...requestBody,\n ...(isRefreshToken ? { refresh_token: '[REDACTED]' } : { code: '[REDACTED]' }),\n ...(requestBody.code_verifier ? { code_verifier: '[REDACTED]' } : {}),\n })\n\n const token = await fetch(endpoints.token_endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestBody)\n })\n .then(response => response.json())\n .catch(error => {\n log('Network error fetching token:', error)\n if (!this.isOnline) {\n this.pendingRefresh = true\n throw new Error('Network offline - refresh will be retried when online')\n }\n throw new Error('Network error during token refresh')\n })\n\n if (token.access_token) {\n try {\n const decoded = jwtDecode<{ typ?: string }>(token.access_token)\n if (decoded.typ === 'refresh') {\n log('Error: received refresh token as access token')\n throw new Error('Invalid token: received refresh token instead of access token')\n }\n } catch (decodeError) {\n if ((decodeError as Error).message.includes('Invalid token')) {\n throw decodeError\n }\n log('Warning: could not decode access token for type check:', decodeError)\n }\n }\n\n if (token.error) {\n log('error fetching token', token.error)\n\n if (typeof token.error === 'string' && (token.error.includes('network') || token.error.includes('timeout'))) {\n this.pendingRefresh = true\n throw new Error('Network issue - refresh will be retried when online')\n }\n\n await this.clearStoredAuth()\n this.resetAuthState()\n this.notify()\n throw new Error(`Token refresh failed: ${token.error}`)\n } else {\n this.token = token\n this.pendingRefresh = false\n\n if (token.refresh_token) {\n await this.storage.set(STORAGE_KEYS.REFRESH_TOKEN, token.refresh_token)\n log('Updated refresh token in storage')\n }\n\n if (!isRefreshToken) {\n await this.storage.remove(STORAGE_KEYS.REDIRECT_URI)\n await this.storage.remove(STORAGE_KEYS.CODE_VERIFIER)\n log('Cleaned up redirect_uri and code_verifier from storage after successful exchange')\n }\n\n this.reportConnection(token.access_token).catch(() => {})\n\n await this.processNewToken()\n }\n\n return token\n } catch (error) {\n log('Token refresh error:', error)\n\n if (!this.isNetworkError(error)) {\n await this.clearStoredAuth()\n this.resetAuthState()\n this.notify()\n }\n\n throw error\n }\n })()\n\n if (isRefreshToken) {\n this.refreshPromise = tokenPromise\n tokenPromise.finally(() => {\n if (this.refreshPromise === tokenPromise) {\n this.refreshPromise = null\n log('Cleared refresh promise reference')\n }\n })\n } else {\n this.codeExchangePromise = tokenPromise\n tokenPromise.finally(() => {\n if (this.codeExchangePromise === tokenPromise) {\n this.codeExchangePromise = null\n log('Cleared code exchange promise reference')\n }\n })\n }\n\n return tokenPromise\n }\n\n private resetAuthState(): void {\n this.user = null\n this.isSignedIn = false\n this.token = null\n this.did = null\n this.tokenScope = null\n this.isAuthReady = true\n }\n\n private async clearStoredAuth(): Promise<void> {\n await this.storage.remove(STORAGE_KEYS.REFRESH_TOKEN)\n await this.storage.remove(STORAGE_KEYS.USER_INFO)\n await this.storage.remove(STORAGE_KEYS.REDIRECT_URI)\n await this.storage.remove(STORAGE_KEYS.CODE_VERIFIER)\n await this.storage.remove(STORAGE_KEYS.SERVER_URL)\n await this.storage.remove(STORAGE_KEYS.PDS_ENDPOINTS)\n }\n\n private isNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.includes('offline') || error.message.includes('Network')\n }\n return false\n }\n}\n","// Storage utilities for Basic React package\nexport interface BasicStorage {\n get(key: string): Promise<string | null>\n set(key: string, value: string): Promise<void>\n remove(key: string): Promise<void>\n}\n\nexport class LocalStorageAdapter implements BasicStorage {\n async get(key: string): Promise<string | null> {\n return localStorage.getItem(key)\n }\n \n async set(key: string, value: string): Promise<void> {\n localStorage.setItem(key, value)\n }\n \n async remove(key: string): Promise<void> {\n localStorage.removeItem(key)\n }\n}\n\nexport const STORAGE_KEYS = {\n REFRESH_TOKEN: 'basic_refresh_token',\n USER_INFO: 'basic_user_info',\n AUTH_STATE: 'basic_auth_state',\n REDIRECT_URI: 'basic_redirect_uri',\n SERVER_URL: 'basic_server_url',\n PDS_ENDPOINTS: 'basic_pds_endpoints',\n LAST_CONNECT_REPORT: 'basic_last_connect_report',\n DEBUG: 'basic_debug',\n CODE_VERIFIER: 'basic_code_verifier'\n} as const\n\nexport function getCookie(name: string): string {\n let cookieValue = '';\n if (document.cookie && document.cookie !== '') {\n const cookies = document.cookie.split(';');\n for (let i = 0; i < cookies.length; i++) {\n const cookie = cookies[i]?.trim();\n if (cookie && cookie.substring(0, name.length + 1) === (name + '=')) {\n cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\n break;\n }\n }\n }\n return cookieValue;\n}\n\nexport function setCookie(name: string, value: string, options?: { secure?: boolean, sameSite?: string, httpOnly?: boolean }): void {\n const opts = {\n secure: true,\n sameSite: 'Strict',\n httpOnly: false,\n ...options\n };\n \n let cookieString = `${name}=${value}`;\n if (opts.secure) cookieString += '; Secure';\n if (opts.sameSite) cookieString += `; SameSite=${opts.sameSite}`;\n if (opts.httpOnly) cookieString += '; HttpOnly';\n \n document.cookie = cookieString;\n}\n\nexport function clearCookie(name: string): void {\n document.cookie = `${name}=; Secure; SameSite=Strict`;\n}\n","const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\n/**\n * Normalize a project_id / client_id to the canonical did:web format\n * before sending it to the PDS.\n *\n * - did:web:... -> passthrough (already canonical)\n * - bare UUID -> did:web:{adminHostname}:projects:{hex}\n * - \"self\" -> passthrough\n */\nexport function normalizeClientId(projectId: string, adminHostname: string = 'api.basic.tech'): string {\n if (!projectId) return projectId\n if (projectId === 'self') return projectId\n if (projectId.startsWith('did:')) return projectId\n\n if (UUID_RE.test(projectId)) {\n const hex = projectId.replace(/-/g, '').toLowerCase()\n return `did:web:${adminHostname}:projects:${hex}`\n }\n\n return projectId\n}\n","export type ResolvedDid = {\n did: string\n handle?: string\n didDocument: Record<string, unknown>\n pdsUrl: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint: string\n}\n\n/**\n * Convert a did:web DID to the HTTPS URL where its DID document lives.\n *\n * did:web:pds.basic.id:did:abc123 -> https://pds.basic.id/did/abc123/did.json\n * did:web:example.com -> https://example.com/.well-known/did.json\n */\nexport function resolveDidWebUrl(did: string): string | null {\n if (!did.startsWith('did:web:')) return null\n\n const rest = did.slice(8) // strip 'did:web:'\n if (!rest) return null\n const parts = rest.split(':')\n\n // Decode the hostname (first part, may contain %3A for port)\n const hostname = parts[0]!.replace(/%3A/gi, ':')\n\n if (parts.length === 1) {\n return `https://${hostname}/.well-known/did.json`\n }\n\n const pathParts = parts.slice(1).map(p => decodeURIComponent(p))\n return `https://${hostname}/${pathParts.join('/')}/did.json`\n}\n\n/**\n * Given a DID document, extract PDS URL and discover OAuth endpoints.\n */\nasync function resolveFromDocument(did: string, didDocument: Record<string, unknown>): Promise<ResolvedDid> {\n const services = didDocument.service as Array<{ id: string; type: string; serviceEndpoint: string }> | undefined\n const pdsService = services?.find(\n (s) => s.id === '#basic_pds' || s.id === `${did}#basic_pds`\n )\n if (!pdsService) {\n throw new Error(`DID document has no #basic_pds service entry`)\n }\n const pdsUrl = pdsService.serviceEndpoint.replace(/\\/+$/, '')\n\n const oauthRes = await fetch(`${pdsUrl}/auth/.well-known/openid-configuration`)\n if (!oauthRes.ok) {\n throw new Error(`Failed to fetch OpenID configuration from ${pdsUrl}: ${oauthRes.status}`)\n }\n const oauth = await oauthRes.json()\n\n return {\n did,\n didDocument,\n pdsUrl,\n authorization_endpoint: oauth.authorization_endpoint,\n token_endpoint: oauth.token_endpoint,\n userinfo_endpoint: oauth.userinfo_endpoint,\n }\n}\n\n/**\n * Fetch a DID document by DID, extract the PDS URL, and discover OAuth endpoints.\n */\nexport async function resolveDid(did: string): Promise<ResolvedDid> {\n const url = resolveDidWebUrl(did)\n if (!url) {\n throw new Error(`Unsupported DID method: ${did}`)\n }\n\n const didRes = await fetch(url)\n if (!didRes.ok) {\n throw new Error(`Failed to fetch DID document at ${url}: ${didRes.status}`)\n }\n const didDocument = await didRes.json()\n\n return resolveFromDocument(did, didDocument)\n}\n\n/**\n * Resolve a handle (e.g. \"alice.basic.id\") to a DID and discover PDS + OAuth endpoints.\n *\n * Fetches https://{handle}/.well-known/did.json per the did:web spec.\n */\nexport async function resolveHandle(handle: string): Promise<ResolvedDid> {\n const res = await fetch(`https://${handle}/.well-known/did.json`)\n if (!res.ok) {\n throw new Error(`Handle resolution failed for ${handle}: ${res.status}`)\n }\n const didDocument = await res.json()\n const did = didDocument.id as string\n if (!did) {\n throw new Error(`Handle response has no 'id' field`)\n }\n\n const resolved = await resolveFromDocument(did, didDocument)\n resolved.handle = handle\n return resolved\n}\n","import { BasicStorage } from '../utils/storage'\nimport { log } from '../config'\n\nexport interface VersionInfo {\n version: string\n lastUpdated: number\n}\n\nexport interface Migration {\n fromVersion: string\n toVersion: string\n migrate: (storage: BasicStorage) => Promise<void>\n}\n\nexport class VersionUpdater {\n private storage: BasicStorage\n private currentVersion: string\n private migrations: Migration[]\n private versionKey = 'basic_app_version'\n\n constructor(storage: BasicStorage, currentVersion: string, migrations: Migration[] = []) {\n this.storage = storage\n this.currentVersion = currentVersion\n this.migrations = migrations.sort((a, b) => this.compareVersions(a.fromVersion, b.fromVersion))\n }\n\n /**\n * Check current stored version and run migrations if needed\n * Only compares major.minor versions, ignoring beta/prerelease parts\n * Example: \"0.7.0-beta.1\" and \"0.7.0\" are treated as the same version\n */\n async checkAndUpdate(): Promise<{ updated: boolean; fromVersion?: string; toVersion: string }> {\n const storedVersion = await this.getStoredVersion()\n \n if (!storedVersion) {\n // First time setup\n await this.setStoredVersion(this.currentVersion)\n return { updated: false, toVersion: this.currentVersion }\n }\n\n if (storedVersion === this.currentVersion) {\n return { updated: false, toVersion: this.currentVersion }\n }\n\n // Need to run migrations\n const migrationsToRun = this.getMigrationsToRun(storedVersion, this.currentVersion)\n \n if (migrationsToRun.length === 0) {\n // No migrations needed, just update version\n await this.setStoredVersion(this.currentVersion)\n return { updated: true, fromVersion: storedVersion, toVersion: this.currentVersion }\n }\n\n // Run migrations\n for (const migration of migrationsToRun) {\n try {\n log(`Running migration from ${migration.fromVersion} to ${migration.toVersion}`)\n await migration.migrate(this.storage)\n } catch (error) {\n console.error(`Migration failed from ${migration.fromVersion} to ${migration.toVersion}:`, error)\n throw new Error(`Migration failed: ${error}`)\n }\n }\n\n // Update to current version\n await this.setStoredVersion(this.currentVersion)\n return { updated: true, fromVersion: storedVersion, toVersion: this.currentVersion }\n }\n\n private async getStoredVersion(): Promise<string | null> {\n try {\n const versionData = await this.storage.get(this.versionKey)\n if (!versionData) return null\n \n const versionInfo: VersionInfo = JSON.parse(versionData)\n return versionInfo.version\n } catch (error) {\n console.warn('Failed to get stored version:', error)\n return null\n }\n }\n\n private async setStoredVersion(version: string): Promise<void> {\n const versionInfo: VersionInfo = {\n version,\n lastUpdated: Date.now()\n }\n await this.storage.set(this.versionKey, JSON.stringify(versionInfo))\n }\n\n private getMigrationsToRun(fromVersion: string, toVersion: string): Migration[] {\n return this.migrations.filter(migration => {\n const storedLessThanMigrationTo = this.compareVersions(fromVersion, migration.toVersion) < 0\n const currentGreaterThanOrEqualMigrationTo = this.compareVersions(toVersion, migration.toVersion) >= 0\n const shouldRun = storedLessThanMigrationTo && currentGreaterThanOrEqualMigrationTo\n log(`Migration ${migration.fromVersion} → ${migration.toVersion}: shouldRun=${shouldRun}`)\n return shouldRun\n })\n }\n\n /**\n * Simple semantic version comparison (major.minor only, ignoring beta/prerelease)\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\n private compareVersions(a: string, b: string): number {\n // Extract major.minor from version strings, ignoring beta/prerelease parts\n const aMajorMinor = this.extractMajorMinor(a)\n const bMajorMinor = this.extractMajorMinor(b)\n \n // Compare major version first\n if (aMajorMinor.major !== bMajorMinor.major) {\n return aMajorMinor.major - bMajorMinor.major\n }\n \n // Then compare minor version\n return aMajorMinor.minor - bMajorMinor.minor\n }\n\n /**\n * Extract major.minor from version string, ignoring beta/prerelease\n * Examples: \"0.7.0-beta.1\" -> {major: 0, minor: 7}\n * \"1.2.3\" -> {major: 1, minor: 2}\n */\n private extractMajorMinor(version: string): { major: number, minor: number } {\n // Remove beta/prerelease parts and split by dots\n const cleanVersion = version.split('-')[0]?.split('+')[0] || version\n const parts = cleanVersion.split('.').map(Number)\n \n return {\n major: parts[0] || 0,\n minor: parts[1] || 0\n }\n }\n\n /**\n * Add a migration to the updater\n */\n addMigration(migration: Migration): void {\n this.migrations.push(migration)\n this.migrations.sort((a, b) => this.compareVersions(a.fromVersion, b.fromVersion))\n }\n}\n\n/**\n * Create a simple version updater instance\n */\nexport function createVersionUpdater(\n storage: BasicStorage, \n currentVersion: string, \n migrations: Migration[] = []\n): VersionUpdater {\n return new VersionUpdater(storage, currentVersion, migrations)\n}\n","import { BasicStorage } from '../utils/storage'\nimport { Migration } from './versionUpdater'\nimport { log } from '../config'\n\nexport const addMigrationTimestamp: Migration = {\n fromVersion: '0.6.0',\n toVersion: '0.7.0',\n async migrate(storage: BasicStorage) {\n log('Running migration 0.6.0 → 0.7.0')\n storage.set('test_migration', 'true')\n }\n}\n\n\n/**\n * Get all available migrations\n */\nexport function getMigrations(): Migration[] {\n return [\n addMigrationTimestamp\n ]\n}\n","// Schema utilities for Basic React package\nimport { validateSchema, compareSchemas } from '@basictech/schema'\nimport { log } from '../config'\n\nexport async function getSchemaStatus(schema: any): Promise<{\n valid: boolean,\n status: string,\n latest: any\n}> {\n const projectId = schema.project_id\n const valid = validateSchema(schema)\n\n if (!valid.valid) {\n console.warn('BasicDB Error: your local schema is invalid. Please fix errors and try again - sync is disabled')\n return { \n valid: false, \n status: 'invalid',\n latest: null\n }\n }\n\n const latestSchema = await fetch(`https://api.basic.tech/project/${projectId}/schema`)\n .then(res => res.json())\n .then(data => data.data[0].schema)\n .catch(err => {\n return { \n valid: false, \n status: 'error',\n latest: null\n }\n })\n\n if (!latestSchema.version) {\n return { \n valid: false, \n status: 'error',\n latest: null\n }\n }\n\n if (latestSchema.version > schema.version) {\n // error_code: schema_behind\n console.warn('BasicDB Error: your local schema version is behind the latest. Found version:', schema.version, 'but expected', latestSchema.version, \" - sync is disabled\")\n return { \n valid: false, \n status: 'behind', \n latest: latestSchema\n }\n } else if (latestSchema.version < schema.version) {\n // error_code: schema_ahead\n console.warn('BasicDB Error: your local schema version is ahead of the latest. Found version:', schema.version, 'but expected', latestSchema.version, \" - sync is disabled\")\n return { \n valid: false, \n status: 'ahead', \n latest: latestSchema\n }\n } else if (latestSchema.version === schema.version) {\n const changes = compareSchemas(schema, latestSchema)\n if (changes.valid) {\n return { \n valid: true,\n status: 'current',\n latest: latestSchema\n }\n } else {\n // error_code: schema_conflict\n console.warn('BasicDB Error: your local schema is conflicting with the latest. Your version:', schema.version, 'does not match origin version', latestSchema.version, \" - sync is disabled\")\n return { \n valid: false, \n status: 'conflict',\n latest: latestSchema\n }\n }\n } else { \n return { \n valid: false, \n status: 'error',\n latest: null\n }\n }\n}\n\nexport async function validateAndCheckSchema(schema: any): Promise<{\n isValid: boolean,\n schemaStatus: { valid: boolean, status?: string, latest?: any },\n errors?: any[]\n}> {\n const valid = validateSchema(schema)\n if (!valid.valid) {\n log('Basic Schema is invalid!', valid.errors)\n console.group('Schema Errors')\n let errorMessage = ''\n valid.errors.forEach((error, index) => {\n log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`)\n errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}\\n`\n })\n console.groupEnd()\n \n return {\n isValid: false,\n schemaStatus: { valid: false },\n errors: valid.errors\n }\n }\n\n let schemaStatus: { valid: boolean, status?: string, latest?: any } = { valid: false }\n if (schema.version !== 0) {\n schemaStatus = await getSchemaStatus(schema)\n log('schemaStatus', schemaStatus)\n } else {\n schemaStatus = { valid: false, status: 'unpublished' }\n log(\"schema not published - at version 0\")\n }\n\n return {\n isValid: true,\n schemaStatus\n }\n}\n","import { useBasic, BasicProvider } from \"./AuthContext\";\nimport { useLiveQuery as useQuery } from \"dexie-react-hooks\";\n\nexport { useBasic, BasicProvider, useQuery }\nexport { BasicDevToolbar } from \"./dev/BasicDevToolbar\"\nexport type { BasicDevToolbarProps } from \"./dev/BasicDevToolbar\"\n\nexport type { \n AuthConfig, \n BasicStorage, \n LocalStorageAdapter, \n BasicProviderProps,\n BasicContextType,\n BasicSchemaDevInfo,\n AuthResult\n} from \"./AuthContext\"\nexport { DBStatus } from \"./AuthContext\"\n\n// Core DB exports\nexport type { \n DBMode, \n BasicDB, \n Collection, \n RemoteDBConfig,\n GetTokenOptions,\n AuthError\n} from \"./core/db\"\n\nexport { RemoteDB, RemoteCollection, RemoteDBError, NotAuthenticatedError } from \"./core/db\"\n\n// Storage utilities\nexport { STORAGE_KEYS } from \"./utils/storage\"\n\n// DID resolution\nexport { resolveDid, resolveHandle, resolveDidWebUrl } from \"./utils/resolveDid\"\nexport type { ResolvedDid } from \"./utils/resolveDid\""],"mappings":"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","names":["changes","baseRevision","partial","onChangesAccepted","requestId","version","DBStatus","useCallback","useState","Dexie","syncProtocol","Dexie","validateData","version","jsx","jsxs","BasicDevToolbar","useState","useCallback","error"]}