UNPKG

@tanstack/db-collections

Version:

A collection for (aspirationally) every way of loading your data

175 lines (174 loc) 7.18 kB
import { QueryClient, QueryFunctionContext, QueryKey, QueryObserverOptions } from '@tanstack/query-core'; import { CollectionConfig, DeleteMutationFn, InsertMutationFn, UpdateMutationFn, UtilsRecord } from '@tanstack/db'; export interface QueryCollectionConfig<TItem extends object, TError = unknown, TQueryKey extends QueryKey = QueryKey> { queryKey: TQueryKey; queryFn: (context: QueryFunctionContext<TQueryKey>) => Promise<Array<TItem>>; queryClient: QueryClient; enabled?: boolean; refetchInterval?: QueryObserverOptions<Array<TItem>, TError, Array<TItem>, Array<TItem>, TQueryKey>[`refetchInterval`]; retry?: QueryObserverOptions<Array<TItem>, TError, Array<TItem>, Array<TItem>, TQueryKey>[`retry`]; retryDelay?: QueryObserverOptions<Array<TItem>, TError, Array<TItem>, Array<TItem>, TQueryKey>[`retryDelay`]; staleTime?: QueryObserverOptions<Array<TItem>, TError, Array<TItem>, Array<TItem>, TQueryKey>[`staleTime`]; id?: string; getKey: CollectionConfig<TItem>[`getKey`]; schema?: CollectionConfig<TItem>[`schema`]; sync?: CollectionConfig<TItem>[`sync`]; startSync?: CollectionConfig<TItem>[`startSync`]; /** * Optional asynchronous handler function called before an insert operation * @param params Object containing transaction and collection information * @returns Promise resolving to void or { refetch?: boolean } to control refetching * @example * // Basic query collection insert handler * onInsert: async ({ transaction }) => { * const newItem = transaction.mutations[0].modified * await api.createTodo(newItem) * // Automatically refetches query after insert * } * * @example * // Insert handler with refetch control * onInsert: async ({ transaction }) => { * const newItem = transaction.mutations[0].modified * await api.createTodo(newItem) * return { refetch: false } // Skip automatic refetch * } * * @example * // Insert handler with multiple items * onInsert: async ({ transaction }) => { * const items = transaction.mutations.map(m => m.modified) * await api.createTodos(items) * // Will refetch query to get updated data * } * * @example * // Insert handler with error handling * onInsert: async ({ transaction }) => { * try { * const newItem = transaction.mutations[0].modified * await api.createTodo(newItem) * } catch (error) { * console.error('Insert failed:', error) * throw error // Transaction will rollback optimistic changes * } * } */ onInsert?: InsertMutationFn<TItem>; /** * Optional asynchronous handler function called before an update operation * @param params Object containing transaction and collection information * @returns Promise resolving to void or { refetch?: boolean } to control refetching * @example * // Basic query collection update handler * onUpdate: async ({ transaction }) => { * const mutation = transaction.mutations[0] * await api.updateTodo(mutation.original.id, mutation.changes) * // Automatically refetches query after update * } * * @example * // Update handler with multiple items * onUpdate: async ({ transaction }) => { * const updates = transaction.mutations.map(m => ({ * id: m.key, * changes: m.changes * })) * await api.updateTodos(updates) * // Will refetch query to get updated data * } * * @example * // Update handler with manual refetch * onUpdate: async ({ transaction, collection }) => { * const mutation = transaction.mutations[0] * await api.updateTodo(mutation.original.id, mutation.changes) * * // Manually trigger refetch * await collection.utils.refetch() * * return { refetch: false } // Skip automatic refetch * } * * @example * // Update handler with related collection refetch * onUpdate: async ({ transaction, collection }) => { * const mutation = transaction.mutations[0] * await api.updateTodo(mutation.original.id, mutation.changes) * * // Refetch related collections when this item changes * await Promise.all([ * collection.utils.refetch(), // Refetch this collection * usersCollection.utils.refetch(), // Refetch users * tagsCollection.utils.refetch() // Refetch tags * ]) * * return { refetch: false } // Skip automatic refetch since we handled it manually * } */ onUpdate?: UpdateMutationFn<TItem>; /** * Optional asynchronous handler function called before a delete operation * @param params Object containing transaction and collection information * @returns Promise resolving to void or { refetch?: boolean } to control refetching * @example * // Basic query collection delete handler * onDelete: async ({ transaction }) => { * const mutation = transaction.mutations[0] * await api.deleteTodo(mutation.original.id) * // Automatically refetches query after delete * } * * @example * // Delete handler with refetch control * onDelete: async ({ transaction }) => { * const mutation = transaction.mutations[0] * await api.deleteTodo(mutation.original.id) * return { refetch: false } // Skip automatic refetch * } * * @example * // Delete handler with multiple items * onDelete: async ({ transaction }) => { * const keysToDelete = transaction.mutations.map(m => m.key) * await api.deleteTodos(keysToDelete) * // Will refetch query to get updated data * } * * @example * // Delete handler with related collection refetch * onDelete: async ({ transaction, collection }) => { * const mutation = transaction.mutations[0] * await api.deleteTodo(mutation.original.id) * * // Refetch related collections when this item is deleted * await Promise.all([ * collection.utils.refetch(), // Refetch this collection * usersCollection.utils.refetch(), // Refetch users * projectsCollection.utils.refetch() // Refetch projects * ]) * * return { refetch: false } // Skip automatic refetch since we handled it manually * } */ onDelete?: DeleteMutationFn<TItem>; } /** * Type for the refetch utility function */ export type RefetchFn = () => Promise<void>; /** * Query collection utilities type */ export interface QueryCollectionUtils extends UtilsRecord { refetch: RefetchFn; } /** * Creates query collection options for use with a standard Collection * * @param config - Configuration options for the Query collection * @returns Collection options with utilities */ export declare function queryCollectionOptions<TItem extends object, TError = unknown, TQueryKey extends QueryKey = QueryKey>(config: QueryCollectionConfig<TItem, TError, TQueryKey>): CollectionConfig<TItem> & { utils: QueryCollectionUtils; };