@basictech/react 0.7.0-beta.4 → 0.7.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +12 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +179 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +179 -103
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/AuthContext.tsx +233 -120
- package/src/sync/index.ts +4 -4
- package/src/utils/storage.ts +1 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/AuthContext.tsx","../src/sync/index.ts","../src/sync/syncProtocol.js","../src/config.ts","../package.json","../src/updater/versionUpdater.ts","../src/updater/updateMigrations.ts","../src/utils/storage.ts","../src/utils/network.ts","../src/utils/schema.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { useBasic, BasicProvider, BasicStorage, LocalStorageAdapter, AuthConfig, BasicProviderProps } from \"./AuthContext\";\nimport { useLiveQuery as useQuery } from \"dexie-react-hooks\";\n// import { createVersionUpdater, VersionUpdater, Migration } from \"./versionUpdater\";\n\n\nexport {\n useBasic, BasicProvider, useQuery\n}\n\nexport type {\n AuthConfig, BasicStorage, LocalStorageAdapter, BasicProviderProps\n}","import React, { createContext, useContext, useEffect, useState, useRef } from 'react'\nimport { jwtDecode } from 'jwt-decode'\n\nimport { BasicSync } from './sync'\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'\n\nexport type AuthConfig = {\n scopes?: string | string[];\n server_url?: string;\n}\n\nexport type BasicProviderProps = {\n children: React.ReactNode;\n project_id?: string;\n schema?: any;\n debug?: boolean;\n storage?: BasicStorage;\n auth?: AuthConfig;\n}\n\nconst DEFAULT_AUTH_CONFIG: Required<AuthConfig> = {\n scopes: 'profile email app:admin',\n server_url: 'https://api.basic.tech'\n}\n\n\ntype BasicSyncType = {\n basic_schema: any;\n connect: (options: { access_token: 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\nexport const BasicContext = createContext<{\n unicorn: string,\n isAuthReady: boolean,\n isSignedIn: boolean,\n user: User | null,\n signout: () => Promise<void>,\n signin: () => Promise<void>,\n signinWithCode: (code: string, state?: string) => Promise<{ success: boolean, error?: string }>,\n getToken: () => Promise<string>,\n getSignInLink: (redirectUri?: string) => Promise<string>,\n db: any,\n dbStatus: DBStatus\n}>({\n unicorn: \"🦄\",\n isAuthReady: false,\n isSignedIn: false,\n user: null,\n signout: () => Promise.resolve(),\n signin: () => Promise.resolve(),\n signinWithCode: () => new Promise(() => { }),\n getToken: () => new Promise(() => { }),\n getSignInLink: () => Promise.resolve(\"\"),\n db: {},\n dbStatus: DBStatus.LOADING\n});\n\ntype ErrorObject = {\n code: string;\n title: string;\n message: string;\n}\n\nexport function BasicProvider({\n children,\n project_id,\n schema,\n debug = false,\n storage,\n auth\n}: BasicProviderProps) {\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 storageAdapter = storage || new LocalStorageAdapter();\n \n // Merge auth config with defaults\n const authConfig: Required<AuthConfig> = {\n scopes: auth?.scopes || DEFAULT_AUTH_CONFIG.scopes,\n server_url: auth?.server_url || DEFAULT_AUTH_CONFIG.server_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 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 function initDb(options: { shouldConnect: boolean }) {\n if (!syncRef.current) {\n log('Initializing Basic DB')\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 // syncRef.current.syncable.getStatus().then((status: number) => {\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 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 if (result.schemaStatus.valid) {\n initDb({ shouldConnect: true })\n } else {\n log('Schema is invalid!', result.schemaStatus)\n initDb({ shouldConnect: false })\n }\n\n checkForNewVersion()\n }\n\n if (schema) {\n checkSchema()\n } else {\n setIsReady(true)\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({ access_token: tok })\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 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 const user = await fetch(`${authConfig.server_url}/auth/userInfo`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${acc_token}`\n }\n })\n .then(response => response.json())\n .catch(error => log('Error:', error))\n\n if (user.error) {\n log('error fetching user', user.error)\n return\n } else {\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\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 const isExpired = decoded.exp && decoded.exp < Date.now() / 1000\n\n if (isExpired) {\n log('token is expired - refreshing ...')\n try {\n const newToken = await fetchToken(token?.refresh_token || '', 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 if (!signInLink || !signInLink.startsWith('https://')) {\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 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 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 const isExpired = decoded.exp && decoded.exp < Date.now() / 1000\n\n if (isExpired) {\n log('token is expired - refreshing ...')\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) => {\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 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 log('Updated access token in cookie')\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 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 const noDb = ({\n collection: () => {\n throw new Error('no basicdb found - initialization failed. double check your schema.')\n }\n })\n\n return (\n <BasicContext.Provider value={{\n unicorn: \"🦄\",\n isAuthReady,\n isSignedIn,\n user,\n signout,\n signin,\n signinWithCode,\n getToken,\n getSignInLink,\n db: syncRef.current ? syncRef.current : noDb,\n dbStatus\n }}>\n\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, PromiseExtended } from 'dexie';\nimport 'dexie-syncable';\nimport 'dexie-observable';\n\nimport { syncProtocol } from './syncProtocol'\nimport { log } from '../config'\n\nimport { validateSchema, validateData } from '@basictech/schema'\nsyncProtocol()\n\n\n// const DexieSyncStatus = {\n// \"-1\": \"ERROR\",\n// \"0\": \"OFFLINE\",\n// \"1\": \"CONNECTING\",\n// \"2\": \"ONLINE\",\n// \"3\": \"SYNCING\",\n// \"4\": \"ERROR_WILL_RETRY\"\n// }\n\n\n// const SERVER_URL = \"https://pds.basic.id\"\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 }: { access_token: string }) {\n const 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() {\n const 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(name: string) {\n // TODO: check against schema\n\n return {\n\n /**\n * Returns the underlying Dexie table\n * @type {Dexie.Table}\n */\n ref: this.table(name),\n\n // --- WRITE ---- // \n add: (data: any) => {\n // log(\"Adding data to\", name, data)\n\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n return Promise.reject({ ... valid })\n }\n\n return this.table(name).add({\n id: uuidv7(),\n ...data\n })\n\n },\n\n put: (data: any) => {\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n return Promise.reject({ ... valid })\n }\n\n return this.table(name).put({\n id: uuidv7(),\n ...data\n })\n },\n\n update: (id: string, data: any) => {\n const valid = validateData(this.basic_schema, name, data, false)\n if (!valid.valid) {\n log('Invalid data', valid)\n return Promise.reject({ ... valid })\n }\n\n return this.table(name).update(id, data)\n },\n\n delete: (id: string) => {\n return this.table(name).delete(id)\n },\n\n\n // --- READ ---- // \n\n get: async (id: string) => {\n return this.table(name).get(id) \n },\n\n getAll: async () => {\n return this.table(name).toArray();\n },\n\n // --- QUERY ---- // \n // TODO: lots to do here. simplifing creating querie, filtering/ordering/limit, and execute\n\n query: () => this.table(name),\n\n filter: (fn: any) => this.table(name).filter(fn).toArray(),\n\n }\n }\n}\n\nclass QueryMethod { \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","\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","{\n \"name\": \"@basictech/react\",\n \"version\": \"0.7.0-beta.3\",\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.0.8\",\n \"dexie-observable\": \"^4.0.1-beta.13\",\n \"dexie-react-hooks\": \"^1.1.7\",\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 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"],"mappings":"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","names":["useQuery","import_dexie","changes","baseRevision","partial","onChangesAccepted","requestId","key","uuidv7","version","import_schema","error","user","token"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/AuthContext.tsx","../src/sync/index.ts","../src/sync/syncProtocol.js","../src/config.ts","../package.json","../src/updater/versionUpdater.ts","../src/updater/updateMigrations.ts","../src/utils/storage.ts","../src/utils/network.ts","../src/utils/schema.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { useBasic, BasicProvider, BasicStorage, LocalStorageAdapter, AuthConfig, BasicProviderProps } from \"./AuthContext\";\nimport { useLiveQuery as useQuery } from \"dexie-react-hooks\";\n// import { createVersionUpdater, VersionUpdater, Migration } from \"./versionUpdater\";\n\n\nexport {\n useBasic, BasicProvider, useQuery\n}\n\nexport type {\n AuthConfig, BasicStorage, LocalStorageAdapter, BasicProviderProps\n}","import React, { createContext, useContext, useEffect, useState, useRef } from 'react'\nimport { jwtDecode } from 'jwt-decode'\n\nimport { BasicSync } from './sync'\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'\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 project_id?: string;\n schema?: any;\n debug?: boolean;\n storage?: BasicStorage;\n auth?: AuthConfig;\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\nexport const BasicContext = createContext<{\n unicorn: string,\n isAuthReady: boolean,\n isSignedIn: boolean,\n user: User | null,\n signout: () => Promise<void>,\n signin: () => Promise<void>,\n signinWithCode: (code: string, state?: string) => Promise<{ success: boolean, error?: string }>,\n getToken: () => Promise<string>,\n getSignInLink: (redirectUri?: string) => Promise<string>,\n db: any,\n dbStatus: DBStatus\n}>({\n unicorn: \"🦄\",\n isAuthReady: false,\n isSignedIn: false,\n user: null,\n signout: () => Promise.resolve(),\n signin: () => Promise.resolve(),\n signinWithCode: () => new Promise(() => { }),\n getToken: () => new Promise(() => { }),\n getSignInLink: () => Promise.resolve(\"\"),\n db: {},\n dbStatus: DBStatus.LOADING\n});\n\ntype ErrorObject = {\n code: string;\n title: string;\n message: string;\n}\n\nexport function BasicProvider({\n children,\n project_id,\n schema,\n debug = false,\n storage,\n auth\n}: BasicProviderProps) {\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 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 function initDb(options: { shouldConnect: boolean }) {\n if (!syncRef.current) {\n log('Initializing Basic DB')\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 // syncRef.current.syncable.getStatus().then((status: number) => {\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 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 if (result.schemaStatus.valid) {\n initDb({ shouldConnect: true })\n } else {\n log('Schema is invalid!', result.schemaStatus)\n initDb({ shouldConnect: false })\n }\n\n checkForNewVersion()\n }\n\n if (schema) {\n checkSchema()\n } else {\n setIsReady(true)\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 try {\n const newToken = await fetchToken(token?.refresh_token || '', 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 // 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 const noDb = ({\n collection: () => {\n throw new Error('no basicdb found - initialization failed. double check your schema.')\n }\n })\n\n return (\n <BasicContext.Provider value={{\n unicorn: \"🦄\",\n isAuthReady,\n isSignedIn,\n user,\n signout,\n signin,\n signinWithCode,\n getToken,\n getSignInLink,\n db: syncRef.current ? syncRef.current : noDb,\n dbStatus\n }}>\n\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, PromiseExtended } from 'dexie';\nimport 'dexie-syncable';\nimport 'dexie-observable';\n\nimport { syncProtocol } from './syncProtocol'\nimport { log } from '../config'\n\nimport { validateSchema, validateData } from '@basictech/schema'\nsyncProtocol()\n\n\n// const DexieSyncStatus = {\n// \"-1\": \"ERROR\",\n// \"0\": \"OFFLINE\",\n// \"1\": \"CONNECTING\",\n// \"2\": \"ONLINE\",\n// \"3\": \"SYNCING\",\n// \"4\": \"ERROR_WILL_RETRY\"\n// }\n\n\n// const SERVER_URL = \"https://pds.basic.id\"\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(name: string) {\n // TODO: check against schema\n\n return {\n\n /**\n * Returns the underlying Dexie table\n * @type {Dexie.Table}\n */\n ref: this.table(name),\n\n // --- WRITE ---- // \n add: (data: any) => {\n // log(\"Adding data to\", name, data)\n\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n return Promise.reject({ ... valid })\n }\n\n return this.table(name).add({\n id: uuidv7(),\n ...data\n })\n\n },\n\n put: (data: any) => {\n const valid = validateData(this.basic_schema, name, data)\n if (!valid.valid) {\n log('Invalid data', valid)\n return Promise.reject({ ... valid })\n }\n\n return this.table(name).put({\n id: uuidv7(),\n ...data\n })\n },\n\n update: (id: string, data: any) => {\n const valid = validateData(this.basic_schema, name, data, false)\n if (!valid.valid) {\n log('Invalid data', valid)\n return Promise.reject({ ... valid })\n }\n\n return this.table(name).update(id, data)\n },\n\n delete: (id: string) => {\n return this.table(name).delete(id)\n },\n\n\n // --- READ ---- // \n\n get: async (id: string) => {\n return this.table(name).get(id) \n },\n\n getAll: async () => {\n return this.table(name).toArray();\n },\n\n // --- QUERY ---- // \n // TODO: lots to do here. simplifing creating querie, filtering/ordering/limit, and execute\n\n query: () => this.table(name),\n\n filter: (fn: any) => this.table(name).filter(fn).toArray(),\n\n }\n }\n}\n\nclass QueryMethod { \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","\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","{\n \"name\": \"@basictech/react\",\n \"version\": \"0.7.0-beta.4\",\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.0.8\",\n \"dexie-observable\": \"^4.0.1-beta.13\",\n \"dexie-react-hooks\": \"^1.1.7\",\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,2CAAAA;AAAA;AAAA;;;ACAA,mBAA8E;AAC9E,wBAA0B;;;ACC1B,kBAA6B;AAC7B,IAAAC,gBAAuC;AACvC,4BAAO;AACP,8BAAO;;;ACJP,mBAAsB;;;ACIf,IAAM,MAAM,IAAI,SAAgB;AACnC,MAAI;AACA,QAAI,aAAa,QAAQ,aAAa,MAAM,QAAQ;AAChD,cAAQ,IAAI,WAAW,GAAG,IAAI;AAAA,IAClC;AAAA,EACJ,SAAS,GAAG;AAAA,EAEZ;AACJ;;;ADTO,IAAM,eAAe,WAAY;AACtC,MAAI,2BAA2B;AAE/B,MAAI,kBAAkB;AAEtB,qBAAM,SAAS,qBAAqB,aAAa;AAAA,IAC/C,MAAM,SACJ,SACA,KACA,SACA,cACA,gBACA,SACA,SACA,oBACA,mBACA,WACA,SACA;AAEA,UAAI,YAAY;AAChB,UAAI,kBAAkB,CAAC;AAGvB,UAAI,iBAAiB,GAAG;AACxB,UAAI,KAAK,IAAI,UAAU,GAAG;AAK1B,eAAS,YAAYC,UAASC,eAAcC,UAASC,oBAAmB;AACtE,YAAI,eAAeH,SAAQ,QAAQC,aAAY;AAC/C,UAAE;AACF,wBAAgB,UAAU,SAAS,CAAC,IAAIE;AAcxC,WAAG;AAAA,UACD,KAAK,UAAU;AAAA,YACb,MAAM;AAAA,YACN,SAASH;AAAA,YACT,SAASE;AAAA,YACT,cAAcD;AAAA,YACd;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAKA,SAAG,SAAS,SAAU,OAAO;AAK3B,YAAI,2CAA2C,QAAQ,cAAc;AACrE,WAAG;AAAA,UACD,KAAK,UAAU;AAAA,YACb,MAAM;AAAA,YACN,gBAAgB,QAAQ,kBAAkB;AAAA,YAC1C,WAAW,QAAQ;AAAA,YACnB,QAAQ,QAAQ;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MAEF;AAGA,SAAG,UAAU,SAAU,OAAO;AAC5B,WAAG,MAAM;AACT,YAAI,cAAc,KAAK;AACvB,gBAAQ,OAAO,SAAS,eAAe;AAAA,MACzC;AAGA,SAAG,UAAU,SAAU,OAAO;AAE5B,gBAAQ,oBAAoB,MAAM,QAAQ,eAAe;AAAA,MAC3D;AAQA,UAAI,eAAe;AAEnB,SAAG,YAAY,SAAU,OAAO;AAC9B,YAAI;AAWF,cAAI,oBAAoB,KAAK,MAAM,MAAM,IAAI;AAC7C,cAAI,qBAAqB,mBAAmB,EAAE,gBAAgB,aAAa,CAAC;AAE5E,cAAI,kBAAkB,QAAQ,kBAAkB;AAC9C,oBAAQ,iBAAiB,kBAAkB;AAC3C,oBAAQ,KAAK;AAEb,wBAAY,SAAS,cAAc,SAAS,iBAAiB;AAE7D,eAAG;AAAA,cACD,KAAK,UAAU;AAAA,gBACb,MAAM;AAAA,gBACN;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,WAAW,kBAAkB,QAAQ,WAAW;AAC9C;AAAA,cACE,kBAAkB;AAAA,cAClB,kBAAkB;AAAA,cAClB,kBAAkB;AAAA,YACpB;AACA,gBAAI,gBAAgB,CAAC,kBAAkB,SAAS;AAE9C,wBAAU;AAAA;AAAA,gBAER,OAAO,SACLD,UACAC,eACAC,UACAC,oBACA;AACA;AAAA,oBACEH;AAAA,oBACAC;AAAA,oBACAC;AAAA,oBACAC;AAAA,kBACF;AAAA,gBACF;AAAA;AAAA,gBAEA,YAAY,WAAY;AACtB,qBAAG,MAAM;AAAA,gBACX;AAAA,cACF,CAAC;AACD,6BAAe;AAAA,YACjB;AAAA,UACF,WAAW,kBAAkB,QAAQ,OAAO;AAC1C,gBAAIC,aAAY,kBAAkB;AAClC,gBAAI,iBAAiB,gBAAgBA,WAAU,SAAS,CAAC;AACzD,2BAAe;AACf,mBAAO,gBAAgBA,WAAU,SAAS,CAAC;AAAA,UAC7C,WAAW,kBAAkB,QAAQ,SAAS;AAC5C,gBAAIA,aAAY,kBAAkB;AAClC,eAAG,MAAM;AACT,oBAAQ,kBAAkB,SAAS,QAAQ;AAAA,UAC7C,OAAO;AACL,gBAAI,mBAAmB,iBAAiB;AACxC,eAAG,MAAM;AACT,oBAAQ,mBAAmB,QAAQ;AAAA,UACrC;AAAA,QACF,SAAS,GAAG;AACV,aAAG,MAAM;AACT,cAAI,gBAAgB,CAAC;AACrB,kBAAQ,GAAG,QAAQ;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AD5KA,oBAA6C;AAC7C,aAAa;AAgBN,IAAM,YAAN,cAAwB,oBAAM;AAAA,EACnC;AAAA,EAEA,YAAY,MAAc,SAAc;AACtC,UAAM,MAAM,OAAO;AAOnB,SAAK,eAAe,QAAQ;AAC5B,SAAK,QAAQ,CAAC,EAAE,OAAO,KAAK,yBAAyB,KAAK,YAAY,CAAC;AAEvE,SAAK,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AAMzB,SAAK,WAAW,UAAU,MAAM,KAAK,WAAW,UAAU;AAAA,EAS5D;AAAA,EAEA,MAAM,QAAQ,EAAE,cAAc,OAAO,GAA8C;AACjF,UAAM,SAAS,UAAU;AAEzB,QAAI,iBAAiB,MAAM;AAE3B,UAAM,KAAK,gBAAgB;AAE3B,QAAI,wBAAwB;AAC5B,WAAO,KAAK,SAAS,QAAQ,aAAa,QAAQ,EAAE,WAAW,cAAc,QAAQ,KAAK,aAAa,CAAC;AAAA,EAC1G;AAAA,EAEA,MAAM,WAAW,EAAE,OAAO,IAAyB,CAAC,GAAG;AACrD,UAAM,SAAS,UAAU;AAEzB,WAAO,KAAK,SAAS,WAAW,MAAM;AAAA,EACxC;AAAA,EAEA,MAAc,kBAAkB;AAC9B,QAAI;AACF,YAAM,YAAY,MAAM,KAAK,MAAM,YAAY,EAAE,QAAQ;AACzD,YAAM,iBAAiB,UAAU,OAAO,UAAQ,KAAK,SAAS,OAAO;AACrE,UAAI,qBAAqB,cAAc;AAEvC,UAAI,eAAe,SAAS,GAAG;AAG7B,cAAM,gBAAgB,KAAK,IAAI,GAAG,eAAe,IAAI,UAAQ,KAAK,EAAE,CAAC;AAErE,cAAM,cAAc,eAAe,KAAK,UAAQ,KAAK,OAAO,aAAa;AACzE,YAAI,eAAe,YAAY,aAAa,GAAG;AAC7C,cAAI,wDAAwD;AAC5D;AAAA,QACF;AAGA,YAAI,oBAAoB,aAAa;AACrC,YAAI,iDAAiD;AAErD,mBAAW,QAAQ,gBAAgB;AACjC,cAAI,yBAAyB,KAAK,IAAI,KAAK,QAAQ;AACnD,gBAAM,KAAK,MAAM,YAAY,EAAE,OAAO,KAAK,IAAI,EAAE,UAAU,KAAK,OAAO,gBAAgB,IAAI,EAAE,CAAC;AAE9F,cAAI,sBAAsB,KAAK,EAAE,OAAO,KAAK,OAAO,gBAAgB,WAAW,GAAG,EAAE;AAAA,QACtF;AAGA,cAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAI,CAAC;AAEtD,YAAI,OAAO,WAAW,aAAa;AACjC,iBAAO,SAAS,OAAO;AAAA,QACzB;AAAA,MACF;AAEA,UAAI,oBAAoB;AAAA,IAC1B,SAAS,OAAO;AACd,cAAQ,MAAM,oCAAoC,KAAK;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,mBAAmB,IAAS;AAC1B,SAAK,SAAS,GAAG,iBAAiB,EAAE;AAAA,EACtC;AAAA,EAGA,yBAAyB,QAAa;AACpC,UAAM,SAAS,OAAO,QAAQ,OAAO,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAW;AAEtE,YAAM,gBAAgB,OAAO,QAAQ,MAAM,MAAM,EAAE,OAAO,CAAC,CAACC,MAAK,KAAK,MAAW,MAAM,OAAO,EAAE,IAAI,CAAC,CAACA,MAAK,KAAK,MAAW,IAAIA,IAAG,EAAE,EAAE,KAAK,EAAE;AAC7I,aAAO;AAAA,QACL,CAAC,GAAG,GAAG,OAAO;AAAA,MAChB;AAAA,IACF,CAAC;AAED,WAAO,OAAO,OAAO,CAAC,GAAG,GAAG,MAAM;AAAA,EACpC;AAAA,EAEA,YAAY;AAMV,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAW,MAAc;AAGvB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAML,KAAK,KAAK,MAAM,IAAI;AAAA;AAAA,MAGpB,KAAK,CAAC,SAAc;AAGlB,cAAM,YAAQ,4BAAa,KAAK,cAAc,MAAM,IAAI;AACxD,YAAI,CAAC,MAAM,OAAO;AAChB,cAAI,gBAAgB,KAAK;AACzB,iBAAO,QAAQ,OAAO,EAAE,GAAI,MAAM,CAAC;AAAA,QACrC;AAEA,eAAO,KAAK,MAAM,IAAI,EAAE,IAAI;AAAA,UAC1B,QAAI,YAAAC,IAAO;AAAA,UACX,GAAG;AAAA,QACL,CAAC;AAAA,MAEH;AAAA,MAEA,KAAK,CAAC,SAAc;AAClB,cAAM,YAAQ,4BAAa,KAAK,cAAc,MAAM,IAAI;AACxD,YAAI,CAAC,MAAM,OAAO;AAChB,cAAI,gBAAgB,KAAK;AACzB,iBAAO,QAAQ,OAAO,EAAE,GAAI,MAAM,CAAC;AAAA,QACrC;AAEA,eAAO,KAAK,MAAM,IAAI,EAAE,IAAI;AAAA,UAC1B,QAAI,YAAAA,IAAO;AAAA,UACX,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA,MAEA,QAAQ,CAAC,IAAY,SAAc;AACjC,cAAM,YAAQ,4BAAa,KAAK,cAAc,MAAM,MAAM,KAAK;AAC/D,YAAI,CAAC,MAAM,OAAO;AAChB,cAAI,gBAAgB,KAAK;AACzB,iBAAO,QAAQ,OAAO,EAAE,GAAI,MAAM,CAAC;AAAA,QACrC;AAEA,eAAO,KAAK,MAAM,IAAI,EAAE,OAAO,IAAI,IAAI;AAAA,MACzC;AAAA,MAEA,QAAQ,CAAC,OAAe;AACtB,eAAO,KAAK,MAAM,IAAI,EAAE,OAAO,EAAE;AAAA,MACnC;AAAA;AAAA,MAKA,KAAK,OAAO,OAAe;AACzB,eAAO,KAAK,MAAM,IAAI,EAAE,IAAI,EAAE;AAAA,MAChC;AAAA,MAEA,QAAQ,YAAY;AAClB,eAAO,KAAK,MAAM,IAAI,EAAE,QAAQ;AAAA,MAClC;AAAA;AAAA;AAAA,MAKA,OAAO,MAAM,KAAK,MAAM,IAAI;AAAA,MAE5B,QAAQ,CAAC,OAAY,KAAK,MAAM,IAAI,EAAE,OAAO,EAAE,EAAE,QAAQ;AAAA,IAE3D;AAAA,EACF;AACF;;;AGxNE,cAAW;;;ACWN,IAAM,iBAAN,MAAqB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EAErB,YAAY,SAAuB,gBAAwB,aAA0B,CAAC,GAAG;AACvF,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,SAAK,aAAa,WAAW,KAAK,CAAC,GAAG,MAAM,KAAK,gBAAgB,EAAE,aAAa,EAAE,WAAW,CAAC;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAyF;AAC7F,UAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAElD,QAAI,CAAC,eAAe;AAElB,YAAM,KAAK,iBAAiB,KAAK,cAAc;AAC/C,aAAO,EAAE,SAAS,OAAO,WAAW,KAAK,eAAe;AAAA,IAC1D;AAEA,QAAI,kBAAkB,KAAK,gBAAgB;AACzC,aAAO,EAAE,SAAS,OAAO,WAAW,KAAK,eAAe;AAAA,IAC1D;AAGA,UAAM,kBAAkB,KAAK,mBAAmB,eAAe,KAAK,cAAc;AAElF,QAAI,gBAAgB,WAAW,GAAG;AAEhC,YAAM,KAAK,iBAAiB,KAAK,cAAc;AAC/C,aAAO,EAAE,SAAS,MAAM,aAAa,eAAe,WAAW,KAAK,eAAe;AAAA,IACrF;AAGA,eAAW,aAAa,iBAAiB;AACvC,UAAI;AACF,gBAAQ,IAAI,0BAA0B,UAAU,WAAW,OAAO,UAAU,SAAS,EAAE;AACvF,cAAM,UAAU,QAAQ,KAAK,OAAO;AAAA,MACtC,SAAS,OAAO;AACd,gBAAQ,MAAM,yBAAyB,UAAU,WAAW,OAAO,UAAU,SAAS,KAAK,KAAK;AAChG,cAAM,IAAI,MAAM,qBAAqB,KAAK,EAAE;AAAA,MAC9C;AAAA,IACF;AAGA,UAAM,KAAK,iBAAiB,KAAK,cAAc;AAC/C,WAAO,EAAE,SAAS,MAAM,aAAa,eAAe,WAAW,KAAK,eAAe;AAAA,EACrF;AAAA,EAEA,MAAc,mBAA2C;AACvD,QAAI;AACF,YAAM,cAAc,MAAM,KAAK,QAAQ,IAAI,KAAK,UAAU;AAC1D,UAAI,CAAC;AAAa,eAAO;AAEzB,YAAM,cAA2B,KAAK,MAAM,WAAW;AACvD,aAAO,YAAY;AAAA,IACrB,SAAS,OAAO;AACd,cAAQ,KAAK,iCAAiC,KAAK;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,iBAAiBC,UAAgC;AAC7D,UAAM,cAA2B;AAAA,MAC/B,SAAAA;AAAA,MACA,aAAa,KAAK,IAAI;AAAA,IACxB;AACA,UAAM,KAAK,QAAQ,IAAI,KAAK,YAAY,KAAK,UAAU,WAAW,CAAC;AAAA,EACrE;AAAA,EAEQ,mBAAmB,aAAqB,WAAgC;AAC9E,WAAO,KAAK,WAAW,OAAO,eAAa;AAGzC,YAAM,4BAA4B,KAAK,gBAAgB,aAAa,UAAU,SAAS,IAAI;AAC3F,YAAM,uCAAuC,KAAK,gBAAgB,WAAW,UAAU,SAAS,KAAK;AAErG,cAAQ,IAAI,sBAAsB,UAAU,WAAW,WAAM,UAAU,SAAS,GAAG;AACnF,cAAQ,IAAI,YAAY,WAAW,mBAAmB,UAAU,SAAS,KAAK,yBAAyB,EAAE;AACzG,cAAQ,IAAI,aAAa,SAAS,oBAAoB,UAAU,SAAS,KAAK,oCAAoC,EAAE;AAEpH,YAAM,YAAY,6BAA6B;AAC/C,cAAQ,IAAI,iBAAiB,SAAS,EAAE;AAExC,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAgB,GAAW,GAAmB;AAEpD,UAAM,cAAc,KAAK,kBAAkB,CAAC;AAC5C,UAAM,cAAc,KAAK,kBAAkB,CAAC;AAG5C,QAAI,YAAY,UAAU,YAAY,OAAO;AAC3C,aAAO,YAAY,QAAQ,YAAY;AAAA,IACzC;AAGA,WAAO,YAAY,QAAQ,YAAY;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,kBAAkBA,UAAmD;AAE3E,UAAM,eAAeA,SAAQ,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,KAAKA;AAC7D,UAAM,QAAQ,aAAa,MAAM,GAAG,EAAE,IAAI,MAAM;AAEhD,WAAO;AAAA,MACL,OAAO,MAAM,CAAC,KAAK;AAAA,MACnB,OAAO,MAAM,CAAC,KAAK;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAA4B;AACvC,SAAK,WAAW,KAAK,SAAS;AAC9B,SAAK,WAAW,KAAK,CAAC,GAAG,MAAM,KAAK,gBAAgB,EAAE,aAAa,EAAE,WAAW,CAAC;AAAA,EACnF;AACF;AAKO,SAAS,qBACd,SACA,gBACA,aAA0B,CAAC,GACX;AAChB,SAAO,IAAI,eAAe,SAAS,gBAAgB,UAAU;AAC/D;;;AC3JO,IAAM,wBAAmC;AAAA,EAC9C,aAAa;AAAA,EACb,WAAW;AAAA,EACX,MAAM,QAAQ,SAAuB;AACnC,YAAQ,IAAI,wBAAwB;AACpC,YAAQ,IAAI,kBAAkB,MAAM;AAAA,EACtC;AACF;AAMO,SAAS,gBAA6B;AAC3C,SAAO;AAAA,IACL;AAAA,EACF;AACF;;;ACdO,IAAM,sBAAN,MAAkD;AAAA,EACrD,MAAM,IAAI,KAAqC;AAC3C,WAAO,aAAa,QAAQ,GAAG;AAAA,EACnC;AAAA,EAEA,MAAM,IAAI,KAAa,OAA8B;AACjD,iBAAa,QAAQ,KAAK,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,OAAO,KAA4B;AACrC,iBAAa,WAAW,GAAG;AAAA,EAC/B;AACJ;AAEO,IAAM,eAAe;AAAA,EACxB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,OAAO;AACX;AAEO,SAAS,UAAU,MAAsB;AAC5C,MAAI,cAAc;AAClB,MAAI,SAAS,UAAU,SAAS,WAAW,IAAI;AAC3C,UAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,YAAM,SAAS,QAAQ,CAAC,GAAG,KAAK;AAChC,UAAI,UAAU,OAAO,UAAU,GAAG,KAAK,SAAS,CAAC,MAAO,OAAO,KAAM;AACjE,sBAAc,mBAAmB,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC;AAClE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;AAEO,SAAS,UAAU,MAAc,OAAe,SAA6E;AAChI,QAAM,OAAO;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,GAAG;AAAA,EACP;AAEA,MAAI,eAAe,GAAG,IAAI,IAAI,KAAK;AACnC,MAAI,KAAK;AAAQ,oBAAgB;AACjC,MAAI,KAAK;AAAU,oBAAgB,cAAc,KAAK,QAAQ;AAC9D,MAAI,KAAK;AAAU,oBAAgB;AAEnC,WAAS,SAAS;AACtB;AAEO,SAAS,YAAY,MAAoB;AAC5C,WAAS,SAAS,GAAG,IAAI;AAC7B;;;AC3DO,SAAS,cAAc,OAA0B;AACpD,SACI,OAAO,SAAS,aAAa,eAC7B,OAAO,SAAS,aAAa,eAC7B,OAAO,SAAS,SAAS,SAAS,WAAW,KAC7C,OAAO,SAAS,SAAS,SAAS,WAAW,KAC7C,OAAO,SAAS,SAAS,SAAS,QAAQ,KAC1C,QAAQ,IAAI,aAAa,iBACzB,UAAU;AAElB;AAEA,eAAsB,qBAInB;AACC,MAAI;AACA,UAAM,SAAS,QAAe,SAAS,MAAM;AAE7C,UAAM,WAAW,MAAM,MAAM,+CAA+C,SAAS,SAAS,QAAQ,EAAE;AACxG,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACtD;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,gBAAgB,KAAK;AAE3B,QAAI,kBAAkB,SAAgB;AAClC,cAAQ,KAAK,kCAAkC,eAAe;AAAA,oCAAuC,aAAa,aAAa;AAAA,IACnI;AACA,QAAI,QAAQ;AACR,UAAI,gDAAgD;AAAA,IACxD;AAEA,WAAO;AAAA,MACH,eAAe,YAAmB;AAAA,MAClC;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,SAAS,OAAO;AACZ,QAAI,mCAAmC,KAAK;AAC5C,WAAO;AAAA,MACH,eAAe;AAAA,MACf,eAAe;AAAA,MACf,gBAAgB;AAAA,IACpB;AAAA,EACJ;AACJ;AAEO,SAAS,0BAAgC;AAC5C,MAAI,OAAO,SAAS,OAAO,SAAS,MAAM,KAAK,OAAO,SAAS,OAAO,SAAS,OAAO,GAAG;AACrF,UAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,QAAI,aAAa,OAAO,MAAM;AAC9B,QAAI,aAAa,OAAO,OAAO;AAC/B,WAAO,QAAQ,UAAU,CAAC,GAAG,SAAS,OAAO,IAAI,WAAW,IAAI,MAAM;AACtE,QAAI,mCAAmC;AAAA,EAC3C;AACJ;AAEO,SAAS,cAAc,YAA4B;AACtD,UAAQ,YAAY;AAAA,IAChB,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX;AACI,aAAO;AAAA,EACf;AACJ;;;AChFA,IAAAC,iBAA+C;AAG/C,eAAsB,gBAAgB,QAInC;AACC,QAAM,YAAY,OAAO;AACzB,QAAM,YAAQ,+BAAe,MAAM;AAEnC,MAAI,CAAC,MAAM,OAAO;AACd,YAAQ,KAAK,iGAAiG;AAC9G,WAAO;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ;AAEA,QAAM,eAAe,MAAM,MAAM,kCAAkC,SAAS,SAAS,EACpF,KAAK,SAAO,IAAI,KAAK,CAAC,EACtB,KAAK,UAAQ,KAAK,KAAK,CAAC,EAAE,MAAM,EAChC,MAAM,SAAO;AACV,WAAO;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ,CAAC;AAED,UAAQ,IAAI,gBAAgB,YAAY;AAExC,MAAI,CAAC,aAAa,SAAS;AACvB,WAAO;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ;AAEA,MAAI,aAAa,UAAU,OAAO,SAAS;AAEvC,YAAQ,KAAK,iFAAiF,OAAO,SAAS,gBAAgB,aAAa,SAAS,qBAAqB;AACzK,WAAO;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ,WAAW,aAAa,UAAU,OAAO,SAAS;AAE9C,YAAQ,KAAK,mFAAmF,OAAO,SAAS,gBAAgB,aAAa,SAAS,qBAAqB;AAC3K,WAAO;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ,WAAW,aAAa,YAAY,OAAO,SAAS;AAChD,UAAM,cAAU,+BAAe,QAAQ,YAAY;AACnD,QAAI,QAAQ,OAAO;AACf,aAAO;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,MACZ;AAAA,IACJ,OAAO;AAEH,cAAQ,KAAK,kFAAkF,OAAO,SAAS,iCAAiC,aAAa,SAAS,qBAAqB;AAC3L,aAAO;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,MACZ;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,WAAO;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ;AACJ;AAEA,eAAsB,uBAAuB,QAI1C;AACC,QAAM,YAAQ,+BAAe,MAAM;AACnC,MAAI,CAAC,MAAM,OAAO;AACd,QAAI,4BAA4B,MAAM,MAAM;AAC5C,YAAQ,MAAM,eAAe;AAC7B,QAAI,eAAe;AACnB,UAAM,OAAO,QAAQ,CAAC,OAAO,UAAU;AACnC,UAAI,GAAG,QAAQ,CAAC,KAAK,MAAM,SAAS,SAAS,MAAM,YAAY,EAAE;AACjE,sBAAgB,GAAG,QAAQ,CAAC,KAAK,MAAM,OAAO,SAAS,MAAM,YAAY;AAAA;AAAA,IAC7E,CAAC;AACD,YAAQ,SAAS;AAEjB,WAAO;AAAA,MACH,SAAS;AAAA,MACT,cAAc,EAAE,OAAO,MAAM;AAAA,MAC7B,QAAQ,MAAM;AAAA,IAClB;AAAA,EACJ;AAEA,MAAI,eAAe,EAAE,OAAO,MAAM;AAClC,MAAI,OAAO,YAAY,GAAG;AACtB,mBAAe,MAAM,gBAAgB,MAAM;AAC3C,QAAI,gBAAgB,YAAY;AAAA,EACpC,OAAO;AACH,QAAI,qCAAqC;AAAA,EAC7C;AAEA,SAAO;AAAA,IACH,SAAS;AAAA,IACT;AAAA,EACJ;AACJ;;;ATksBQ;AA3xBR,IAAM,sBAAsB;AAAA,EACxB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,QAAQ;AACZ;AA0CO,IAAM,mBAAe,4BAYzB;AAAA,EACC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,SAAS,MAAM,QAAQ,QAAQ;AAAA,EAC/B,QAAQ,MAAM,QAAQ,QAAQ;AAAA,EAC9B,gBAAgB,MAAM,IAAI,QAAQ,MAAM;AAAA,EAAE,CAAC;AAAA,EAC3C,UAAU,MAAM,IAAI,QAAQ,MAAM;AAAA,EAAE,CAAC;AAAA,EACrC,eAAe,MAAM,QAAQ,QAAQ,EAAE;AAAA,EACvC,IAAI,CAAC;AAAA,EACL,UAAU;AACd,CAAC;AAQM,SAAS,cAAc;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AACJ,GAAuB;AACnB,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAkB,KAAK;AAC3D,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAuB,IAAI;AACrD,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAe,CAAC,CAAC;AACzC,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAkB,KAAK;AACjE,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAkB,KAAK;AAErD,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAmB,uBAAgB;AACnE,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAA6B,IAAI;AAC3D,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAkB,UAAU,MAAM;AAClE,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,uBAAkB,KAAK;AAEnE,QAAM,cAAU,qBAAyB,IAAI;AAC7C,QAAM,iBAAiB,WAAW,IAAI,oBAAoB;AAG1D,QAAM,aAAa;AAAA,IACf,QAAQ,MAAM,UAAU,oBAAoB;AAAA,IAC5C,YAAY,MAAM,cAAc,oBAAoB;AAAA,IACpD,QAAQ,MAAM,UAAU,oBAAoB;AAAA,EAChD;AAGA,QAAM,eAAe,MAAM,QAAQ,WAAW,MAAM,IAC9C,WAAW,OAAO,KAAK,GAAG,IAC1B,WAAW;AAGjB,QAAM,wBAAoB,qBAAqC,IAAI;AAEnE,QAAM,YAAY,MAAM,cAAc,KAAK;AAE3C,QAAM,mBAAmB,MAAM,wBAAwB;AAEvD,8BAAU,MAAM;AACZ,UAAM,eAAe,MAAM;AACvB,UAAI,0BAA0B;AAC9B,kBAAY,IAAI;AAChB,UAAI,gBAAgB;AAChB,YAAI,gCAAgC;AACpC,0BAAkB,KAAK;AACvB,YAAI,OAAO;AACP,gBAAM,eAAe,MAAM,iBAAiB,aAAa,QAAQ,qBAAqB;AACtF,cAAI,cAAc;AACd,uBAAW,cAAc,IAAI,EAAE,MAAM,CAAAC,WAAS;AAC1C,kBAAI,yBAAyBA,MAAK;AAAA,YACtC,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,UAAM,gBAAgB,MAAM;AACxB,UAAI,sBAAsB;AAC1B,kBAAY,KAAK;AAAA,IACrB;AAEA,WAAO,iBAAiB,UAAU,YAAY;AAC9C,WAAO,iBAAiB,WAAW,aAAa;AAEhD,WAAO,MAAM;AACT,aAAO,oBAAoB,UAAU,YAAY;AACjD,aAAO,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACJ,GAAG,CAAC,gBAAgB,KAAK,CAAC;AAE1B,8BAAU,MAAM;AACZ,aAAS,OAAO,SAAqC;AACjD,UAAI,CAAC,QAAQ,SAAS;AAClB,YAAI,uBAAuB;AAC3B,gBAAQ,UAAU,IAAI,UAAU,WAAW,EAAE,OAAe,CAAC;AAE7D,gBAAQ,QAAQ,SAAS,GAAG,iBAAiB,CAAC,QAAgB,QAAgB;AAC1E,sBAAY,cAAc,MAAM,CAAa;AAAA,QACjD,CAAC;AAMD,YAAI,QAAQ,eAAe;AACvB,2BAAiB,IAAI;AAAA,QACzB,OAAO;AACH,cAAI,kBAAkB;AAAA,QAC1B;AAEA,mBAAW,IAAI;AAAA,MACnB;AAAA,IACJ;AAEA,mBAAe,cAAc;AACzB,YAAM,SAAS,MAAM,uBAAuB,MAAM;AAElD,UAAI,CAAC,OAAO,SAAS;AACjB,YAAI,eAAe;AACnB,YAAI,OAAO,QAAQ;AACf,iBAAO,OAAO,QAAQ,CAACA,QAAO,UAAU;AACpC,4BAAgB,GAAG,QAAQ,CAAC,KAAKA,OAAM,OAAO,SAASA,OAAM,YAAY;AAAA;AAAA,UAC7E,CAAC;AAAA,QACL;AACA,iBAAS;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACb,CAAC;AACD,mBAAW,IAAI;AACf,eAAO;AAAA,MACX;AAEA,UAAI,OAAO,aAAa,OAAO;AAC3B,eAAO,EAAE,eAAe,KAAK,CAAC;AAAA,MAClC,OAAO;AACH,YAAI,sBAAsB,OAAO,YAAY;AAC7C,eAAO,EAAE,eAAe,MAAM,CAAC;AAAA,MACnC;AAEA,yBAAmB;AAAA,IACvB;AAEA,QAAI,QAAQ;AACR,kBAAY;AAAA,IAChB,OAAO;AACH,iBAAW,IAAI;AAAA,IACnB;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACZ,mBAAe,cAAc;AACzB,UAAI,SAAS,QAAQ,WAAW,cAAc,eAAe;AACzD,cAAM,MAAM,MAAM,SAAS;AAC3B,YAAI,CAAC,KAAK;AACN,cAAI,gBAAgB;AACpB;AAAA,QACJ;AAEA,YAAI,qBAAqB;AAEzB,gBAAQ,SAAS,QAAQ;AAAA,UACrB,cAAc;AAAA,UACd,QAAQ,WAAW;AAAA,QACvB,CAAC,EACI,MAAM,CAAC,MAAM;AACV,cAAI,0BAA0B,CAAC;AAAA,QACnC,CAAC;AAAA,MACT;AAAA,IACJ;AACA,gBAAY;AAAA,EAEhB,GAAG,CAAC,YAAY,aAAa,CAAC;AAE9B,8BAAU,MAAM;AACZ,UAAM,iBAAiB,YAAY;AAC/B,YAAM,eAAe,IAAI,aAAa,OAAO,QAAQ,SAAS,OAAO;AAGrE,YAAM,kBAAkB,MAAM,eAAe,IAAI,aAAa,UAAU;AACxE,UAAI,mBAAmB,oBAAoB,WAAW,YAAY;AAC9D,YAAI,4CAA4C;AAChD,cAAM,eAAe,OAAO,aAAa,aAAa;AACtD,cAAM,eAAe,OAAO,aAAa,SAAS;AAClD,cAAM,eAAe,OAAO,aAAa,UAAU;AACnD,cAAM,eAAe,OAAO,aAAa,YAAY;AACrD,oBAAY,aAAa;AACzB,oBAAY,oBAAoB;AAAA,MACpC;AACA,YAAM,eAAe,IAAI,aAAa,YAAY,WAAW,UAAU;AAEvE,UAAI;AACA,cAAM,iBAAiB,qBAAqB,gBAAgB,SAAgB,cAAc,CAAC;AAC3F,cAAM,eAAe,MAAM,eAAe,eAAe;AAEzD,YAAI,aAAa,SAAS;AACtB,cAAI,oBAAoB,aAAa,WAAW,OAAO,aAAa,SAAS,EAAE;AAAA,QACnF,OAAO;AACH,cAAI,eAAe,aAAa,SAAS,aAAa;AAAA,QAC1D;AAAA,MACJ,SAASA,QAAO;AACZ,YAAI,0BAA0BA,MAAK;AAAA,MACvC;AAEA,UAAI;AACA,YAAI,OAAO,SAAS,OAAO,SAAS,MAAM,GAAG;AACzC,cAAI,OAAO,OAAO,UAAU,QAAQ,MAAM,OAAO,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC;AACnE,cAAI,CAAC;AAAM;AAEX,gBAAM,QAAQ,MAAM,eAAe,IAAI,aAAa,UAAU;AAC9D,gBAAM,WAAW,OAAO,SAAS,OAAO,MAAM,QAAQ,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC;AACxE,cAAI,CAAC,SAAS,UAAU,UAAU;AAC9B,gBAAI,kCAAkC;AACtC,2BAAe,IAAI;AAEnB,kBAAM,eAAe,OAAO,aAAa,UAAU;AACnD,6BAAiB;AACjB;AAAA,UACJ;AAEA,gBAAM,eAAe,OAAO,aAAa,UAAU;AACnD,2BAAiB;AAEjB,qBAAW,MAAM,KAAK,EAAE,MAAM,CAACA,WAAU;AACrC,gBAAI,yBAAyBA,MAAK;AAAA,UACtC,CAAC;AAAA,QACL,OAAO;AACH,gBAAM,eAAe,MAAM,eAAe,IAAI,aAAa,aAAa;AACxE,cAAI,cAAc;AACd,gBAAI,oEAAoE;AACxE,uBAAW,cAAc,IAAI,EAAE,MAAM,CAACA,WAAU;AAC5C,kBAAI,iCAAiCA,MAAK;AAAA,YAC9C,CAAC;AAAA,UACL,OAAO;AACH,gBAAI,eAAe,UAAU,aAAa;AAC1C,gBAAI,iBAAiB,IAAI;AACrB,oBAAM,YAAY,KAAK,MAAM,YAAY;AACzC,uBAAS,SAAS;AAClB,kBAAI,UAAU,eAAe;AACzB,sBAAM,eAAe,IAAI,aAAa,eAAe,UAAU,aAAa;AAAA,cAChF;AAAA,YACJ,OAAO;AACH,oBAAM,iBAAiB,MAAM,eAAe,IAAI,aAAa,SAAS;AACtE,kBAAI,gBAAgB;AAChB,oBAAI;AACA,wBAAM,WAAW,KAAK,MAAM,cAAc;AAC1C,0BAAQ,QAAQ;AAChB,gCAAc,IAAI;AAClB,sBAAI,0CAA0C;AAAA,gBAClD,SAASA,QAAO;AACZ,sBAAI,mCAAmCA,MAAK;AAAA,gBAChD;AAAA,cACJ;AACA,6BAAe,IAAI;AAAA,YACvB;AAAA,UACJ;AAAA,QACJ;AAAA,MAEJ,SAAS,GAAG;AACR,YAAI,uBAAuB,CAAC;AAAA,MAChC;AAAA,IACJ;AAEA,mBAAe;AAAA,EACnB,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACZ,mBAAe,UAAU,WAAmB;AACxC,cAAQ,KAAK,eAAe;AAC5B,UAAI;AACA,cAAM,WAAW,MAAM,MAAM,GAAG,WAAW,UAAU,kBAAkB;AAAA,UACnE,QAAQ;AAAA,UACR,SAAS;AAAA,YACL,iBAAiB,UAAU,SAAS;AAAA,UACxC;AAAA,QACJ,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AACd,gBAAM,IAAI,MAAM,8BAA8B,SAAS,MAAM,EAAE;AAAA,QACnE;AAEA,cAAMC,QAAO,MAAM,SAAS,KAAK;AAEjC,YAAIA,MAAK,OAAO;AACZ,cAAI,uBAAuBA,MAAK,KAAK;AACrC,gBAAM,IAAI,MAAM,oBAAoBA,MAAK,KAAK,EAAE;AAAA,QACpD;AAEA,YAAI,OAAO,eAAe;AACtB,gBAAM,eAAe,IAAI,aAAa,eAAe,MAAM,aAAa;AAAA,QAC5E;AAEA,cAAM,eAAe,IAAI,aAAa,WAAW,KAAK,UAAUA,KAAI,CAAC;AACrE,YAAI,6BAA6B;AAEjC,kBAAU,sBAAsB,OAAO,gBAAgB,IAAI,EAAE,UAAU,MAAM,CAAC;AAC9E,kBAAU,eAAe,KAAK,UAAU,KAAK,CAAC;AAE9C,gBAAQA,KAAI;AACZ,sBAAc,IAAI;AAClB,uBAAe,IAAI;AAAA,MACvB,SAASD,QAAO;AACZ,YAAI,8BAA8BA,MAAK;AAEvC,uBAAe,IAAI;AAAA,MACvB;AAAA,IACJ;AAEA,mBAAe,aAAa;AACxB,UAAI,CAAC,OAAO;AACR,YAAI,4BAA4B;AAEhC,uBAAe,IAAI;AACnB;AAAA,MACJ;AAEA,YAAM,cAAU,6BAAU,OAAO,YAAY;AAE7C,YAAM,mBAAmB;AACzB,YAAM,YAAY,QAAQ,OAAO,QAAQ,MAAO,KAAK,IAAI,IAAI,MAAQ;AAErE,UAAI,WAAW;AACX,YAAI,mCAAmC;AACvC,YAAI;AACA,gBAAM,WAAW,MAAM,WAAW,OAAO,iBAAiB,IAAI,IAAI;AAClE,oBAAU,UAAU,gBAAgB,EAAE;AAAA,QAC1C,SAASA,QAAO;AACZ,cAAI,0CAA0CA,MAAK;AAEnD,cAAKA,OAAgB,QAAQ,SAAS,SAAS,KAAMA,OAAgB,QAAQ,SAAS,SAAS,GAAG;AAC9F,gBAAI,4DAA4D;AAChE,sBAAU,OAAO,gBAAgB,EAAE;AAAA,UACvC,OAAO;AACH,2BAAe,IAAI;AAAA,UACvB;AAAA,QACJ;AAAA,MACJ,OAAO;AACH,kBAAU,OAAO,gBAAgB,EAAE;AAAA,MACvC;AAAA,IACJ;AAEA,QAAI,OAAO;AACP,iBAAW;AAAA,IACf;AAAA,EACJ,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,gBAAgB,OAAO,gBAAyB;AAClD,QAAI;AACA,UAAI,yBAAyB;AAE7B,UAAI,CAAC,YAAY;AACb,cAAM,IAAI,MAAM,iDAAiD;AAAA,MACrE;AAEA,YAAM,cAAc,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC;AAC1D,YAAM,eAAe,IAAI,aAAa,YAAY,WAAW;AAE7D,YAAM,cAAc,eAAe,OAAO,SAAS;AAEnD,UAAI,CAAC,eAAgB,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC,YAAY,WAAW,UAAU,GAAI;AAC7F,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACnD;AAGA,YAAM,eAAe,IAAI,aAAa,cAAc,WAAW;AAC/D,UAAI,2CAA2C,WAAW;AAE1D,UAAI,UAAU,GAAG,WAAW,UAAU;AACtC,iBAAW,cAAc,UAAU;AACnC,iBAAW,iBAAiB,mBAAmB,WAAW,CAAC;AAC3D,iBAAW;AACX,iBAAW,UAAU,mBAAmB,YAAY,CAAC;AACrD,iBAAW,UAAU,WAAW;AAEhC,UAAI,oDAAoD,YAAY;AACpE,aAAO;AAAA,IAEX,SAASA,QAAO;AACZ,UAAI,kCAAkCA,MAAK;AAC3C,YAAMA;AAAA,IACV;AAAA,EACJ;AAEA,QAAM,SAAS,YAAY;AACvB,QAAI;AACA,UAAI,eAAe;AAEnB,UAAI,CAAC,YAAY;AACb,YAAI,2CAA2C;AAC/C,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC/D;AAEA,YAAM,aAAa,MAAM,cAAc;AACvC,UAAI,2BAA2B,UAAU;AAGzC,UAAI;AACA,YAAI,IAAI,UAAU;AAAA,MACtB,QAAQ;AACJ,YAAI,uCAAuC;AAC3C,cAAM,IAAI,MAAM,sCAAsC;AAAA,MAC1D;AAEA,aAAO,SAAS,OAAO;AAAA,IAE3B,SAASA,QAAO;AACZ,UAAI,yBAAyBA,MAAK;AAElC,UAAI,UAAU,GAAG;AACb,iBAAS;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAUA,OAAgB,WAAW;AAAA,QACzC,CAAC;AAAA,MACL;AAEA,YAAMA;AAAA,IACV;AAAA,EACJ;AAEA,QAAM,iBAAiB,OAAO,MAAc,UAAkE;AAC1G,QAAI;AACA,UAAI,oCAAoC,IAAI;AAE5C,UAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACnC,eAAO,EAAE,SAAS,OAAO,OAAO,6BAA6B;AAAA,MACjE;AAEA,UAAI,OAAO;AACP,cAAM,cAAc,MAAM,eAAe,IAAI,aAAa,UAAU;AACpE,YAAI,eAAe,gBAAgB,OAAO;AACtC,cAAI,6BAA6B,EAAE,UAAU,OAAO,QAAQ,YAAY,CAAC;AACzE,iBAAO,EAAE,SAAS,OAAO,OAAO,2BAA2B;AAAA,QAC/D;AAAA,MACJ;AAEA,YAAM,eAAe,OAAO,aAAa,UAAU;AACnD,uBAAiB;AAEjB,YAAME,SAAQ,MAAM,WAAW,MAAM,KAAK;AAE1C,UAAIA,QAAO;AACP,YAAI,2BAA2B;AAC/B,eAAO,EAAE,SAAS,KAAK;AAAA,MAC3B,OAAO;AACH,eAAO,EAAE,SAAS,OAAO,OAAO,oCAAoC;AAAA,MACxE;AAAA,IACJ,SAASF,QAAO;AACZ,UAAI,yBAAyBA,MAAK;AAClC,aAAO;AAAA,QACH,SAAS;AAAA,QACT,OAAQA,OAAgB,WAAW;AAAA,MACvC;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,UAAU,YAAY;AACxB,QAAI,cAAc;AAClB,YAAQ,CAAC,CAAC;AACV,kBAAc,KAAK;AACnB,aAAS,IAAI;AAEb,gBAAY,aAAa;AACzB,gBAAY,oBAAoB;AAChC,UAAM,eAAe,OAAO,aAAa,UAAU;AACnD,UAAM,eAAe,OAAO,aAAa,aAAa;AACtD,UAAM,eAAe,OAAO,aAAa,SAAS;AAClD,UAAM,eAAe,OAAO,aAAa,YAAY;AACrD,UAAM,eAAe,OAAO,aAAa,UAAU;AACnD,QAAI,QAAQ,SAAS;AACjB,OAAC,YAAY;AACT,YAAI;AACA,gBAAM,QAAQ,SAAS,MAAM;AAC7B,gBAAM,QAAQ,SAAS,OAAO,EAAE,iBAAiB,MAAM,CAAC;AACxD,kBAAQ,UAAU;AAClB,kBAAQ,UAAU,OAAO;AAAA,QAC7B,SAASA,QAAO;AACZ,kBAAQ,MAAM,kCAAkCA,MAAK;AAAA,QACzD;AAAA,MACJ,GAAG;AAAA,IACP;AAAA,EACJ;AAEA,QAAM,WAAW,YAA6B;AAC1C,QAAI,kBAAkB;AAEtB,QAAI,CAAC,OAAO;AAER,YAAM,eAAe,MAAM,eAAe,IAAI,aAAa,aAAa;AACxE,UAAI,cAAc;AACd,YAAI,wDAAwD;AAG5D,YAAI,kBAAkB,SAAS;AAC3B,cAAI,+CAA+C;AACnD,cAAI;AACA,kBAAM,WAAW,MAAM,kBAAkB;AACzC,gBAAI,UAAU,cAAc;AACxB,qBAAO,SAAS;AAAA,YACpB;AAAA,UACJ,SAASA,QAAO;AACZ,gBAAI,6BAA6BA,MAAK;AACtC,kBAAMA;AAAA,UACV;AAAA,QACJ;AAEA,YAAI;AACA,gBAAM,WAAW,MAAM,WAAW,cAAc,IAAI;AACpD,cAAI,UAAU,cAAc;AACxB,mBAAO,SAAS;AAAA,UACpB;AAAA,QACJ,SAASA,QAAO;AACZ,cAAI,yCAAyCA,MAAK;AAElD,cAAKA,OAAgB,QAAQ,SAAS,SAAS,KAAMA,OAAgB,QAAQ,SAAS,SAAS,GAAG;AAC9F,gBAAI,2DAA2D;AAC/D,kBAAM,YAAY,aAAa,QAAQ,oBAAoB;AAC3D,gBAAI,WAAW;AACX,qBAAO;AAAA,YACX;AACA,kBAAM,IAAI,MAAM,8DAA8D;AAAA,UAClF;AAEA,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACnE;AAAA,MACJ;AACA,UAAI,gBAAgB;AACpB,YAAM,IAAI,MAAM,gBAAgB;AAAA,IACpC;AAEA,UAAM,cAAU,6BAAU,OAAO,YAAY;AAE7C,UAAM,mBAAmB;AACzB,UAAM,YAAY,QAAQ,OAAO,QAAQ,MAAO,KAAK,IAAI,IAAI,MAAQ;AAErE,QAAI,WAAW;AACX,UAAI,mCAAmC;AAGvC,UAAI,kBAAkB,SAAS;AAC3B,YAAI,+CAA+C;AACnD,YAAI;AACA,gBAAM,WAAW,MAAM,kBAAkB;AACzC,iBAAO,UAAU,gBAAgB;AAAA,QACrC,SAASA,QAAO;AACZ,cAAI,6BAA6BA,MAAK;AAEtC,cAAKA,OAAgB,QAAQ,SAAS,SAAS,KAAMA,OAAgB,QAAQ,SAAS,SAAS,GAAG;AAC9F,gBAAI,+DAA+D;AACnE,mBAAO,MAAM;AAAA,UACjB;AAEA,gBAAMA;AAAA,QACV;AAAA,MACJ;AAEA,YAAM,eAAe,OAAO,iBAAiB,MAAM,eAAe,IAAI,aAAa,aAAa;AAChG,UAAI,cAAc;AACd,YAAI;AACA,gBAAM,WAAW,MAAM,WAAW,cAAc,IAAI;AACpD,iBAAO,UAAU,gBAAgB;AAAA,QACrC,SAASA,QAAO;AACZ,cAAI,oCAAoCA,MAAK;AAE7C,cAAKA,OAAgB,QAAQ,SAAS,SAAS,KAAMA,OAAgB,QAAQ,SAAS,SAAS,GAAG;AAC9F,gBAAI,+DAA+D;AACnE,mBAAO,MAAM;AAAA,UACjB;AAEA,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACnE;AAAA,MACJ,OAAO;AACH,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAChD;AAAA,IACJ;AAEA,WAAO,OAAO,gBAAgB;AAAA,EAClC;AAEA,QAAM,aAAa,OAAO,oBAA4B,iBAA0B,UAAiC;AAE7G,QAAI,kBAAkB,kBAAkB,SAAS;AAC7C,UAAI,yCAAyC;AAC7C,aAAO,kBAAkB;AAAA,IAC7B;AAGA,UAAM,kBAAkB,YAAmC;AACvD,UAAI;AACA,YAAI,CAAC,UAAU;AACX,cAAI,gDAAgD;AACpD,4BAAkB,IAAI;AACtB,gBAAM,IAAI,MAAM,uDAAuD;AAAA,QAC3E;AAEA,YAAI;AAEJ,YAAI,gBAAgB;AAEhB,wBAAc;AAAA,YACV,YAAY;AAAA,YACZ,eAAe;AAAA,UACnB;AAEA,cAAI,YAAY;AACZ,wBAAY,YAAY;AAAA,UAC5B;AAAA,QACJ,OAAO;AAEH,wBAAc;AAAA,YACV,YAAY;AAAA,YACZ,MAAM;AAAA,UACV;AAGA,gBAAM,oBAAoB,MAAM,eAAe,IAAI,aAAa,YAAY;AAC5E,cAAI,mBAAmB;AACnB,wBAAY,eAAe;AAC3B,gBAAI,6CAA6C,iBAAiB;AAAA,UACtE,OAAO;AACH,gBAAI,8DAA8D;AAAA,UACtE;AAGA,cAAI,YAAY;AACZ,wBAAY,YAAY;AAAA,UAC5B;AAAA,QACJ;AAEA,YAAI,gCAAgC,EAAE,GAAG,aAAa,eAAe,iBAAiB,eAAe,QAAW,MAAM,CAAC,iBAAiB,eAAe,OAAU,CAAC;AAElK,cAAME,SAAQ,MAAM,MAAM,GAAG,WAAW,UAAU,eAAe;AAAA,UAC7D,QAAQ;AAAA,UACR,SAAS;AAAA,YACL,gBAAgB;AAAA,UACpB;AAAA,UACA,MAAM,KAAK,UAAU,WAAW;AAAA,QACpC,CAAC,EACI,KAAK,cAAY,SAAS,KAAK,CAAC,EAChC,MAAM,CAAAF,WAAS;AACZ,cAAI,iCAAiCA,MAAK;AAC1C,cAAI,CAAC,UAAU;AACX,8BAAkB,IAAI;AACtB,kBAAM,IAAI,MAAM,uDAAuD;AAAA,UAC3E;AACA,gBAAM,IAAI,MAAM,oCAAoC;AAAA,QACxD,CAAC;AAEL,YAAIE,OAAM,OAAO;AACb,cAAI,wBAAwBA,OAAM,KAAK;AAEvC,cAAIA,OAAM,MAAM,SAAS,SAAS,KAAKA,OAAM,MAAM,SAAS,SAAS,GAAG;AACpE,8BAAkB,IAAI;AACtB,kBAAM,IAAI,MAAM,qDAAqD;AAAA,UACzE;AAEA,gBAAM,eAAe,OAAO,aAAa,aAAa;AACtD,gBAAM,eAAe,OAAO,aAAa,SAAS;AAClD,gBAAM,eAAe,OAAO,aAAa,YAAY;AACrD,gBAAM,eAAe,OAAO,aAAa,UAAU;AACnD,sBAAY,aAAa;AACzB,sBAAY,oBAAoB;AAEhC,kBAAQ,CAAC,CAAC;AACV,wBAAc,KAAK;AACnB,mBAAS,IAAI;AACb,yBAAe,IAAI;AAEnB,gBAAM,IAAI,MAAM,yBAAyBA,OAAM,KAAK,EAAE;AAAA,QAC1D,OAAO;AACH,mBAASA,MAAK;AACd,4BAAkB,KAAK;AAEvB,cAAIA,OAAM,eAAe;AACrB,kBAAM,eAAe,IAAI,aAAa,eAAeA,OAAM,aAAa;AACxE,gBAAI,kCAAkC;AAAA,UAC1C;AAGA,cAAI,CAAC,gBAAgB;AACjB,kBAAM,eAAe,OAAO,aAAa,YAAY;AACrD,gBAAI,gEAAgE;AAAA,UACxE;AAEA,oBAAU,sBAAsBA,OAAM,cAAc,EAAE,UAAU,MAAM,CAAC;AACvE,oBAAU,eAAe,KAAK,UAAUA,MAAK,CAAC;AAC9C,cAAI,gDAAgD;AAAA,QACxD;AACA,eAAOA;AAAA,MACX,SAASF,QAAO;AACZ,YAAI,wBAAwBA,MAAK;AAEjC,YAAI,CAAEA,OAAgB,QAAQ,SAAS,SAAS,KAAK,CAAEA,OAAgB,QAAQ,SAAS,SAAS,GAAG;AAChG,gBAAM,eAAe,OAAO,aAAa,aAAa;AACtD,gBAAM,eAAe,OAAO,aAAa,SAAS;AAClD,gBAAM,eAAe,OAAO,aAAa,YAAY;AACrD,gBAAM,eAAe,OAAO,aAAa,UAAU;AACnD,sBAAY,aAAa;AACzB,sBAAY,oBAAoB;AAEhC,kBAAQ,CAAC,CAAC;AACV,wBAAc,KAAK;AACnB,mBAAS,IAAI;AACb,yBAAe,IAAI;AAAA,QACvB;AAEA,cAAMA;AAAA,MACV;AAAA,IACJ,GAAG;AAGH,QAAI,gBAAgB;AAChB,wBAAkB,UAAU;AAG5B,qBAAe,QAAQ,MAAM;AACzB,YAAI,kBAAkB,YAAY,gBAAgB;AAC9C,4BAAkB,UAAU;AAC5B,cAAI,mCAAmC;AAAA,QAC3C;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,WAAO;AAAA,EACX;AAEA,QAAM,OAAQ;AAAA,IACV,YAAY,MAAM;AACd,YAAM,IAAI,MAAM,qEAAqE;AAAA,IACzF;AAAA,EACJ;AAEA,SACI,6CAAC,aAAa,UAAb,EAAsB,OAAO;AAAA,IAC1B,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,QAAQ,UAAU,QAAQ,UAAU;AAAA,IACxC;AAAA,EACJ,GAEK;AAAA,aAAS,UAAU,KAAK,4CAAC,gBAAa,OAAc;AAAA,IACpD,WAAW;AAAA,KAChB;AAER;AAEA,SAAS,aAAa,EAAE,MAAM,GAA2B;AACrD,SAAO,6CAAC,SAAI,OAAO;AAAA,IACf,UAAU;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,YAAY;AAAA,EAChB,GACI;AAAA,iDAAC,QAAG,OAAO,EAAE,UAAU,UAAU,SAAS,IAAI,GAAG;AAAA;AAAA,MAAO,MAAM;AAAA,OAAK;AAAA,IACnE,4CAAC,QAAG,OAAO,EAAE,UAAU,UAAU,YAAY,MAAM,GAAI,gBAAM,OAAM;AAAA,IACnE,4CAAC,OAAG,gBAAM,SAAQ;AAAA,KACtB;AACJ;AAGO,SAAS,WAAW;AACvB,aAAO,yBAAW,YAAY;AAClC;;;ADn2BA,+BAAyC;","names":["useQuery","import_dexie","changes","baseRevision","partial","onChangesAccepted","requestId","key","uuidv7","version","import_schema","error","user","token"]}
|