@tanstack/db
Version:
A reactive client store for building super fast apps on sync
192 lines (191 loc) • 6.94 kB
text/typescript
import { BaseCollectionConfig, CollectionConfig, PendingMutation, UtilsRecord } from './types.cjs';
import { StandardSchemaV1 } from '@standard-schema/spec';
export declare class DatabaseRequiredError extends Error {
constructor();
}
/**
* Thrown when the specified object store doesn't exist in the database
*/
export declare class ObjectStoreNotFoundError extends Error {
constructor(storeName: string, databaseName: string, availableStores: ReadonlyArray<string>);
}
/**
* Thrown when the name (object store) configuration is missing
*/
export declare class NameRequiredError extends Error {
constructor();
}
/**
* Thrown when the getKey function is missing
*/
export declare class GetKeyRequiredError extends Error {
constructor();
}
export interface CreateIndexedDBOptions {
/** Database name */
name: string;
/** Schema version (increment when adding stores) */
version: number;
/** Object store names to create */
stores: ReadonlyArray<string>;
/** Custom IDBFactory for testing/mocking */
idbFactory?: IDBFactory;
/** Reports a native blocker without settling the open request. */
onBlocked?: (event: IDBVersionChangeEvent) => void;
}
/**
* A shared IndexedDB database instance.
* Create with createIndexedDB() and pass to collections.
*/
export interface IndexedDBInstance {
/** The underlying IDBDatabase connection */
readonly db: IDBDatabase;
/** Database name */
readonly name: string;
/** Database version */
readonly version: number;
/** Requested object store names (frozen); omissions do not remove stores */
readonly stores: ReadonlyArray<string>;
/** IDBFactory used to create this database (for testing) */
readonly idbFactory?: IDBFactory;
/** Close the connection and mark its managed Collections as errored. */
close: () => void;
}
type InferSchemaOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> extends object ? StandardSchemaV1.InferOutput<T> : Record<string, unknown> : Record<string, unknown>;
/**
* Schema input type inference helper
*/
type InferSchemaInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> extends object ? StandardSchemaV1.InferInput<T> : Record<string, unknown> : Record<string, unknown>;
/**
* Configuration options for creating an IndexedDB Collection
*/
export interface IndexedDBCollectionConfig<T extends object = object, TSchema extends StandardSchemaV1 = never, TKey extends string | number = string | number> extends BaseCollectionConfig<T, TKey, TSchema> {
/**
* IndexedDB instance from createIndexedDB()
* REQUIRED - must create database before collections
*/
db: IndexedDBInstance;
/**
* Name of the object store within the database
* Must exist in the underlying database
*/
name: string;
}
/**
* Database information returned by getDatabaseInfo()
*/
export interface DatabaseInfo {
name: string;
version: number;
objectStores: Array<string>;
/** Origin-wide storage usage in bytes, including other databases and caches. */
estimatedSize?: number;
}
/**
* Utility functions exposed on collection.utils
*/
export interface IndexedDBCollectionUtils<TItem extends object = Record<string, unknown>, TInsertInput extends object = TItem> extends UtilsRecord {
/**
* Removes all data from the object store
* Does NOT delete the database itself
*/
clearObjectStore: () => Promise<void>;
/**
* Returns database information for debugging
*/
getDatabaseInfo: () => Promise<DatabaseInfo>;
/**
* Accepts mutations from a manual transaction and persists to IndexedDB
*/
acceptMutations: (transaction: {
mutations: Array<PendingMutation>;
}) => Promise<void>;
/**
* Exports all data from the object store as an array
* Useful for backup/debugging
*/
exportData: () => Promise<Array<TItem>>;
/**
* Validates input rows and atomically replaces the object store.
* Failure preserves the previous rows and versions.
*/
importData: (items: Array<TInsertInput>) => Promise<void>;
}
/**
* Creates or opens an IndexedDB database with the specified stores.
* Call this once at app startup, then pass the instance to collections.
* The connection closes on versionchange so another context can upgrade or
* delete the database. Affected Collections enter error and retain their rows.
* Recreate affected Collections with a new instance before
* further persistence.
*
* All stores are created in a single upgrade transaction, avoiding
* version race conditions when multiple collections share a database.
*
* @example
* ```typescript
* const db = await createIndexedDB({
* name: 'myApp',
* version: 1,
* stores: ['todos', 'users', 'settings'],
* })
*
* const todosCollection = createCollection(
* indexedDBCollectionOptions({
* db,
* name: 'todos',
* getKey: (item: { id: string }) => item.id,
* })
* )
* ```
*/
export declare function createIndexedDB(options: CreateIndexedDBOptions): Promise<IndexedDBInstance>;
/**
* Creates IndexedDB collection options for use with a standard Collection.
* This provides persistent local storage with cross-tab synchronization.
*
* IMPORTANT: You must first create the database with createIndexedDB() and
* pass the instance to this function. This ensures all stores are created
* upfront in a single upgrade transaction.
*
* @example
* // Step 1: Create database with all stores
* const db = await createIndexedDB({
* name: 'myApp',
* version: 1,
* stores: ['todos', 'users'],
* })
*
* // Step 2: Create collections using the shared database
* const todosCollection = createCollection(
* indexedDBCollectionOptions({
* db,
* name: 'todos',
* schema: todoSchema,
* getKey: (item: { id: string }) => item.id,
* })
* )
*
* @example
* // Without schema (explicit type)
* const todosCollection = createCollection(
* indexedDBCollectionOptions<Todo>({
* db,
* name: 'todos',
* getKey: (item: { id: string }) => item.id,
* })
* )
*/
export declare function indexedDBCollectionOptions<T extends StandardSchemaV1, TKey extends string | number = string | number>(config: IndexedDBCollectionConfig<InferSchemaOutput<T>, T, TKey> & {
schema: T;
}): CollectionConfig<InferSchemaOutput<T>, TKey, T, IndexedDBCollectionUtils<InferSchemaOutput<T>, InferSchemaInput<T>>> & {
schema: T;
utils: IndexedDBCollectionUtils<InferSchemaOutput<T>, InferSchemaInput<T>>;
};
export declare function indexedDBCollectionOptions<T extends object, TKey extends string | number = string | number>(config: IndexedDBCollectionConfig<T, never, TKey> & {
schema?: never;
}): CollectionConfig<T, TKey, never, IndexedDBCollectionUtils<T>> & {
schema?: never;
utils: IndexedDBCollectionUtils<T>;
};
export {};