@pol-studios/db
v1.0.10
Published
Database layer for React applications with Supabase and PowerSync support
Downloads
1,313
Maintainers
Readme
@pol-studios/db
Database layer for React applications with Supabase and PowerSync support
A comprehensive database abstraction layer supporting both Supabase (V2 hooks) and PowerSync (V3 hooks) for offline-first applications. Provides React Query integration, realtime subscriptions, mutation hooks, and storage utilities.
Installation
pnpm add @pol-studios/dbPeer Dependencies
# Required
pnpm add react @supabase/supabase-js @tanstack/react-query @pol-studios/db/auth @pol-studios/hooks
# Optional (for React Native / offline-first)
pnpm add @powersync/react-native @react-native-community/netinfo react-nativeQuick Start
import { SupabaseProvider, useDbQuery, useDbInsert, useDbUpdate, useDbDelete } from "@pol-studios/db";
// Wrap your app with the provider
function App() {
return (
<SupabaseProvider url={SUPABASE_URL} anonKey={SUPABASE_ANON_KEY}>
<QueryClientProvider client={queryClient}>
<MyApp />
</QueryClientProvider>
</SupabaseProvider>
);
}
// Query data
function ProjectList() {
const { data, isLoading } = useDbQuery("projects", {
select: "*",
order: { column: "created_at", ascending: false },
});
if (isLoading) return <Loading />;
return <List items={data} />;
}
// Mutations
function CreateProject() {
const insert = useDbInsert("projects");
const update = useDbUpdate("projects");
const remove = useDbDelete("projects");
const handleCreate = () => {
insert.mutate({ name: "New Project", status: "active" });
};
const handleUpdate = (id, data) => {
update.mutate({ id, ...data });
};
const handleDelete = (id) => {
remove.mutate({ id });
};
}Subpath Exports
| Path | Description |
|------|-------------|
| @pol-studios/db | All exports combined |
| @pol-studios/db/client | Supabase client utilities |
| @pol-studios/db/core | Core types and configuration |
| @pol-studios/db/query | Query system utilities |
| @pol-studios/db/mutation | Mutation hooks (batch operations) |
| @pol-studios/db/realtime | Realtime subscription utilities |
| @pol-studios/db/parser | Query parser utilities |
| @pol-studios/db/hooks | V3 hooks (PowerSync) |
| @pol-studios/db/types | TypeScript type definitions |
| @pol-studios/db/gen | Generated entity configurations |
API Reference
V2 Hooks (Supabase-based)
import {
// Query hooks
useDbQuery,
useDbInfiniteQuery,
useDbAdvanceQuery,
useDbPartialQuery,
useDbRealtimeQuery,
// Mutation hooks
useDbInsert,
useDbUpdate,
useDbDelete,
useDbUpsert,
useDbMultiUpsert,
useDbMultiDelete,
// Batch mutations
useBatchUpsert,
useBatchDelete,
} from "@pol-studios/db";
// Basic query
const { data } = useDbQuery("projects", {
select: "id, name, status",
filter: { status: "active" },
order: { column: "name" },
limit: 10,
});
// Infinite scroll query
const { data, fetchNextPage, hasNextPage } = useDbInfiniteQuery("projects", {
select: "*",
pageSize: 20,
});
// Advanced query with joins
const { data } = useDbAdvanceQuery("projects", {
select: "*, tasks(*), owner:profiles(*)",
filter: { archived: false },
});
// Realtime query (auto-updates on changes)
const { data } = useDbRealtimeQuery("projects", {
select: "*",
filter: { team_id: teamId },
});
// Insert with automatic cache invalidation
const { mutate: insert } = useDbInsert("projects");
insert({ name: "New Project" });
// Update
const { mutate: update } = useDbUpdate("projects");
update({ id: projectId, name: "Updated Name" });
// Upsert
const { mutate: upsert } = useDbUpsert("projects");
upsert({ id: projectId, name: "Name" }); // Insert or update
// Batch operations
const { mutate: batchUpsert } = useBatchUpsert("projects");
batchUpsert(projectsArray);V3 Hooks (PowerSync / Offline-first)
import {
// V3 Query hooks
useDbQueryV3,
useDbQueryById,
useDbInfiniteQueryV3,
useDbCountV3,
useAdvanceQuery,
// V3 Mutation hooks
useDbInsertV3,
useDbUpdateV3,
useDbDeleteV3,
useDbUpsertV3,
// Sync utilities
useSyncStatus,
useSyncControl,
useOnlineStatus,
useDataLayer,
} from "@pol-studios/db";
// V3 queries work offline with PowerSync
const { data } = useDbQueryV3("projects", {
where: { status: "active" },
orderBy: { created_at: "desc" },
});
// Get single item by ID
const { data: project } = useDbQueryById("projects", projectId);
// Count query
const { data: count } = useDbCountV3("projects", {
where: { status: "active" },
});
// Sync status
const { isSyncing, lastSyncTime, pendingChanges } = useSyncStatus();
// Control sync
const { startSync, stopSync, forceSync } = useSyncControl();
// Online status
const isOnline = useOnlineStatus();Supabase Client
import {
useSupabase,
SupabaseProvider,
createNewSupabaseClient,
typedSupabase,
onSupabaseInitialized,
setDefaultOptions,
} from "@pol-studios/db";
// Get typed Supabase client
const supabase = useSupabase();
// Direct client creation
const client = createNewSupabaseClient(url, key);
// Typed client for specific database schema
const typed = typedSupabase(client);
// Initialize callback
onSupabaseInitialized((client) => {
console.log("Supabase ready");
});Realtime Subscriptions
import { useDbRealtime, useLiveChangesIndicator, useLiveChangeTracking } from "@pol-studios/db";
// Subscribe to table changes
useDbRealtime("projects", {
event: "INSERT",
filter: `team_id=eq.${teamId}`,
callback: (payload) => {
console.log("New project:", payload.new);
},
});
// Track live changes indicator
const { hasChanges, changeCount } = useLiveChangesIndicator("projects");
// Track specific changes
const { changes, clearChanges } = useLiveChangeTracking("projects", projectId);Storage
import {
useStorageUrl,
useStoragePath,
useStorageUpload,
useStorageUploadWithEntity,
useDbUpload,
} from "@pol-studios/db";
// Get public URL for storage path
const url = useStorageUrl("avatars", "user-123.png");
// Generate storage path
const path = useStoragePath("documents", { entityId, fileName });
// Upload file
const { upload, isUploading, progress } = useStorageUpload("documents");
await upload(file);
// Upload with entity association
const { upload } = useStorageUploadWithEntity("attachments", {
entityType: "project",
entityId: projectId,
});Utility Hooks
import {
useAI,
useReceiptAI,
useServerAvailability,
useSearchQuery,
useAutosaveState,
useBackgroundTask,
useToastError,
useLatestOperationLog,
useConsent,
useAccountDeletion,
useUserStatus,
useDataExport,
} from "@pol-studios/db";
// AI integration
const { generate, isLoading } = useAI();
// Receipt AI processing
const { processReceipt } = useReceiptAI();
// Server availability check
const isAvailable = useServerAvailability();
// Search with debounce
const { results, search } = useSearchQuery("projects", { debounce: 300 });
// Autosave state
const [value, setValue, { isDirty, isSaving }] = useAutosaveState(initial, saveFn);
// Background task
const { run, isRunning, progress } = useBackgroundTask(asyncFn);
// Error toast integration
const showError = useToastError();Edge Functions
import { useSupabaseFunction } from "@pol-studios/db";
// Call Supabase Edge Functions
const { invoke, isLoading, data, error } = useSupabaseFunction("process-data");
await invoke({ input: "value" });Data Layer Provider (V3)
import { DataLayerProvider, useDataLayer } from "@pol-studios/db";
// Wrap app for offline-first support
<DataLayerProvider config={dataLayerConfig}>
<App />
</DataLayerProvider>
// Access data layer
const { adapter, isReady, syncStatus } = useDataLayer();TypeScript Types
import type {
// Database types
DatabaseTypes,
TableNames,
PublicTableNames,
SchemaNames,
SchemaTableNames,
// Query types
QueryOptions,
QueryResult,
QuerySingleResult,
WhereClause,
WhereOperators,
OrderBy,
// Mutation types
MutationResult,
MutationHookResult,
DeleteMutationResult,
ExtractRow,
ExtractInsert,
ExtractUpdate,
// V3 types
DataLayerConfig,
DataAdapter,
SyncStatus,
SyncMode,
SyncScope,
SyncControl,
ConnectionConfig,
// Strategy types
SupabaseStrategy,
PowerSyncStrategy,
HybridStrategy,
CachedStrategy,
AutoStrategy,
TableStrategy,
// Schema types
DatabaseSchema,
TableSchema,
ColumnInfo,
ColumnType,
RelationshipInfo,
RelationshipType,
// Supabase types
TypedSupabaseClient,
SupabaseDatabaseTypes,
UserSessionId,
} from "@pol-studios/db";Network Utilities
import {
getOnlineStatus,
getOnlineStatusSync,
initializeNetworkMonitoring,
subscribeToNetworkChanges,
isReactNative,
} from "@pol-studios/db";
// Check online status
const isOnline = await getOnlineStatus();
const isOnlineSync = getOnlineStatusSync();
// Initialize network monitoring
initializeNetworkMonitoring();
// Subscribe to network changes
const unsubscribe = subscribeToNetworkChanges((isOnline) => {
console.log("Network:", isOnline ? "online" : "offline");
});Related Packages
- @pol-studios/db/auth - Authentication (required peer dependency)
- @pol-studios/hooks - React hooks (required peer dependency)
- @pol-studios/utils - Utility functions
- @pol-studios/features - Feature modules (uses db)
License
UNLICENSED
