@pol-studios/db 1.0.55 → 1.0.57
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/dist/{DataLayerContext-C7cJtiO8.d.ts → DataLayerContext-BYZtDD0g.d.ts} +1 -1
- package/dist/auth/context.js +4 -2
- package/dist/auth/hooks.js +5 -3
- package/dist/auth/index.js +5 -3
- package/dist/{chunk-7YGDT46S.js → chunk-4EO55YV2.js} +10 -7
- package/dist/chunk-4EO55YV2.js.map +1 -0
- package/dist/{chunk-WILXD5X3.js → chunk-6SDH7M7J.js} +25 -9
- package/dist/chunk-6SDH7M7J.js.map +1 -0
- package/dist/{chunk-OC6S4XFL.js → chunk-DDL63KLQ.js} +385 -104
- package/dist/chunk-DDL63KLQ.js.map +1 -0
- package/dist/{chunk-WSKBZIEI.js → chunk-GWYTROSD.js} +95 -1
- package/dist/chunk-GWYTROSD.js.map +1 -0
- package/dist/{chunk-BRFFTGVJ.js → chunk-MEBT5YHA.js} +2 -2
- package/dist/chunk-QYAFI34Q.js +64 -0
- package/dist/chunk-QYAFI34Q.js.map +1 -0
- package/dist/{chunk-AA3VUWTP.js → chunk-VSJKGPRI.js} +12 -8
- package/dist/chunk-VSJKGPRI.js.map +1 -0
- package/dist/{chunk-AKCNWHXV.js → chunk-VYFAMTHI.js} +2 -2
- package/dist/chunk-W7PERM66.js +215 -0
- package/dist/chunk-W7PERM66.js.map +1 -0
- package/dist/{chunk-HZIVE5AZ.js → chunk-YRIPM2AN.js} +253 -338
- package/dist/chunk-YRIPM2AN.js.map +1 -0
- package/dist/core/index.d.ts +24 -1
- package/dist/{executor-YJw4m7Q7.d.ts → executor-D15yjeMo.d.ts} +20 -0
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.js +4 -2
- package/dist/{index-jVYdTeWx.d.ts → index-CFUuTzXO.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -8
- package/dist/index.native.d.ts +6 -6
- package/dist/index.native.js +10 -8
- package/dist/index.web.d.ts +10 -9
- package/dist/index.web.js +23 -12
- package/dist/index.web.js.map +1 -1
- package/dist/powersync-bridge/index.d.ts +1 -1
- package/dist/query/index.d.ts +4 -83
- package/dist/query/index.js +13 -3
- package/dist/realtime/index.d.ts +80 -1
- package/dist/realtime/index.js +11 -9
- package/dist/realtime/index.js.map +1 -1
- package/dist/select-parser-BAV7fOaM.d.ts +144 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/{useDbCount-DHLJzmkO.d.ts → useDbCount-Ckb-FhZk.d.ts} +1 -1
- package/dist/{useResolveFeedback-B0UcYWVI.d.ts → useResolveFeedback-CuUkdHoR.d.ts} +13 -29
- package/dist/with-auth/index.js +7 -5
- package/dist/with-auth/index.js.map +1 -1
- package/package.json +5 -2
- package/dist/chunk-7YGDT46S.js.map +0 -1
- package/dist/chunk-AA3VUWTP.js.map +0 -1
- package/dist/chunk-HZIVE5AZ.js.map +0 -1
- package/dist/chunk-OC6S4XFL.js.map +0 -1
- package/dist/chunk-WILXD5X3.js.map +0 -1
- package/dist/chunk-WSKBZIEI.js.map +0 -1
- /package/dist/{chunk-BRFFTGVJ.js.map → chunk-MEBT5YHA.js.map} +0 -0
- /package/dist/{chunk-AKCNWHXV.js.map → chunk-VYFAMTHI.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/TimeoutError.ts","../src/useDbQuery.ts","../src/auth/context/setupAuthContext.tsx","../src/auth/context/AuthProvider.tsx","../src/auth/context/PermissionContext.tsx","../src/auth/context/UserMetadataContext.tsx","../src/useDbUpsert.ts"],"sourcesContent":["export const TIMEOUT_ERROR_MESSAGE = \"Request timed out\";\nexport const DEFAULT_QUERY_TIMEOUT = 15_000; // 15 seconds\n\nexport function isTimeoutError(error: Error | null | undefined): boolean {\n if (!error) return false;\n return error.name === \"AbortError\" || error.message === TIMEOUT_ERROR_MESSAGE || error.message.toLowerCase().includes(\"timed out\");\n}","import { PostgrestError, PostgrestSingleResponse } from \"@supabase/supabase-js\";\nimport { useMemo, useRef } from \"react\";\nimport { ItemType } from \"@pol-studios/utils\";\nimport { encode, UseQuerySingleReturn } from \"@supabase-cache-helpers/postgrest-react-query\";\nimport { omit } from \"@pol-studios/utils\";\nimport { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport { useDelayedValue } from \"@pol-studios/hooks/state\";\nimport { DEFAULT_QUERY_TIMEOUT, TIMEOUT_ERROR_MESSAGE } from \"./errors/TimeoutError\";\ntype ConfigurationOptions<T> = {\n crossOrganization?: boolean;\n filter?: (item: ItemType<T>) => boolean;\n timeout?: number;\n};\nexport type UseDbQuerySingleReturn<T> = UseQuerySingleReturn<T> & {\n data: T | null | undefined;\n count?: number | null;\n};\nexport function useDbQuery<Result>(query: PromiseLike<PostgrestSingleResponse<Result>> & {\n abortSignal?: (signal: AbortSignal) => PromiseLike<PostgrestSingleResponse<Result>>;\n}, config?: Omit<UseQueryOptions<Result, PostgrestError>, \"queryKey\" | \"queryFn\"> & ConfigurationOptions<Result>) {\n // Debounce query key to prevent rapid query churn during fast navigation\n const queryKey = encode(query, false);\n const queryKeyString = queryKey.join(\"-\");\n const debouncedKeyString = useDelayedValue(queryKeyString, 50);\n\n // Only enable query when key has stabilized (debounced matches current)\n const isKeyStable = queryKeyString === debouncedKeyString;\n const effectiveEnabled = config?.enabled !== false && isKeyStable;\n const timeoutMs = config?.timeout ?? DEFAULT_QUERY_TIMEOUT;\n\n // Track count from Supabase response (for queries with count: \"exact\")\n const countRef = useRef<number | null>(null);\n const request = useQuery(useMemo(() => ({\n queryKey,\n queryFn: async ({\n signal\n }) => {\n const controller = new AbortController();\n signal.addEventListener(\"abort\", () => controller.abort());\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n try {\n // Execute query with abort signal\n const queryWithSignal = query.abortSignal?.(controller.signal) ?? query;\n const result = await queryWithSignal;\n if (result.error) throw result.error;\n // Store count if available (from queries with count: \"exact\")\n countRef.current = result.count ?? null;\n return result.data;\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n throw new Error(TIMEOUT_ERROR_MESSAGE);\n }\n throw err;\n } finally {\n clearTimeout(timeoutId);\n }\n },\n ...omit({\n retry: 1,\n ...config,\n enabled: effectiveEnabled\n }, [\"queryKey\", \"timeout\"])\n }), [queryKey, config, effectiveEnabled, timeoutMs, query]));\n\n // Return request with count property added\n return useMemo(() => ({\n ...request,\n count: countRef.current\n }), [request, countRef.current]) as UseDbQuerySingleReturn<Result>;\n}","/**\n * SetupAuthContext - Shared context for auth state\n *\n * This file is separate to avoid circular dependencies between\n * AuthProvider and PermissionContext.\n */\n\nimport { createContext, ReactNode } from \"react\";\nimport { AuthTokenResponsePassword, SignUpWithPasswordCredentials, User } from \"@supabase/supabase-js\";\nexport type ProfileStatus = \"active\" | \"archived\" | \"suspended\";\n\n/**\n * Represents an effective permission for a user on a specific resource.\n * These are eagerly loaded at login for fast permission checks.\n */\nexport interface EffectivePermission {\n /** The type of resource (e.g., 'project', 'client', 'database') */\n resourceType: string;\n /** The ID of the specific resource */\n resourceId: string;\n /** The permission action (e.g., 'view', 'edit', 'admin') */\n permission: string;\n /** Numeric level for comparison: view=1, edit=2, admin=3 */\n permissionLevel: number;\n /** How the permission was granted */\n source: \"direct\" | \"group\" | \"inherited\";\n /** If inherited, from which resource */\n inheritedFrom: string | null;\n /** When the permission expires, if applicable */\n expiresAt: string | null;\n}\nexport interface SetupAuthContext {\n user?: User | null | undefined;\n isLoading: boolean;\n profile: Profile | null | undefined;\n access: string[];\n /** Eagerly loaded effective permissions for the user */\n effectivePermissions: EffectivePermission[];\n /** Whether the profile is archived */\n isArchived: boolean;\n /** Whether the profile is suspended */\n isSuspended: boolean;\n /** The profile status (active, archived, suspended) */\n profileStatus: ProfileStatus | undefined;\n registerAsync: (register: SignUpWithPasswordCredentials) => Promise<any>;\n signInAsync: (username: string, password: string) => Promise<AuthTokenResponsePassword>;\n signOutAsync: () => Promise<any>;\n refreshAsync: () => Promise<void>;\n onSignOut: (action: () => any) => string;\n removeOnSignOut: (id: string) => any;\n hasAccess?: (key: string) => boolean;\n}\n\n// Profile type - simplified version, the full type is in AuthProvider\nexport interface Profile {\n id: string;\n email?: string;\n fullName?: string;\n status?: ProfileStatus;\n UserAccess?: Array<{\n accessKey: string;\n }>;\n [key: string]: any;\n}\nexport const setupAuthContext = createContext({} as SetupAuthContext);\n\n/**\n * Props for SetupAuthContextProvider\n * A simpler provider that takes pre-computed auth state\n */\nexport interface SetupAuthContextProviderProps {\n children: ReactNode;\n auth: SetupAuthContext;\n}","/**\n * AuthProvider - Unified auth provider for offline-first apps\n *\n * Features:\n * - Supabase auth with session timeout protection (3 second timeout)\n * - Profile and access data via useDbQuery (auto strategy: Supabase primary, PowerSync offline backup)\n * - Group-based access with permission levels (view=1, edit=2, admin=3)\n * - Wildcard matching (*:*:*, type:*:action, etc.)\n * - Works 100% offline once data is synced\n */\n\nimport { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { User, SignUpWithPasswordCredentials } from \"@supabase/supabase-js\";\nimport { isUsable, newUuid } from \"@pol-studios/utils\";\nimport { useDbQuery } from \"../../hooks/useDbQuery\";\nimport { useDbQueryById } from \"../../hooks/useDbQueryById\";\nimport useSupabase from \"../../useSupabase\";\nimport { setupAuthContext, type ProfileStatus, type EffectivePermission } from \"./setupAuthContext\";\n\n// Re-export from shared context for API compatibility\nexport { setupAuthContext, type SetupAuthContext, type SetupAuthContextProviderProps, type ProfileStatus, type EffectivePermission } from \"./setupAuthContext\";\n\n// Session fetch timeout - fail fast to avoid loading hangs\nconst SESSION_FETCH_TIMEOUT_MS = 3000;\n\n// ============================================================================\n// Types for access-related tables\n// ============================================================================\n\ninterface ProfileRow {\n id: string;\n email?: string | null;\n firstName?: string | null;\n lastName?: string | null;\n fullName?: string | null;\n status?: ProfileStatus | null;\n profilePath?: string | null;\n [key: string]: unknown;\n}\ninterface UserAccessRow {\n id: string;\n accessKey: string;\n effect: string;\n expiresAt: string | null;\n userId: string;\n}\ninterface UserGroupRow {\n id: string;\n userId: string;\n groupId: number;\n expiresAt: string | null;\n}\ninterface GroupRow {\n id: number;\n name: string;\n isActive: number; // PowerSync stores booleans as 0/1\n}\ninterface GroupAccessKeyRow {\n id: string;\n groupId: number;\n accessKey: string;\n effect: string;\n expiresAt?: string | null;\n}\nexport interface AuthProviderProps {\n children: ReactNode;\n}\n\n// ============================================================================\n// Permission Helpers\n// ============================================================================\n\n/** Maps permission action strings to numeric levels for comparison */\nfunction getPermissionLevel(action: string): number {\n switch (action.toLowerCase()) {\n case \"view\":\n case \"read\":\n return 1;\n case \"edit\":\n case \"write\":\n return 2;\n case \"admin\":\n case \"delete\":\n case \"share\":\n return 3;\n default:\n return 0;\n }\n}\n\n/** Check if a date string is not expired (null = never expires) */\nfunction isNotExpired(expiresAt: string | null | undefined): boolean {\n return !expiresAt || new Date(expiresAt) > new Date();\n}\n\n/**\n * Check if an access key pattern matches a requested key.\n * Supports wildcards (*) in any segment.\n *\n * Examples:\n * - \"*:*:*\" matches everything (super admin)\n * - \"project:*:read\" matches project:123:read\n * - \"project:123:*\" matches project:123:read, project:123:write\n */\nfunction matchesAccessPattern(pattern: string, requestedKey: string): boolean {\n if (pattern === requestedKey) return true;\n if (pattern === \"*:*:*\") return true;\n const patternParts = pattern.split(\":\");\n const keyParts = requestedKey.split(\":\");\n if (patternParts.length !== keyParts.length) return false;\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i] === \"*\") continue;\n if (patternParts[i] !== keyParts[i]) return false;\n }\n return true;\n}\n\n// ============================================================================\n// AuthProvider Component\n// ============================================================================\n\nexport function AuthProvider({\n children\n}: AuthProviderProps) {\n const supabase = useSupabase();\n\n // Auth state\n const [currentUser, setCurrentUser] = useState<User | null | undefined>(undefined);\n const [userNeedsChange, setUserNeedsChange] = useState(true);\n const [onSignOutCallbacks, setOnSignOutCallbacks] = useState(new Map<string, () => any>());\n\n // ─── Auth Actions ─────────────────────────────────────────────────────────\n\n async function registerAsync(register: SignUpWithPasswordCredentials) {\n const response = await supabase.auth.signUp(register);\n if (response.data.user) {\n setCurrentUser(prev => prev?.id === response.data.user?.id ? prev : response.data.user);\n }\n return response;\n }\n async function signInAsync(username: string, password: string) {\n const response_0 = await supabase.auth.signInWithPassword({\n email: username,\n password\n });\n if (response_0.data.user) {\n setCurrentUser(prev_0 => prev_0?.id === response_0.data.user?.id ? prev_0 : response_0.data.user);\n }\n return response_0;\n }\n const signOutAsync = useCallback(async () => {\n const response_1 = await supabase.auth.signOut();\n if (!response_1.error) {\n Array.from(onSignOutCallbacks.values()).forEach(cb => cb());\n }\n return response_1;\n }, [supabase.auth, onSignOutCallbacks]);\n function onSignOut(action: () => any) {\n const id = newUuid();\n setOnSignOutCallbacks(x => new Map(x).set(id, action));\n return id;\n }\n function removeOnSignOut(id_0: string) {\n setOnSignOutCallbacks(x_0 => {\n const map = new Map(x_0);\n map.delete(id_0);\n return map;\n });\n }\n async function refreshAsync() {}\n\n // ─── Session Management with Timeout ──────────────────────────────────────\n\n useEffect(() => {\n const {\n data: {\n subscription\n }\n } = supabase.auth.onAuthStateChange(event => {\n if (event === \"SIGNED_IN\" || event === \"SIGNED_OUT\") {\n setUserNeedsChange(true);\n }\n });\n return () => subscription.unsubscribe();\n }, [supabase.auth]);\n useEffect(() => {\n if (!userNeedsChange) return;\n let cancelled = false;\n async function fetchSessionWithTimeout() {\n try {\n // Race session fetch against timeout to prevent indefinite hangs\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Session fetch timed out after ${SESSION_FETCH_TIMEOUT_MS}ms`));\n }, SESSION_FETCH_TIMEOUT_MS);\n });\n const result = await Promise.race([supabase.auth.getSession(), timeoutPromise]);\n if (cancelled) return;\n const newUser = result?.data?.session?.user ?? null;\n setCurrentUser(prev_2 => {\n if (newUser === null) return null;\n if (prev_2?.id === newUser?.id) return prev_2;\n return newUser;\n });\n setUserNeedsChange(false);\n } catch (error) {\n if (cancelled) return;\n console.error(\"Failed to get session (timeout or error):\", error);\n setCurrentUser(prev_1 => prev_1 === null ? prev_1 : null);\n setUserNeedsChange(false);\n }\n }\n fetchSessionWithTimeout();\n return () => {\n cancelled = true;\n };\n }, [userNeedsChange, supabase.auth]);\n\n // ─── Query Profile and Access via useDbQuery ──────────────────────────────\n // Uses auto strategy: Supabase primary, PowerSync offline backup\n\n const isUserReady = isUsable(currentUser);\n\n // Profile query - useDbQueryById returns single object, not array\n const {\n data: profile,\n isLoading: profileLoading\n } = useDbQueryById<ProfileRow>(\"core.Profile\", currentUser?.id ?? \"\", {\n enabled: isUserReady\n });\n const {\n data: directAccess,\n isLoading: directAccessLoading\n } = useDbQuery<UserAccessRow>(\"core.UserAccess\", {\n where: {\n userId: currentUser?.id\n },\n enabled: isUserReady,\n realtime: true\n });\n const {\n data: userGroups,\n isLoading: userGroupsLoading\n } = useDbQuery<UserGroupRow>(\"core.UserGroup\", {\n where: {\n userId: currentUser?.id\n },\n enabled: isUserReady,\n realtime: true\n });\n const {\n data: groups,\n isLoading: groupsLoading\n } = useDbQuery<GroupRow>(\"core.Group\", {\n where: {\n isActive: 1\n },\n enabled: isUserReady,\n realtime: true\n });\n\n // Get group IDs user belongs to\n const groupIds = useMemo(() => userGroups?.map(ug => ug.groupId) ?? [], [userGroups]);\n\n // Map groups by ID for O(1) lookups\n const groupsMap = useMemo(() => new Map(groups?.map(g => [g.id, g]) ?? []), [groups]);\n const {\n data: groupAccess,\n isLoading: groupAccessLoading\n } = useDbQuery<GroupAccessKeyRow>(\"core.GroupAccessKey\", {\n where: groupIds.length > 0 ? {\n groupId: {\n in: groupIds\n }\n } : undefined,\n enabled: groupIds.length > 0,\n realtime: true\n });\n\n // Track previous profile status for signout logic\n const prevProfileStatusRef = useRef<string | null | undefined>(undefined);\n\n // Auto-signout if profile becomes archived/suspended\n useEffect(() => {\n const currentStatus = profile?.status;\n const prevStatus = prevProfileStatusRef.current;\n\n // Only trigger signout if status changed FROM active TO archived/suspended\n if (prevStatus === \"active\" && (currentStatus === \"archived\" || currentStatus === \"suspended\")) {\n signOutAsync();\n }\n prevProfileStatusRef.current = currentStatus;\n }, [profile?.status, signOutAsync]);\n\n // All access keys with metadata\n const allAccessKeys = useMemo(() => {\n const keys: Array<{\n accessKey: string;\n effect: string;\n source: \"direct\" | \"group\";\n expiresAt?: string | null;\n }> = [];\n\n // Add direct access keys (filter out expired)\n directAccess?.forEach(a => {\n if (isNotExpired(a.expiresAt)) {\n keys.push({\n accessKey: a.accessKey,\n effect: a.effect ?? \"allow\",\n source: \"direct\",\n expiresAt: a.expiresAt\n });\n }\n });\n\n // Add group access keys (only from active groups user belongs to)\n const activeGroupIds = new Set(userGroups?.filter(ug_0 => {\n const group = groupsMap.get(ug_0.groupId);\n return group?.isActive === 1 && isNotExpired(ug_0.expiresAt);\n }).map(ug_1 => ug_1.groupId) ?? []);\n groupAccess?.forEach(ga => {\n if (activeGroupIds.has(ga.groupId) && isNotExpired(ga.expiresAt)) {\n keys.push({\n accessKey: ga.accessKey,\n effect: ga.effect ?? \"allow\",\n source: \"group\",\n expiresAt: ga.expiresAt\n });\n }\n });\n return keys;\n }, [directAccess, userGroups, groupsMap, groupAccess]);\n\n // Combine access keys into a simple string array for hasAccess checks\n const combinedAccess: string[] = useMemo(() => {\n const uniqueKeys = new Set<string>();\n for (const item of allAccessKeys) {\n if (item.accessKey && item.effect === \"allow\") {\n uniqueKeys.add(item.accessKey);\n }\n }\n return Array.from(uniqueKeys);\n }, [allAccessKeys]);\n\n // Compute effective permissions\n const effectivePermissions: EffectivePermission[] = useMemo(() => {\n const permissions: EffectivePermission[] = [];\n for (const item_0 of allAccessKeys) {\n if (item_0.effect !== \"allow\") continue;\n const parts = item_0.accessKey.split(\":\");\n if (parts.length === 3) {\n const [resourceType, resourceId, permission] = parts;\n permissions.push({\n resourceType,\n resourceId,\n permission,\n permissionLevel: getPermissionLevel(permission),\n source: item_0.source,\n inheritedFrom: null,\n expiresAt: item_0.expiresAt ?? null\n });\n }\n }\n return permissions;\n }, [allAccessKeys]);\n\n // Profile status values\n const profileStatus = profile?.status as ProfileStatus | undefined;\n const isArchived = profileStatus === \"archived\";\n const isSuspended = profileStatus === \"suspended\";\n\n // ─── hasAccess Function ───────────────────────────────────────────────────\n\n const hasAccess = useCallback((key: string) => {\n // Archived/suspended users have no access\n if (isArchived || isSuspended) return false;\n if (!isUsable(combinedAccess)) return false;\n\n // Super-admin key bypasses all permission checks\n if (combinedAccess.includes(\"*:*:*\")) return true;\n\n // Check exact match\n if (combinedAccess.includes(key)) return true;\n\n // Empty key = no restriction\n if (!isUsable(key)) return true;\n\n // Check wildcard patterns\n for (const pattern of combinedAccess) {\n if (matchesAccessPattern(pattern, key)) return true;\n }\n\n // Check permission levels for type:id:action format\n const parts_0 = key.split(\":\");\n if (parts_0.length === 3) {\n const [type, id_1, action_0] = parts_0;\n const requiredLevel = getPermissionLevel(action_0);\n const hasPermission = effectivePermissions.some(p => p.resourceType === type && p.resourceId === id_1 && p.permissionLevel >= requiredLevel);\n if (hasPermission) return true;\n }\n return false;\n }, [combinedAccess, effectivePermissions, isArchived, isSuspended]);\n\n // ─── Loading State ────────────────────────────────────────────────────────\n\n const isAccessLoading = directAccessLoading || userGroupsLoading || groupsLoading || groupAccessLoading;\n const authState = useMemo(() => ({\n hasAccess,\n user: currentUser,\n profile,\n access: combinedAccess,\n effectivePermissions,\n profileStatus,\n isArchived,\n isSuspended,\n isLoading: currentUser === null ? false : profileLoading || isAccessLoading || currentUser === undefined,\n signInAsync,\n signOutAsync,\n onSignOut,\n removeOnSignOut,\n registerAsync,\n refreshAsync\n }), [hasAccess, currentUser, profile, combinedAccess, effectivePermissions, profileStatus, isArchived, isSuspended, profileLoading, isAccessLoading]);\n return <setupAuthContext.Provider value={authState}>\n {children}\n </setupAuthContext.Provider>;\n}\nexport type Profile = ProfileRow;","import { createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport useSupabase from \"../../useSupabase\";\nimport { setupAuthContext } from \"./setupAuthContext\";\nimport { EntityType, EntityPermissionLevel, EntityAction, EntityPermissionCheck } from \"../types/EntityPermissions\";\n\n// Cache entry with TTL\ninterface CacheEntry {\n permission: EntityPermissionCheck;\n expiresAt: number;\n}\n\n// Entity identifier for batch lookups\ninterface EntityIdentifier {\n entityType: EntityType;\n entityId: number;\n}\n\n// Cache key helper\nfunction getCacheKey(userId: string | undefined, entityType: EntityType, entityId: number): string {\n return `${userId || \"anon\"}:${entityType}:${entityId}`;\n}\n\n// Default loading state\nconst loadingPermission: EntityPermissionCheck = {\n canView: false,\n canAdminView: false,\n canEdit: false,\n canCreate: false,\n canDelete: false,\n canShare: false,\n permissionLevel: null,\n isLoading: true\n};\n\n// No permission state\nconst noPermission: EntityPermissionCheck = {\n canView: false,\n canAdminView: false,\n canEdit: false,\n canCreate: false,\n canDelete: false,\n canShare: false,\n permissionLevel: null,\n isLoading: false,\n isDenied: false\n};\n\n// Denied permission state - explicitly blocked access\nconst deniedPermission: EntityPermissionCheck = {\n canView: false,\n canAdminView: false,\n canEdit: false,\n canCreate: false,\n canDelete: false,\n canShare: false,\n permissionLevel: null,\n isLoading: false,\n isDenied: true\n};\n\n// Map permission level to permission check\n// If permission is 'denied', it means access was explicitly blocked\n// Handles both legacy formats (ReadOnly, AdminReadOnly, ReadWrite, Admin)\n// and new formats (view, edit, admin, denied)\nfunction mapPermissionLevel(level: EntityPermissionLevel | \"denied\" | string | null): EntityPermissionCheck {\n if (!level) {\n return noPermission;\n }\n\n // Normalize to lowercase for comparison to handle both legacy and new formats\n const normalizedLevel = level.toLowerCase();\n switch (normalizedLevel) {\n // Legacy format: ReadOnly, New format: view\n case \"readonly\":\n case \"view\":\n return {\n canView: true,\n canAdminView: false,\n canEdit: false,\n canCreate: false,\n canDelete: false,\n canShare: false,\n permissionLevel: \"ReadOnly\",\n isLoading: false,\n isDenied: false\n };\n // Legacy format: AdminReadOnly (no new equivalent, keep for backwards compatibility)\n case \"adminreadonly\":\n return {\n canView: true,\n canAdminView: true,\n canEdit: false,\n canCreate: false,\n canDelete: false,\n canShare: false,\n permissionLevel: \"AdminReadOnly\",\n isLoading: false,\n isDenied: false\n };\n // Legacy format: ReadWrite, New format: edit\n case \"readwrite\":\n case \"edit\":\n return {\n canView: true,\n canAdminView: false,\n canEdit: true,\n canCreate: true,\n canDelete: false,\n canShare: false,\n permissionLevel: \"ReadWrite\",\n isLoading: false,\n isDenied: false\n };\n // Legacy format: Admin, New format: admin\n case \"admin\":\n return {\n canView: true,\n canAdminView: true,\n canEdit: true,\n canCreate: true,\n canDelete: true,\n canShare: true,\n permissionLevel: \"Admin\",\n isLoading: false,\n isDenied: false\n };\n // New format: denied - explicit access denial\n case \"denied\":\n return deniedPermission;\n default:\n console.warn(`Unknown permission level: ${level}`);\n return noPermission;\n }\n}\n\n// Context interface\nexport interface PermissionContextValue {\n getPermission: (entityType: EntityType, entityId: number) => EntityPermissionCheck;\n checkPermission: (entityType: EntityType, entityId: number, action: EntityAction) => boolean;\n prefetchPermissions: (entities: EntityIdentifier[]) => Promise<void>;\n invalidatePermission: (entityType: EntityType, entityId: number) => void;\n isLoading: boolean;\n}\n\n/**\n * @deprecated Use permissionContext instead\n */\nexport interface EntityPermissionContextValue extends PermissionContextValue {}\nexport const permissionContext = createContext<PermissionContextValue>({} as PermissionContextValue);\n\n/**\n * @deprecated Use permissionContext instead\n */\nexport const entityPermissionContext = permissionContext;\n\n// TTL for cache entries (5 minutes)\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n// TTL for error cache entries (30 seconds) - shorter to allow quick retry\nconst ERROR_CACHE_TTL_MS = 30 * 1000;\n\n// Batch collection delay (50ms)\nconst BATCH_DELAY_MS = 50;\nexport function PermissionProvider({\n children\n}: {\n children: ReactNode;\n}) {\n const supabase = useSupabase();\n const setupAuth = useContext(setupAuthContext);\n const user = setupAuth?.user;\n\n // Permission cache\n const cacheRef = useRef<Map<string, CacheEntry>>(new Map());\n\n // Pending lookups for batching\n const pendingLookupsRef = useRef<Set<string>>(new Set());\n\n // In-flight lookups to prevent duplicate requests during async RPC calls\n const inFlightRef = useRef<Set<string>>(new Set());\n\n // Batch timer ref\n const batchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Loading state\n const [isLoading, setIsLoading] = useState(false);\n\n // Force re-render trigger\n const [, forceUpdate] = useState(0);\n\n // Clean up expired cache entries\n const cleanupExpiredEntries = useCallback(() => {\n const now = Date.now();\n const cache = cacheRef.current;\n let hasExpired = false;\n for (const [key, entry] of cache.entries()) {\n if (entry.expiresAt < now) {\n cache.delete(key);\n hasExpired = true;\n }\n }\n if (hasExpired) {\n forceUpdate(prev => prev + 1);\n }\n }, []);\n\n // Periodic cleanup of expired entries\n useEffect(() => {\n const cleanupInterval = setInterval(cleanupExpiredEntries, 60 * 1000);\n return () => clearInterval(cleanupInterval);\n }, [cleanupExpiredEntries]);\n\n // Execute batch lookup\n const executeBatchLookup = useCallback(async () => {\n const pending = Array.from(pendingLookupsRef.current);\n pendingLookupsRef.current.clear();\n if (pending.length === 0 || !user?.id) {\n return;\n }\n\n // Move pending keys to in-flight to prevent duplicate requests\n pending.forEach(k => inFlightRef.current.add(k));\n setIsLoading(true);\n try {\n // Parse pending keys back to entities (format: userId:entityType:entityId)\n const entities = pending.map(key_0 => {\n const parts = key_0.split(\":\");\n // Skip the userId part (index 0), use entityType (index 1) and entityId (index 2)\n const entityType = parts[1];\n const entityIdStr = parts[2];\n return {\n entity_type: entityType as EntityType,\n entity_id: parseInt(entityIdStr, 10)\n };\n });\n\n // Call RPC for batch lookup\n // Using 'as any' because the RPC function type isn't in the generated database types\n const {\n data,\n error\n } = await (supabase.rpc as any)(\"get_user_entity_permissions\", {\n p_user_id: user.id,\n p_entities: entities\n });\n if (error) {\n console.error(\"Failed to fetch entity permissions:\", error);\n // Mark all pending as no permission with shorter TTL to allow quick retry\n const cache_0 = cacheRef.current;\n const now_0 = Date.now();\n for (const key_1 of pending) {\n cache_0.set(key_1, {\n permission: noPermission,\n expiresAt: now_0 + ERROR_CACHE_TTL_MS\n });\n }\n } else if (data) {\n // Update cache with results\n const cache_1 = cacheRef.current;\n const now_1 = Date.now();\n\n // Create a map of results for quick lookup\n // Permission can be a standard level or 'denied' for explicit deny\n const resultsMap = new Map<string, EntityPermissionLevel | \"denied\">();\n // Type the data as an array of permission results\n const results = data as Array<{\n entity_type: EntityType;\n entity_id: number;\n permission: EntityPermissionLevel | \"denied\";\n }>;\n for (const result of results) {\n const key_2 = getCacheKey(user?.id, result.entity_type, result.entity_id);\n resultsMap.set(key_2, result.permission);\n }\n\n // Update cache for all pending keys\n for (const key_3 of pending) {\n const permissionLevel = resultsMap.get(key_3) || null;\n cache_1.set(key_3, {\n permission: mapPermissionLevel(permissionLevel),\n expiresAt: now_1 + CACHE_TTL_MS\n });\n }\n }\n forceUpdate(prev_0 => prev_0 + 1);\n } catch (err) {\n console.error(\"Unexpected error fetching entity permissions:\", err);\n } finally {\n // Remove from in-flight after completion (success or error)\n pending.forEach(k => inFlightRef.current.delete(k));\n setIsLoading(false);\n }\n }, [supabase, user?.id]);\n\n // Schedule batch lookup\n const scheduleBatchLookup = useCallback(() => {\n if (batchTimerRef.current) {\n clearTimeout(batchTimerRef.current);\n }\n batchTimerRef.current = setTimeout(() => {\n batchTimerRef.current = null;\n executeBatchLookup();\n }, BATCH_DELAY_MS);\n }, [executeBatchLookup]);\n\n // Get permission for an entity\n const getPermission = useCallback((entityType_0: EntityType, entityId: number): EntityPermissionCheck => {\n const key_4 = getCacheKey(user?.id, entityType_0, entityId);\n const cache_2 = cacheRef.current;\n const cached = cache_2.get(key_4);\n const now_2 = Date.now();\n\n // Return cached if valid\n if (cached && cached.expiresAt > now_2) {\n return cached.permission;\n }\n\n // Don't add if already pending or in-flight to prevent duplicate requests\n if (!pendingLookupsRef.current.has(key_4) && !inFlightRef.current.has(key_4)) {\n pendingLookupsRef.current.add(key_4);\n scheduleBatchLookup();\n }\n return loadingPermission;\n }, [scheduleBatchLookup, user?.id]);\n\n // Check specific permission action\n const checkPermission = useCallback((entityType_1: EntityType, entityId_0: number, action: EntityAction): boolean => {\n const permission = getPermission(entityType_1, entityId_0);\n if (permission.isLoading) {\n return false;\n }\n switch (action) {\n case \"view\":\n return permission.canView;\n case \"adminView\":\n return permission.canAdminView;\n case \"edit\":\n return permission.canEdit;\n case \"create\":\n return permission.canCreate;\n case \"delete\":\n return permission.canDelete;\n case \"share\":\n return permission.canShare;\n default:\n return false;\n }\n }, [getPermission]);\n\n // Prefetch permissions for multiple entities\n const prefetchPermissions = useCallback(async (entities_0: EntityIdentifier[]): Promise<void> => {\n if (!user?.id || entities_0.length === 0) {\n return;\n }\n const cache_3 = cacheRef.current;\n const now_3 = Date.now();\n\n // Filter out already cached entries, items already pending, and items in-flight\n const toFetch = entities_0.filter(entity => {\n const key_5 = getCacheKey(user?.id, entity.entityType, entity.entityId);\n const cached_0 = cache_3.get(key_5);\n const isPending = pendingLookupsRef.current.has(key_5);\n const isInFlight = inFlightRef.current.has(key_5);\n return !isPending && !isInFlight && (!cached_0 || cached_0.expiresAt <= now_3);\n });\n if (toFetch.length === 0) {\n return;\n }\n setIsLoading(true);\n try {\n const entitiesParam = toFetch.map(e => ({\n entity_type: e.entityType,\n entity_id: e.entityId\n }));\n\n // Using 'as any' because the RPC function type isn't in the generated database types\n const {\n data: data_0,\n error: error_0\n } = await (supabase.rpc as any)(\"get_user_entity_permissions\", {\n p_user_id: user.id,\n p_entities: entitiesParam\n });\n if (error_0) {\n console.error(\"Failed to prefetch entity permissions:\", error_0);\n return;\n }\n if (data_0) {\n // Capture timestamp AFTER the RPC call completes\n const cacheTimestamp = Date.now();\n\n // Permission can be a standard level or 'denied' for explicit deny\n const resultsMap_0 = new Map<string, EntityPermissionLevel | \"denied\">();\n // Type the data as an array of permission results\n const results_0 = data_0 as Array<{\n entity_type: EntityType;\n entity_id: number;\n permission: EntityPermissionLevel | \"denied\";\n }>;\n for (const result_0 of results_0) {\n const key_6 = getCacheKey(user?.id, result_0.entity_type, result_0.entity_id);\n resultsMap_0.set(key_6, result_0.permission);\n }\n for (const entity_0 of toFetch) {\n const key_7 = getCacheKey(user?.id, entity_0.entityType, entity_0.entityId);\n const permissionLevel_0 = resultsMap_0.get(key_7) || null;\n cache_3.set(key_7, {\n permission: mapPermissionLevel(permissionLevel_0),\n expiresAt: cacheTimestamp + CACHE_TTL_MS\n });\n }\n forceUpdate(prev_1 => prev_1 + 1);\n }\n } catch (err_0) {\n console.error(\"Unexpected error prefetching entity permissions:\", err_0);\n } finally {\n setIsLoading(false);\n }\n }, [supabase, user?.id]);\n\n // Invalidate a specific permission\n const invalidatePermission = useCallback((entityType_2: EntityType, entityId_1: number): void => {\n const key_8 = getCacheKey(user?.id, entityType_2, entityId_1);\n cacheRef.current.delete(key_8);\n forceUpdate(prev_2 => prev_2 + 1);\n }, [user?.id]);\n\n // Parse scoped access key format: <entity_type>:<entity_id>:<permission_level>\n // Returns null if the key format is invalid\n const parseScopedAccessKey = useCallback((key_9: string): {\n entityType: EntityType;\n entityId: number;\n } | null => {\n if (!key_9 || typeof key_9 !== \"string\") {\n return null;\n }\n const parts_0 = key_9.split(\":\");\n if (parts_0.length < 2) {\n return null;\n }\n const entityType_3 = parts_0[0];\n const entityId_2 = parseInt(parts_0[1], 10);\n if (isNaN(entityId_2)) {\n return null;\n }\n // Use explicit mapping instead of string manipulation\n // This correctly handles \"database\" -> \"ProjectDatabase\" case\n const entityTypeMap: Record<string, EntityType> = {\n client: \"Client\",\n project: \"Project\",\n database: \"ProjectDatabase\",\n projectdatabase: \"ProjectDatabase\"\n };\n const normalizedEntityType = entityTypeMap[entityType_3.toLowerCase()];\n if (!normalizedEntityType) {\n return null;\n }\n return {\n entityType: normalizedEntityType,\n entityId: entityId_2\n };\n }, []);\n\n // Real-time subscription for permission changes\n useEffect(() => {\n if (!user?.id) {\n return;\n }\n\n // Subscribe to changes on UserAccess table for the current user\n // Use unique channel name per user to avoid collisions\n const channel = supabase.channel(`entity-permissions-${user.id}`).on(\"postgres_changes\", {\n event: \"*\",\n schema: \"core\",\n table: \"UserAccess\",\n filter: `userId=eq.${user.id}`\n }, payload => {\n // Parse the scoped access key from the new record\n if (payload.new && typeof payload.new === \"object\" && \"scopedAccessKey\" in payload.new && typeof payload.new.scopedAccessKey === \"string\") {\n const parsed = parseScopedAccessKey(payload.new.scopedAccessKey);\n if (parsed) {\n invalidatePermission(parsed.entityType, parsed.entityId);\n }\n }\n // Parse the scoped access key from the old record (for deletes/updates)\n if (payload.old && typeof payload.old === \"object\" && \"scopedAccessKey\" in payload.old && typeof payload.old.scopedAccessKey === \"string\") {\n const parsed_0 = parseScopedAccessKey(payload.old.scopedAccessKey);\n if (parsed_0) {\n invalidatePermission(parsed_0.entityType, parsed_0.entityId);\n }\n }\n }).subscribe();\n return () => {\n channel.unsubscribe();\n supabase.removeChannel(channel);\n };\n }, [supabase, user?.id, invalidatePermission, parseScopedAccessKey]);\n\n // Clear cache on user change\n useEffect(() => {\n cacheRef.current.clear();\n pendingLookupsRef.current.clear();\n inFlightRef.current.clear();\n if (batchTimerRef.current) {\n clearTimeout(batchTimerRef.current);\n batchTimerRef.current = null;\n }\n forceUpdate(prev_3 => prev_3 + 1);\n }, [user?.id]);\n\n // Cleanup batch timer on unmount\n useEffect(() => {\n return () => {\n if (batchTimerRef.current) {\n clearTimeout(batchTimerRef.current);\n }\n };\n }, []);\n const value = useMemo(() => ({\n getPermission,\n checkPermission,\n prefetchPermissions,\n invalidatePermission,\n isLoading\n }), [getPermission, checkPermission, prefetchPermissions, invalidatePermission, isLoading]);\n return <permissionContext.Provider value={value}>\n {children}\n </permissionContext.Provider>;\n}\nexport function usePermissions() {\n const context = useContext(permissionContext);\n if (!context || Object.keys(context).length === 0) {\n throw new Error(\"usePermissions must be used within a PermissionProvider\");\n }\n return context;\n}","import { c as _c } from \"react/compiler-runtime\";\nimport { ReactNode, createContext, useContext, useEffect, useMemo, useState, useCallback, useRef } from \"react\";\nimport { useDbQuery as useQuery } from \"../../useDbQuery\";\nimport { useDbUpsert as useUpsert } from \"../../useDbUpsert\";\nimport useSupabase, { Database } from \"../../useSupabase\";\nimport { isUsable } from \"@pol-studios/utils\";\nimport { setupAuthContext } from \"./AuthProvider\";\n\n// UserMetadata query constant\nconst UserMetadataQuery = {\n schema: \"core\",\n table: \"UserMetadata\",\n defaultQuery: \"key, userId, value\"\n} as const;\n\n// Type definitions for UserMetadata\nexport type UserMetadataRow = Database[\"core\"][\"Tables\"][\"UserMetadata\"][\"Row\"];\nexport type UserMetadataInsert = Database[\"core\"][\"Tables\"][\"UserMetadata\"][\"Insert\"];\nexport type UserMetadataUpdate = Database[\"core\"][\"Tables\"][\"UserMetadata\"][\"Update\"];\n\n// Context interface\nexport interface UserMetadataContextType {\n metadata: Record<string, string>;\n isLoading: boolean;\n error: Error | null;\n setMetadata: (key: string, value: string) => Promise<void>;\n getMetadata: (key: string) => string | undefined;\n removeMetadata: (key: string) => Promise<void>;\n refreshMetadata: () => Promise<void>;\n}\n\n// Create context\nexport const userMetadataContext = createContext<UserMetadataContextType | null>(null);\n\n// Provider component\nexport function UserMetadataProvider({\n children\n}: {\n children: ReactNode;\n}) {\n const supabase = useSupabase();\n const [metadata, setMetadataState] = useState<Record<string, string>>({});\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Get current user ID from auth context\n const setupAuth = useContext(setupAuthContext);\n const userId = setupAuth?.user?.id;\n\n // Query to fetch all user metadata\n const metadataQuery = useQuery(supabase.schema(\"core\").from(\"UserMetadata\").select(UserMetadataQuery.defaultQuery).eq(\"userId\", userId!).order(\"key\"), {\n enabled: isUsable(userId),\n crossOrganization: true\n });\n\n // Upsert mutation for updating metadata\n const upsertMutation = useUpsert({\n table: \"UserMetadata\",\n schema: \"core\"\n }, [\"userId\", \"key\"] // composite primary keys\n );\n\n // Ref to hold mutation to avoid infinite loops in useCallback dependencies\n const upsertMutationRef = useRef(upsertMutation);\n upsertMutationRef.current = upsertMutation;\n\n // Update local state when query data changes\n useEffect(() => {\n if (metadataQuery.data && Array.isArray(metadataQuery.data)) {\n const metadataMap: Record<string, string> = {};\n metadataQuery.data.forEach((item: any) => {\n metadataMap[item.key] = item.value;\n });\n setMetadataState(metadataMap);\n setIsLoading(false);\n setError(null);\n } else if (metadataQuery.error) {\n setError(metadataQuery.error);\n setIsLoading(false);\n } else if (metadataQuery.isLoading) {\n setIsLoading(true);\n } else if (metadataQuery.data && !Array.isArray(metadataQuery.data)) {\n // Handle case where data is not an array (e.g., empty response or count)\n setMetadataState({});\n setIsLoading(false);\n }\n }, [metadataQuery.data, metadataQuery.error, metadataQuery.isLoading]);\n\n // Set metadata function\n const setMetadata = useCallback(async (key: string, value: string) => {\n if (!userId) {\n throw new Error(\"User not authenticated\");\n }\n try {\n await upsertMutationRef.current.mutateAsync({\n userId,\n key,\n value\n });\n\n // Update local state optimistically\n setMetadataState(prev => ({\n ...prev,\n [key]: value\n }));\n } catch (err) {\n setError(err as Error);\n throw err;\n }\n }, [userId]);\n\n // Get metadata function\n const getMetadata = useCallback((key_0: string): string | undefined => {\n return metadata[key_0];\n }, [metadata]);\n\n // Remove metadata function\n const removeMetadata = useCallback(async (key_1: string) => {\n if (!userId) {\n throw new Error(\"User not authenticated\");\n }\n try {\n await supabase.schema(\"core\").from(\"UserMetadata\").delete().eq(\"userId\", userId).eq(\"key\", key_1);\n\n // Update local state\n setMetadataState(prev_0 => {\n const newState = {\n ...prev_0\n };\n delete newState[key_1];\n return newState;\n });\n } catch (err_0) {\n setError(err_0 as Error);\n throw err_0;\n }\n }, [userId, supabase]);\n\n // Refresh metadata function\n const refreshMetadata = useCallback(async () => {\n await metadataQuery.refetch();\n }, [metadataQuery]);\n\n // Context value\n const contextValue = useMemo(() => ({\n metadata,\n isLoading,\n error,\n setMetadata,\n getMetadata,\n removeMetadata,\n refreshMetadata\n }), [metadata, isLoading, error, setMetadata, getMetadata, removeMetadata, refreshMetadata]);\n return <userMetadataContext.Provider value={contextValue}>\n {children}\n </userMetadataContext.Provider>;\n}\n\n// Hook to use the context\nexport function useUserMetadata() {\n const context = useContext(userMetadataContext);\n if (!context) {\n throw new Error(\"useUserMetadata must be used within a UserMetadataProvider\");\n }\n return context;\n}\n\n// Convenience hook for getting a specific metadata value\nexport function useUserMetadataValue(key) {\n const $ = _c(3);\n const {\n getMetadata\n } = useUserMetadata();\n let t0;\n if ($[0] !== getMetadata || $[1] !== key) {\n t0 = getMetadata(key);\n $[0] = getMetadata;\n $[1] = key;\n $[2] = t0;\n } else {\n t0 = $[2];\n }\n return t0;\n}\n\n// Convenience hook for setting a specific metadata value\nexport function useSetUserMetadata() {\n const $ = _c(3);\n const {\n setMetadata,\n removeMetadata\n } = useUserMetadata();\n let t0;\n if ($[0] !== removeMetadata || $[1] !== setMetadata) {\n t0 = {\n setMetadata,\n removeMetadata\n };\n $[0] = removeMetadata;\n $[1] = setMetadata;\n $[2] = t0;\n } else {\n t0 = $[2];\n }\n return t0;\n}\n\n// Advanced state-like hook with JSON serialization support\nexport function useUserMetadataState(key, defaultValue, options) {\n const $ = _c(11);\n const {\n metadata,\n setMetadata,\n isLoading\n } = useUserMetadata();\n const serialize = options?.serialize ?? _temp;\n const deserialize = options?.deserialize ?? _temp2;\n let t0;\n bb0: {\n const rawValue = metadata[key];\n if (!rawValue) {\n t0 = defaultValue;\n break bb0;\n }\n ;\n try {\n let t2;\n if ($[0] !== deserialize || $[1] !== rawValue) {\n t2 = deserialize(rawValue);\n $[0] = deserialize;\n $[1] = rawValue;\n $[2] = t2;\n } else {\n t2 = $[2];\n }\n t0 = t2;\n } catch (t1) {\n const error = t1;\n console.warn(`Failed to deserialize metadata for key \"${key}\":`, error);\n t0 = defaultValue;\n }\n }\n const currentValue = t0;\n let t1;\n if ($[3] !== key || $[4] !== serialize || $[5] !== setMetadata) {\n t1 = async value_1 => {\n const serializedValue = serialize(value_1);\n await setMetadata(key, serializedValue);\n };\n $[3] = key;\n $[4] = serialize;\n $[5] = setMetadata;\n $[6] = t1;\n } else {\n t1 = $[6];\n }\n const setValue = t1;\n let t2;\n if ($[7] !== currentValue || $[8] !== isLoading || $[9] !== setValue) {\n t2 = [currentValue, setValue, isLoading];\n $[7] = currentValue;\n $[8] = isLoading;\n $[9] = setValue;\n $[10] = t2;\n } else {\n t2 = $[10];\n }\n return t2;\n}\nfunction _temp2(value_0) {\n return JSON.parse(value_0);\n}\nfunction _temp(value) {\n return JSON.stringify(value);\n}","import { c as _c } from \"react/compiler-runtime\";\nimport { useMutation } from \"@tanstack/react-query\";\nimport useSupabase, { Database } from \"./useSupabase\";\nimport { useQueriesForTableLoader, useUpdateMutation, useUpsertItem } from \"@supabase-cache-helpers/postgrest-react-query\";\nimport { GetResult } from \"./parser/select-query-parser\";\nimport { GenericSchema } from \"./parser/types\";\nimport { isUsable } from \"@pol-studios/utils\";\nimport { omit } from \"@pol-studios/utils\";\nimport { buildNormalizedQuery } from \"@supabase-cache-helpers/postgrest-core\";\ntype ItemType<T> = T extends Array<infer U> ? U : T;\nexport type MutationOption = Parameters<typeof useUpdateMutation>[3];\nexport type useDbUpsertResponse = ReturnType<typeof useDbUpsert>;\nexport function useDbUpsert(relation, t0, query, mutationOption) {\n const $ = _c(16);\n let t1;\n if ($[0] !== t0) {\n t1 = t0 === undefined ? [\"id\"] : t0;\n $[0] = t0;\n $[1] = t1;\n } else {\n t1 = $[1];\n }\n const primaryKeys = t1;\n const tableName = typeof relation === \"object\" ? relation.table : relation;\n const schemaName = typeof relation === \"object\" ? String(relation.schema) : \"public\";\n const supabase = useSupabase();\n let t2;\n if ($[2] !== primaryKeys) {\n t2 = primaryKeys.map(_temp);\n $[2] = primaryKeys;\n $[3] = t2;\n } else {\n t2 = $[3];\n }\n const primaryKeysAsStrings = t2 as string[];\n const t3 = primaryKeysAsStrings as any;\n const t4 = relation as any;\n let t5;\n if ($[4] !== t3 || $[5] !== t4) {\n t5 = {\n primaryKeys: t3,\n table: t4,\n schema: \"public\"\n };\n $[4] = t3;\n $[5] = t4;\n $[6] = t5;\n } else {\n t5 = $[6];\n }\n const upsertItem = useUpsertItem(t5);\n const queriesForTable = useQueriesForTableLoader(tableName);\n let t6;\n if ($[7] !== primaryKeys || $[8] !== primaryKeysAsStrings || $[9] !== queriesForTable || $[10] !== query || $[11] !== schemaName || $[12] !== supabase || $[13] !== tableName || $[14] !== upsertItem) {\n t6 = {\n mutationFn: async item => {\n let result = null;\n const selectQuery = buildNormalizedQuery({\n queriesForTable,\n query\n });\n const insert = async function insert() {\n const keysToFilter = primaryKeys.filter(x => isUsable((item as any)[x]) === false);\n const keysToFilterAsStrings = keysToFilter.map(_temp2) as string[];\n const response = await (supabase as any).schema(schemaName as \"public\" | \"core\").from(tableName).insert(omit(item as any, keysToFilterAsStrings as any) as any).select(query).single();\n if (response.error) {\n throw response.error;\n }\n result = response.data as any;\n if (result) {\n upsertItem(result as any);\n }\n };\n const isUpsertable = primaryKeys.every(x_0 => x_0 in item && isUsable((item as any)[x_0]));\n if (isUpsertable) {\n const query_0 = (supabase as any).schema(schemaName as \"public\" | \"core\").from(tableName).update(omit(item as any, primaryKeysAsStrings as any) as any);\n primaryKeys.forEach(x_1 => {\n query_0.eq(String(x_1), (item as any)[x_1]);\n });\n const queryResponse = await query_0.select(selectQuery?.selectQuery).single();\n console.log(\"queryResponse\", queryResponse, tableName);\n if (queryResponse.status === 406) {\n await insert();\n } else {\n if (queryResponse.error) {\n throw queryResponse.error;\n }\n if (queryResponse.data) {\n result = queryResponse.data as any;\n if (result) {\n upsertItem(result as any);\n }\n }\n }\n } else {\n await insert();\n }\n return result as any;\n }\n };\n $[7] = primaryKeys;\n $[8] = primaryKeysAsStrings;\n $[9] = queriesForTable;\n $[10] = query;\n $[11] = schemaName;\n $[12] = supabase;\n $[13] = tableName;\n $[14] = upsertItem;\n $[15] = t6;\n } else {\n t6 = $[15];\n }\n const mutation = useMutation(t6);\n return mutation;\n}\nfunction _temp2(k_0) {\n return String(k_0);\n}\nfunction _temp(k) {\n return String(k);\n}"],"mappings":"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","names":["useDbQuery","useMemo","useRef","useMemo","useRef","createContext","useCallback","useEffect","useMemo","useRef","useState","jsx","createContext","useRef","useState","useCallback","useEffect","useMemo","_c","createContext","useContext","useEffect","useMemo","useState","useCallback","useRef","isUsable","omit","insert","isUsable","omit","isUsable","jsx","createContext","useState","useContext","useDbQuery","isUsable","useRef","useEffect","useCallback","useMemo","_c","_temp","_temp2","t2","t1"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/DataLayerContext.ts","../src/hooks/useDataLayer.ts","../src/hooks/useDbQuery.ts","../src/utils/dev-log.ts","../src/hooks/useDbQueryById.ts"],"sourcesContent":["/**\n * V3 Data Layer Context\n *\n * Defines the React context and types for the V3 data layer provider.\n * This context provides access to adapters, sync status, and core instances.\n *\n * PERFORMANCE OPTIMIZATION:\n * The context is split into two separate contexts to prevent unnecessary re-renders:\n * - DataLayerCoreContext: Stable values that don't change after initialization\n * - DataLayerStatusContext: Dynamic values that change during runtime\n *\n * The original DataLayerContext is kept for backward compatibility.\n */\n\nimport { createContext } from \"react\";\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport type { AdapterRegistry } from \"../adapters/registry\";\nimport type { PowerSyncDatabase } from \"../query/executor\";\nimport type { DatabaseSchema, SyncStatus, SyncControl } from \"../core/types\";\nimport type { BackendStatus, AutoDetectionResult } from \"../adapters/auto-detector\";\nimport type { TableDataAdapter } from \"../adapters/types\";\n\n// =============================================================================\n// Status Types\n// =============================================================================\n\n/**\n * Status of the data layer initialization\n */\nexport interface DataLayerStatus {\n /** Whether the data layer is fully initialized */\n isInitialized: boolean;\n /** Current active backend */\n currentBackend: \"powersync\" | \"supabase\" | null;\n /** PowerSync connection status */\n powerSyncStatus: BackendStatus;\n /** Whether device is online */\n isOnline: boolean;\n /** Last auto-detection result */\n lastDetection: AutoDetectionResult | null;\n /** Initialization error if any */\n error: Error | null;\n /** Whether initial sync has completed (from PowerSync) */\n hasSynced: boolean;\n}\n\n// =============================================================================\n// Split Context Types (Performance Optimization)\n// =============================================================================\n\n/**\n * STABLE core context - values that don't change after initialization\n *\n * Use useDataLayerCore() to access these values in query/mutation hooks\n * to avoid re-renders when sync status changes.\n */\nexport interface DataLayerCoreContextValue {\n /** Adapter registry for getting table adapters */\n registry: AdapterRegistry;\n /** Get adapter for a specific table (defaults to 'read' operation) */\n getAdapter: (table: string, operation?: 'read' | 'write') => TableDataAdapter;\n /** PowerSync database instance (null when not available) */\n powerSync: PowerSyncDatabase | null;\n /** Supabase client (always available) */\n supabase: SupabaseClient;\n /** React Query client */\n queryClient: QueryClient;\n /** Database schema */\n schema: DatabaseSchema;\n /** Sync controls (for PowerSync, no-op for Supabase-only) - stable reference */\n syncControl: SyncControl;\n}\n\n/**\n * DYNAMIC status context - values that change during runtime\n *\n * Use useDataLayerStatus() for UI components that display sync status,\n * online indicator, etc. Components using this WILL re-render when status changes.\n */\nexport interface DataLayerStatusContextValue {\n /** Current status */\n status: DataLayerStatus;\n /** Sync status (for PowerSync, no-op for Supabase-only) */\n syncStatus: SyncStatus;\n}\n\n// =============================================================================\n// Combined Context Value Type (Backward Compatibility)\n// =============================================================================\n\n/**\n * Context value for the data layer (combines core and status)\n *\n * @deprecated Prefer using useDataLayerCore() or useDataLayerStatus() for better performance.\n * This combined interface is kept for backward compatibility.\n */\nexport interface DataLayerContextValue {\n /** Adapter registry for getting table adapters */\n registry: AdapterRegistry;\n\n /** Get adapter for a specific table (defaults to 'read' operation) */\n getAdapter: (table: string, operation?: 'read' | 'write') => TableDataAdapter;\n\n /** PowerSync database instance (null when not available) */\n powerSync: PowerSyncDatabase | null;\n\n /** Supabase client (always available) */\n supabase: SupabaseClient;\n\n /** React Query client */\n queryClient: QueryClient;\n\n /** Database schema */\n schema: DatabaseSchema;\n\n /** Current status */\n status: DataLayerStatus;\n\n /** Sync status (for PowerSync, no-op for Supabase-only) */\n syncStatus: SyncStatus;\n\n /** Sync controls (for PowerSync, no-op for Supabase-only) */\n syncControl: SyncControl;\n}\n\n// =============================================================================\n// Context Creation\n// =============================================================================\n\n/**\n * STABLE Core context - values that don't change after initialization\n *\n * Use useDataLayerCore() hook to access. Components consuming this context\n * will NOT re-render when sync status or network status changes.\n */\nexport const DataLayerCoreContext = createContext<DataLayerCoreContextValue | null>(null);\nDataLayerCoreContext.displayName = \"DataLayerCoreContext\";\n\n/**\n * DYNAMIC Status context - values that change during runtime\n *\n * Use useDataLayerStatus() hook to access. Components consuming this context\n * WILL re-render when sync status or network status changes.\n */\nexport const DataLayerStatusContext = createContext<DataLayerStatusContextValue | null>(null);\nDataLayerStatusContext.displayName = \"DataLayerStatusContext\";\n\n/**\n * Combined data layer context (backward compatibility)\n *\n * @deprecated Prefer using DataLayerCoreContext or DataLayerStatusContext for better performance.\n * Provides access to the V3 data layer throughout the React component tree.\n * Must be accessed via the useDataLayer hook or similar consumer.\n */\nexport const DataLayerContext = createContext<DataLayerContextValue | null>(null);\nDataLayerContext.displayName = \"DataLayerContext\";\n\n/**\n * Internal context to detect nested DataLayerProviders.\n *\n * This prevents the common mistake of wrapping an app with multiple DataLayerProviders,\n * which causes confusion about which provider's context is being used.\n *\n * When a DataLayerProvider mounts, it checks this context:\n * - If false/null: First provider, proceed normally\n * - If true: Nested provider detected, warn in dev mode\n */\nexport const DataLayerNestingContext = createContext<boolean>(false);\nDataLayerNestingContext.displayName = \"DataLayerNestingContext\";","/**\n * V3 Data Layer Hooks\n *\n * Provides access to the V3 data layer context for components.\n * This module provides three hooks for different use cases:\n *\n * - useDataLayerCore(): Stable values only (registry, adapters, clients)\n * Use in query/mutation hooks to avoid re-renders on status changes.\n *\n * - useDataLayerStatus(): Dynamic values only (status, syncStatus, syncControl)\n * Use for UI components that display sync status, online indicator, etc.\n *\n * - useDataLayer(): Combined access (backward compatible)\n * Use when you need both core and status values.\n */\n\nimport { useContext } from \"react\";\nimport { DataLayerContext, DataLayerCoreContext, DataLayerStatusContext, type DataLayerContextValue, type DataLayerCoreContextValue, type DataLayerStatusContextValue } from \"../providers/DataLayerContext\";\n\n// =============================================================================\n// PERFORMANCE-OPTIMIZED HOOKS (Recommended)\n// =============================================================================\n\n/**\n * Hook to access ONLY the stable core values (registry, adapters, clients)\n *\n * PERFORMANCE BENEFIT: Components using this hook will NOT re-render when\n * network status or sync status changes. Use this in query/mutation hooks.\n *\n * Provides access to:\n * - registry: Adapter registry for getting table adapters\n * - getAdapter: Function to get adapter for a specific table\n * - powerSync: PowerSync database instance (null when not available)\n * - supabase: Supabase client (always available)\n * - queryClient: React Query client\n * - schema: Database schema\n *\n * @throws Error if used outside of DataLayerProvider\n *\n * @example\n * const { getAdapter, supabase } = useDataLayerCore();\n * const adapter = getAdapter(\"Task\");\n * // This component won't re-render on sync status changes\n */\nexport function useDataLayerCore() {\n const context = useContext(DataLayerCoreContext);\n if (!context) {\n throw new Error(\"useDataLayerCore must be used within a DataLayerProvider. Make sure you have wrapped your app with <DataLayerProvider>.\");\n }\n return context;\n}\n\n/**\n * Hook to access ONLY the STABLE core context (optional version).\n * Returns null if DataLayerProvider is not present, rather than throwing.\n * Use this when you need graceful fallback behavior.\n *\n * @example\n * const dataLayerCore = useDataLayerCoreOptional();\n * if (dataLayerCore) {\n * // Use V3 adapter pattern\n * } else {\n * // Fall back to Supabase\n * }\n */\nexport function useDataLayerCoreOptional() {\n return useContext(DataLayerCoreContext);\n}\n\n/**\n * Hook to access ONLY the dynamic status values\n *\n * PERFORMANCE BENEFIT: Only components that actually need status information\n * will re-render when status changes. Use for UI components that display\n * sync status, online indicator, pending uploads count, etc.\n *\n * Provides access to:\n * - status: Current initialization and connection status\n * - syncStatus: Sync status for PowerSync\n * - syncControl: Sync controls for PowerSync\n *\n * @throws Error if used outside of DataLayerProvider\n *\n * @example\n * const { status, syncStatus } = useDataLayerStatus();\n *\n * return (\n * <StatusBar\n * isOnline={status.isOnline}\n * pendingUploads={syncStatus.pendingUploads}\n * />\n * );\n */\nexport function useDataLayerStatus() {\n const context = useContext(DataLayerStatusContext);\n if (!context) {\n throw new Error(\"useDataLayerStatus must be used within a DataLayerProvider. Make sure you have wrapped your app with <DataLayerProvider>.\");\n }\n return context;\n}\n\n// =============================================================================\n// BACKWARD COMPATIBLE HOOKS\n// =============================================================================\n\n/**\n * Hook to access the V3 data layer context (combined core + status)\n *\n * NOTE: Consider using useDataLayerCore() or useDataLayerStatus() instead\n * for better render performance. This hook re-renders on ALL status changes.\n *\n * Provides access to:\n * - registry: Adapter registry for getting table adapters\n * - getAdapter: Function to get adapter for a specific table\n * - powerSync: PowerSync database instance (null when not available)\n * - supabase: Supabase client (always available)\n * - queryClient: React Query client\n * - schema: Database schema\n * - status: Current initialization and connection status\n * - syncStatus: Sync status for PowerSync\n * - syncControl: Sync controls for PowerSync\n *\n * @throws Error if used outside of DataLayerProvider\n *\n * @example\n * const { getAdapter, status } = useDataLayer();\n *\n * if (status.isInitialized) {\n * const adapter = getAdapter(\"Task\");\n * // Use adapter...\n * }\n */\nexport function useDataLayer() {\n const context = useContext(DataLayerContext);\n if (!context) {\n throw new Error(\"useDataLayer must be used within a DataLayerProvider. Make sure you have wrapped your app with <DataLayerProvider>.\");\n }\n return context;\n}\n\n/**\n * Hook to safely access data layer context (returns null if not in provider)\n *\n * Use this when you need to check if the data layer is available\n * without throwing an error. Useful for conditional rendering or\n * components that may be rendered outside the provider context.\n *\n * @example\n * const dataLayer = useDataLayerOptional();\n *\n * if (dataLayer) {\n * // Safe to use data layer\n * } else {\n * // Render fallback UI\n * }\n */\nexport function useDataLayerOptional() {\n return useContext(DataLayerContext);\n}\nexport default useDataLayer;","/**\n * V3 useDbQuery Hook\n *\n * React hook for querying multiple records from a table.\n * Works identically whether PowerSync or Supabase is the backend.\n * Uses React Query for state management and caching.\n *\n * Types are automatically inferred from table names when you augment\n * the DatabaseTypes interface with your app's Database type.\n *\n * @example\n * // In your app's types/db.d.ts:\n * declare module \"@pol-studios/db\" {\n * interface DatabaseTypes {\n * database: import(\"@/database.types\").Database;\n * }\n * }\n *\n * // Then usage auto-infers types:\n * const { data } = useDbQuery(\"EquipmentFixtureUnit\", { ... });\n * // data is typed as Tables<\"EquipmentFixtureUnit\">[]\n */\n\nimport { useMemo, useEffect, useCallback, useRef } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useDataLayerCore } from \"./useDataLayer\";\nimport type { QueryOptions } from \"../core/types\";\nimport { devLog, devWarn } from \"../utils/dev-log\";\n\n// =============================================================================\n// Module Augmentation Interface\n// =============================================================================\n\n/**\n * Augment this interface in your app to enable automatic type inference.\n *\n * @example\n * // In types/db.d.ts\n * declare module \"@pol-studios/db\" {\n * interface DatabaseTypes {\n * database: import(\"@/database.types\").Database;\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface DatabaseTypes {}\n\n// =============================================================================\n// Database Type Helpers\n// =============================================================================\n\n/**\n * The configured Database type, or a generic fallback\n */\ntype ConfiguredDatabase = DatabaseTypes extends {\n database: infer DB;\n} ? DB : GenericSchema;\n\n/**\n * Generic schema structure for fallback\n */\ntype GenericSchema = {\n public: {\n Tables: Record<string, {\n Row: Record<string, unknown>;\n }>;\n Views: Record<string, {\n Row: Record<string, unknown>;\n }>;\n };\n [schema: string]: {\n Tables: Record<string, {\n Row: Record<string, unknown>;\n }>;\n Views?: Record<string, {\n Row: Record<string, unknown>;\n }>;\n };\n};\n\n/**\n * Default schema from Database (usually \"public\")\n */\ntype DefaultSchema = ConfiguredDatabase extends {\n public: infer S;\n} ? S : never;\n\n/**\n * Extract all valid table names from the default schema\n */\nexport type PublicTableNames = DefaultSchema extends {\n Tables: infer T;\n} ? keyof T & string : string;\n\n/**\n * Extract all valid schema names\n */\nexport type SchemaNames = keyof ConfiguredDatabase & string;\n\n/**\n * Extract table names for a specific schema\n */\nexport type SchemaTableNames<S extends string> = ConfiguredDatabase extends { [K in S]: {\n Tables: infer T;\n} } ? keyof T & string : string;\n\n/**\n * Build dot notation strings for all schema.table combinations\n */\ntype SchemaDotTable = { [S in SchemaNames]: S extends \"public\" ? never // Skip public schema for dot notation\n: `${S}.${SchemaTableNames<S>}` }[SchemaNames];\n\n/**\n * Table identifier - provides autocomplete for valid table names\n *\n * Supports:\n * - \"TableName\" - public schema tables\n * - \"schema.TableName\" - dot notation for other schemas\n * - { schema, table } - object format for other schemas\n */\nexport type TableIdentifier = PublicTableNames | SchemaDotTable | { [S in Exclude<SchemaNames, \"public\">]: {\n schema: S;\n table: SchemaTableNames<S>;\n} }[Exclude<SchemaNames, \"public\">];\n\n/**\n * Resolve row type from a table identifier\n *\n * Supports:\n * - \"TableName\" → public schema\n * - \"schema.TableName\" → specified schema (dot notation)\n * - { schema: \"schema\", table: \"TableName\" } → specified schema (object)\n */\nexport type ResolveRowType<T extends TableIdentifier> = T extends string ?\n// Check for dot notation first (e.g., \"core.Profile\")\nT extends `${infer Schema}.${infer Table}` ? ConfiguredDatabase extends { [K in Schema]: {\n Tables: { [K2 in Table]: {\n Row: infer R;\n } };\n} } ? R : Record<string, unknown> :\n// Plain string - look in public schema\nDefaultSchema extends {\n Tables: { [K in T]: {\n Row: infer R;\n } };\n} ? R : DefaultSchema extends {\n Views: { [K in T]: {\n Row: infer R;\n } };\n} ? R : Record<string, unknown> : T extends {\n schema: infer S;\n table: infer TN;\n} ?\n// Object with schema - look in specified schema\nS extends string ? TN extends string ? ConfiguredDatabase extends { [K in S]: {\n Tables: { [K2 in TN]: {\n Row: infer R;\n } };\n} } ? R : Record<string, unknown> : Record<string, unknown> : Record<string, unknown> : Record<string, unknown>;\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for useDbQuery hook\n */\nexport interface UseDbQueryOptions extends Omit<QueryOptions, \"enabled\"> {\n /** Whether the query is enabled (default: true) */\n enabled?: boolean;\n /**\n * React Query stale time in ms\n * Default depends on backend:\n * - PowerSync (offline): 0 - always refetch from SQLite (disk is fast)\n * - Supabase (online): 30000 - use normal caching\n */\n staleTime?: number;\n /** React Query gcTime (cache time) in ms (default: 300000 - 5 minutes) */\n gcTime?: number;\n /** Whether to refetch on window focus (default: true) */\n refetchOnWindowFocus?: boolean;\n /**\n * Whether to refetch on mount\n * Default depends on backend:\n * - PowerSync (offline): \"always\" - always query SQLite\n * - Supabase (online): true - refetch if stale\n */\n refetchOnMount?: boolean | \"always\";\n /** Whether to enable real-time subscriptions (if adapter supports) */\n realtime?: boolean;\n /** If true, returns single item instead of array (for compatibility with V2) */\n single?: boolean;\n}\n\n/**\n * Result from useDbQuery hook\n */\nexport interface UseDbQueryResult<T> {\n /** Query data */\n data: T[] | undefined;\n /** Whether query is loading (initial load) */\n isLoading: boolean;\n /** Whether query is in pending state */\n isPending: boolean;\n /** Whether query is currently fetching (including refetch) */\n isFetching: boolean;\n /** Whether query is currently refetching (alias for isFetching for V2 compatibility) */\n isRefetching: boolean;\n /** Whether query completed successfully */\n isSuccess: boolean;\n /** Whether query errored */\n isError: boolean;\n /** Query error if any */\n error: Error | null;\n /** Refetch the query */\n refetch: () => Promise<void>;\n /** Total count (if pagination is used) */\n count?: number;\n /** Whether data is stale */\n isStale: boolean;\n /** Timestamp of last data update */\n dataUpdatedAt: number | null;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Build a query key for React Query\n *\n * Creates a stable, unique key for caching based on table and query options.\n * Keys are namespaced with \"v3\" to avoid collisions with V2 queries.\n *\n * NOTE: Backend is intentionally NOT included in the key. The data is the same\n * regardless of whether it comes from Supabase or PowerSync - switching backends\n * should NOT invalidate the cache. This is critical for offline-first UX.\n */\nfunction buildQueryKey(table: string, options: UseDbQueryOptions): unknown[] {\n return [\"v3\", \"query\", table, options.select ?? \"*\", JSON.stringify(options.where ?? {}), JSON.stringify(options.orderBy ?? []), options.limit, options.offset];\n}\n\n/**\n * Serialize query options for dependency tracking\n */\nfunction serializeQueryOptions(options: UseDbQueryOptions): string {\n return JSON.stringify({\n select: options.select,\n where: options.where,\n orderBy: options.orderBy,\n limit: options.limit,\n offset: options.offset\n });\n}\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\n/**\n * Helper to resolve table name from TableIdentifier\n */\nfunction resolveTableName(table: TableIdentifier): string {\n if (typeof table === \"string\") {\n return table;\n }\n return `${table.schema}.${table.table}`;\n}\n\n/**\n * Hook for querying multiple records from a table\n *\n * This hook provides a unified interface for querying data that works\n * identically whether the backend is PowerSync (offline-first) or\n * Supabase (online-only). It uses React Query for caching and state management.\n *\n * Features:\n * - Automatic type inference from table names (when DatabaseTypes is augmented)\n * - Automatic backend selection based on DataLayerProvider configuration\n * - React Query integration for caching, deduplication, and background updates\n * - Optional real-time subscriptions (when adapter supports it)\n * - Pagination support with count\n *\n * @param table - Table name (string) or { schema, table } object\n * @param options - Query options (select, where, orderBy, limit, offset, etc.)\n * @returns Query result with data, loading states, error, and refetch function\n *\n * @example\n * // Basic query - types auto-inferred from table name\n * const { data } = useDbQuery(\"EquipmentFixtureUnit\");\n * // data is typed as Tables<\"EquipmentFixtureUnit\">[]\n *\n * @example\n * // Query from non-public schema\n * const { data } = useDbQuery({ schema: \"core\", table: \"Profile\" });\n * // data is typed as Tables<{ schema: \"core\" }, \"Profile\">[]\n *\n * @example\n * // Query with filters and sorting\n * const { data } = useDbQuery(\"Task\", {\n * select: \"*, Project(*)\",\n * where: { status: \"active\" },\n * orderBy: [{ field: \"createdAt\", direction: \"desc\" }],\n * limit: 10,\n * });\n */\n/**\n * Main hook signature with auto-inferred types from table identifiers\n */\nexport function useDbQuery<T extends TableIdentifier>(table: T, options?: UseDbQueryOptions): UseDbQueryResult<ResolveRowType<T>>;\n\n/**\n * Overload for explicit type parameter when table name is a string literal\n */\nexport function useDbQuery<T>(table: string, options?: UseDbQueryOptions): UseDbQueryResult<T>;\n\n// Implementation signature - uses any to satisfy both overloads\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useDbQuery<T = any>(table: TableIdentifier | string, options: UseDbQueryOptions = {}): UseDbQueryResult<T> {\n const tableName = typeof table === \"string\" ? table : resolveTableName(table as TableIdentifier);\n const {\n registry,\n queryClient,\n powerSync\n } = useDataLayerCore();\n\n // Determine if using PowerSync (offline/SQLite) or Supabase (online)\n const isPowerSync = powerSync !== null;\n\n // Backend-aware defaults:\n // - PowerSync: staleTime=0, refetchOnMount=\"always\" (SQLite is fast, always query disk)\n // - Supabase: staleTime=30000, refetchOnMount=true (use normal React Query caching)\n // - realtime: PowerSync=true (use watch() for live updates), Supabase=false (no streaming)\n const {\n enabled = true,\n staleTime = isPowerSync ? 0 : 30000,\n gcTime = 300000,\n // 5 minutes - keep in memory for instant display while refetching\n refetchOnWindowFocus = true,\n refetchOnMount = isPowerSync ? \"always\" : true,\n realtime = isPowerSync,\n // Enable real-time subscriptions by default for PowerSync\n ...queryOptions\n } = options;\n\n // Get adapter for this table\n // No isInitialized check needed - if we get here, core context exists = initialized\n const adapter = useMemo(() => {\n try {\n return registry.getAdapter(tableName);\n } catch {\n return null;\n }\n }, [registry, tableName]);\n\n // Serialize options into a stable memoized value BEFORE using in other dependencies\n const serializedOptions = useMemo(() => serializeQueryOptions(options), [options.select, options.where, options.orderBy, options.limit, options.offset]);\n\n // Build query key - memoized to prevent unnecessary re-renders\n // Backend is NOT included - cache persists across backend switches for offline-first UX\n const queryKey = useMemo(() => buildQueryKey(tableName, options), [tableName, serializedOptions]);\n\n // Memoize query options to prevent re-creating on every render\n const memoizedQueryOptions = useMemo(() => ({\n select: queryOptions.select,\n where: queryOptions.where,\n orderBy: queryOptions.orderBy,\n limit: queryOptions.limit,\n offset: queryOptions.offset\n }), [serializedOptions]);\n\n // Track the adapter name that was actually used for the most recent query\n // This is used for accurate logging since the memoized adapter may be stale\n const lastUsedAdapterNameRef = useRef<string>(\"unknown\");\n\n // Query function - resolve adapter lazily at query time to ensure we always\n // have the latest adapter instance (the memoized adapter may be stale)\n const queryFn = useCallback(async () => {\n // Use currentAdapter directly - registry.getAdapter() throws if unavailable\n const currentAdapter = registry.getAdapter(tableName);\n\n // Track which adapter was actually used for accurate logging\n lastUsedAdapterNameRef.current = currentAdapter.name;\n const result = await currentAdapter.query(tableName, memoizedQueryOptions);\n return result;\n }, [registry, tableName, memoizedQueryOptions]);\n\n // Execute query with React Query\n // Backend-aware caching strategy:\n // - PowerSync: SQLite is source of truth, always refetch from disk (it's fast)\n // - Supabase: Use normal React Query caching to avoid unnecessary network requests\n const query = useQuery({\n queryKey,\n queryFn,\n enabled: enabled && adapter !== null,\n staleTime,\n gcTime,\n refetchOnWindowFocus,\n refetchOnMount\n });\n\n // Create debounced invalidation function for subscriptions\n const invalidateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const debouncedInvalidate = useCallback(() => {\n if (invalidateTimeoutRef.current) {\n clearTimeout(invalidateTimeoutRef.current);\n }\n invalidateTimeoutRef.current = setTimeout(() => {\n queryClient.invalidateQueries({\n queryKey\n });\n }, 100);\n }, [queryClient, queryKey]);\n\n // Clean up timeout on unmount\n useEffect(() => {\n return () => {\n if (invalidateTimeoutRef.current) {\n clearTimeout(invalidateTimeoutRef.current);\n }\n };\n }, []);\n\n // Set up real-time subscription if enabled\n useEffect(() => {\n // Resolve adapter lazily to get current backend\n let currentAdapter_0;\n try {\n currentAdapter_0 = registry.getAdapter(tableName);\n } catch {\n return; // Adapter not available yet\n }\n if (!realtime || !currentAdapter_0?.subscribe) {\n return;\n }\n\n // Only skip first callback for PowerSync adapter (which fires immediately with current data)\n // SupabaseAdapter's subscribe only fires on actual database changes\n // Use currentAdapter.name for the isFirstCallback check (survives minification)\n const isPowerSyncAdapter = currentAdapter_0.name === \"powersync\";\n let isFirstCallback = isPowerSyncAdapter;\n const unsubscribe = currentAdapter_0.subscribe(tableName, memoizedQueryOptions, data => {\n // Skip the first callback since initial query handles it\n if (isFirstCallback) {\n isFirstCallback = false;\n return;\n }\n\n // Check if query has relations (contains parentheses like \"Table(*)\")\n const hasRelations = memoizedQueryOptions.select?.includes(\"(\");\n if (hasRelations) {\n // Has relations - use debounced invalidation to prevent rapid successive invalidations\n debouncedInvalidate();\n } else {\n // No relations - safe to directly update cache with flat data\n queryClient.setQueryData(queryKey, {\n data,\n count: data.length\n });\n }\n });\n return () => {\n unsubscribe?.();\n };\n }, [realtime, registry, tableName, memoizedQueryOptions, queryClient, queryKey, debouncedInvalidate]);\n\n // Dev logging for debugging\n // Uses lastUsedAdapterNameRef to log the adapter that was ACTUALLY used for the query,\n // not the memoized adapter from render time (which may be stale due to auto-detection)\n useEffect(() => {\n const adapterName = lastUsedAdapterNameRef.current;\n\n // Log errors\n if (query.isError && query.error) {\n devWarn(\"useDbQuery\", `${tableName} via ${adapterName}: Error - ${query.error.message}`);\n }\n\n // Log empty results (only after successful fetch, not during loading)\n if (query.isSuccess && query.data?.data?.length === 0) {\n devLog(\"useDbQuery\", `${tableName} via ${adapterName}: 0 results`);\n }\n }, [query.isError, query.error, query.isSuccess, query.data, tableName]);\n\n // Build refetch function\n const refetch = useCallback(async () => {\n await query.refetch();\n }, [query]);\n return {\n data: query.data?.data as T[] | undefined,\n isLoading: query.isLoading,\n isPending: query.isPending,\n isFetching: query.isFetching,\n isRefetching: query.isFetching,\n // Alias for V2 compatibility\n isSuccess: query.isSuccess,\n isError: query.isError,\n error: query.error as Error | null,\n refetch,\n count: query.data?.count,\n isStale: query.isStale,\n dataUpdatedAt: query.dataUpdatedAt ?? null\n };\n}\nexport default useDbQuery;","/**\n * Development-only logging utility for V3 hooks\n *\n * Logs are only output when __DEV__ is true (development builds).\n * In production builds, these calls are no-ops.\n */\n\ndeclare const __DEV__: boolean;\n\n/**\n * Log a message with a prefix, only in development\n *\n * @param prefix - Hook or component name (e.g., \"useDbQuery\")\n * @param message - Message to log\n *\n * @example\n * devLog(\"useDbQuery\", \"EquipmentUnit via PowerSync: 0 results\");\n * // Output: [useDbQuery] EquipmentUnit via PowerSync: 0 results\n */\nexport function devLog(prefix: string, message: string): void {\n if (typeof __DEV__ !== \"undefined\" && __DEV__) {\n console.log(`[${prefix}] ${message}`);\n }\n}\n\n/**\n * Log a warning with a prefix, only in development\n */\nexport function devWarn(prefix: string, message: string): void {\n if (typeof __DEV__ !== \"undefined\" && __DEV__) {\n console.warn(`[${prefix}] ${message}`);\n }\n}\n\n/**\n * Log an error with a prefix, only in development\n */\nexport function devError(prefix: string, message: string, error?: unknown): void {\n if (typeof __DEV__ !== \"undefined\" && __DEV__) {\n if (error) {\n console.error(`[${prefix}] ${message}`, error);\n } else {\n console.error(`[${prefix}] ${message}`);\n }\n }\n}","/**\n * V3 useDbQueryById Hook\n *\n * React hook for querying a single record by ID from a table.\n * Works identically whether PowerSync or Supabase is the backend.\n * Uses React Query for state management and caching.\n */\n\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useDataLayerCore } from \"./useDataLayer\";\nimport type { WhereClause } from \"../core/types\";\nimport { devLog, devWarn } from \"../utils/dev-log\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for useDbQueryById hook\n */\nexport interface UseDbQueryByIdOptions {\n /** Columns to select (Supabase-style select string) */\n select?: string;\n /** Whether the query is enabled (default: true if id is provided) */\n enabled?: boolean;\n /** React Query stale time in ms (default: 30000) */\n staleTime?: number;\n}\n\n/**\n * Result from useDbQueryById hook\n */\nexport interface UseDbQueryByIdResult<T> {\n /** Query data (undefined while loading, null if not found) */\n data: T | null | undefined;\n /** Whether query is loading (initial load) */\n isLoading: boolean;\n /** Whether query is in pending state */\n isPending: boolean;\n /** Whether query is currently fetching (including refetch) */\n isFetching: boolean;\n /** Query error if any */\n error: Error | null;\n /** Refetch the query */\n refetch: () => Promise<void>;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Build a query key for React Query\n *\n * Creates a stable, unique key for caching based on table, ID, and select.\n * Keys are namespaced with \"v3\" to avoid collisions with V2 queries.\n */\nfunction buildQueryKey(table: string, id: string | number | null | undefined, select?: string): unknown[] {\n return [\"v3\", \"queryById\", table, id, select ?? \"*\"];\n}\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\n/**\n * Hook for querying a single record by ID\n *\n * This hook provides a unified interface for fetching a single record that works\n * identically whether the backend is PowerSync (offline-first) or\n * Supabase (online-only). It uses React Query for caching and state management.\n *\n * Features:\n * - Automatic backend selection based on DataLayerProvider configuration\n * - React Query integration for caching, deduplication, and background updates\n * - Automatic disabling when ID is null/undefined\n * - Fallback to query with where clause if adapter doesn't support queryById\n * - Type-safe with generic type parameter\n *\n * @param table - The table name to query\n * @param id - The record ID (query is disabled if null/undefined)\n * @param options - Query options (select, enabled, staleTime)\n * @returns Query result with data, loading states, error, and refetch function\n *\n * @example\n * // Basic query by ID\n * const { data, isLoading, error } = useDbQueryById<Task>(\"Task\", taskId);\n *\n * @example\n * // Query with relations\n * const { data, isLoading, error } = useDbQueryById<Task>(\"Task\", taskId, {\n * select: \"*, Project(*), AssignedUser:User(*)\",\n * });\n *\n * @example\n * // Conditional query based on other state\n * const { data } = useDbQueryById<Project>(\"Project\", selectedProjectId, {\n * enabled: hasPermission && !!selectedProjectId,\n * });\n *\n * @example\n * // With custom stale time\n * const { data } = useDbQueryById<User>(\"User\", userId, {\n * staleTime: 60000, // 1 minute\n * });\n */\nexport function useDbQueryById<T = Record<string, unknown>>(table: string, id: string | number | null | undefined, options: UseDbQueryByIdOptions = {}): UseDbQueryByIdResult<T> {\n const {\n registry\n } = useDataLayerCore();\n const {\n select,\n enabled = id != null,\n staleTime = 30000\n } = options;\n\n // Get adapter for this table\n // No isInitialized check needed - if we get here, core context exists = initialized\n const adapter = useMemo(() => {\n try {\n return registry.getAdapter(table);\n } catch (error) {\n devWarn(\"useDbQueryById\", `Failed to get adapter for ${table}: ${(error as Error).message}`);\n return null;\n }\n }, [registry, table]);\n\n // Build query key - memoized to prevent unnecessary re-renders\n const queryKey = useMemo(() => buildQueryKey(table, id, select), [table, id, select]);\n\n // Track the adapter name that was actually used for the most recent query\n // This is used for accurate logging since the memoized adapter may be stale\n const lastUsedAdapterNameRef = useRef<string>(\"unknown\");\n\n // Query function - resolve adapter lazily at query time to ensure we always\n // have the latest adapter instance (the memoized adapter may be stale)\n const queryFn = useCallback(async (): Promise<T | null> => {\n if (id == null) {\n return null;\n }\n\n // Use currentAdapter directly - registry.getAdapter() throws if unavailable\n const currentAdapter = registry.getAdapter(table);\n\n // Track which adapter was actually used for accurate logging\n lastUsedAdapterNameRef.current = currentAdapter.name;\n\n // Use queryById if available, otherwise fall back to query with where\n if (currentAdapter.queryById) {\n return currentAdapter.queryById<T>(table, String(id), {\n select\n });\n }\n\n // Fallback: use query with where clause\n const result = await currentAdapter.query<T>(table, {\n select,\n where: {\n id\n } as WhereClause,\n limit: 1\n });\n return result.data[0] ?? null;\n }, [registry, table, id, select]);\n\n // Execute query with React Query\n const query = useQuery({\n queryKey,\n queryFn,\n enabled: enabled && adapter !== null && id != null,\n staleTime\n });\n\n // Dev logging for debugging\n // Uses lastUsedAdapterNameRef to log the adapter that was ACTUALLY used for the query,\n // not the memoized adapter from render time (which may be stale due to auto-detection)\n useEffect(() => {\n const adapterName = lastUsedAdapterNameRef.current;\n\n // Log errors\n if (query.isError && query.error) {\n devWarn(\"useDbQueryById\", `${table}(${id}) via ${adapterName}: Error - ${query.error.message}`);\n }\n\n // Log not found (only after successful fetch, not during loading)\n if (query.isSuccess && query.data === null) {\n devLog(\"useDbQueryById\", `${table}(${id}) via ${adapterName}: not found`);\n }\n }, [query.isError, query.error, query.isSuccess, query.data, table, id]);\n\n // Build refetch function\n const refetch = useCallback(async () => {\n await query.refetch();\n }, [query]);\n return {\n data: query.data,\n isLoading: query.isLoading,\n isPending: query.isPending,\n isFetching: query.isFetching,\n error: query.error as Error | null,\n refetch\n };\n}\nexport default useDbQueryById;"],"mappings":"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","names":["useCallback","useEffect","useMemo","useRef","useQuery","buildQueryKey","useMemo","useRef","useCallback","useQuery","useEffect"]}
|
|
File without changes
|
|
File without changes
|