{"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"]}