UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines 4.33 kB
{"version":3,"file":"query-once.cjs","sources":["../../../src/query/query-once.ts"],"sourcesContent":["import { createLiveQueryCollection } from './live-query-collection.js'\nimport type { InitialQueryBuilder, QueryBuilder } from './builder/index.js'\nimport type { Context, InferResultType } from './builder/types.js'\n\n/**\n * Configuration options for queryOnce\n */\nexport interface QueryOnceConfig<TContext extends Context> {\n /**\n * Query builder function that defines the query\n */\n query:\n | ((q: InitialQueryBuilder) => QueryBuilder<TContext>)\n | QueryBuilder<TContext>\n // Future: timeout, signal, etc.\n}\n\n// Overload 1: Simple query function returning array (non-single result)\n/**\n * Executes a one-shot query and returns the results as an array.\n *\n * This function creates a live query collection, preloads it, extracts the results,\n * and automatically cleans up the collection. It's ideal for:\n * - AI/LLM context building\n * - Data export\n * - Background processing\n * - Testing\n *\n * @param queryFn - A function that receives the query builder and returns a query\n * @returns A promise that resolves to an array of query results\n *\n * @example\n * ```typescript\n * // Basic query\n * const users = await queryOnce((q) =>\n * q.from({ user: usersCollection })\n * )\n *\n * // With filtering and projection\n * const activeUserNames = await queryOnce((q) =>\n * q.from({ user: usersCollection })\n * .where(({ user }) => eq(user.active, true))\n * .select(({ user }) => ({ name: user.name }))\n * )\n * ```\n */\nexport function queryOnce<TContext extends Context>(\n queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>,\n): Promise<InferResultType<TContext>>\n\n// Overload 2: Config object form returning array (non-single result)\n/**\n * Executes a one-shot query using a configuration object.\n *\n * @param config - Configuration object with the query function\n * @returns A promise that resolves to an array of query results\n *\n * @example\n * ```typescript\n * const recentOrders = await queryOnce({\n * query: (q) =>\n * q.from({ order: ordersCollection })\n * .orderBy(({ order }) => desc(order.createdAt))\n * .limit(100),\n * })\n * ```\n */\nexport function queryOnce<TContext extends Context>(\n config: QueryOnceConfig<TContext>,\n): Promise<InferResultType<TContext>>\n\n// Implementation\nexport async function queryOnce<TContext extends Context>(\n configOrQuery:\n | QueryOnceConfig<TContext>\n | ((q: InitialQueryBuilder) => QueryBuilder<TContext>),\n): Promise<InferResultType<TContext>> {\n // Normalize input\n const config: QueryOnceConfig<TContext> =\n typeof configOrQuery === `function`\n ? { query: configOrQuery }\n : configOrQuery\n\n const query = (q: InitialQueryBuilder) => {\n const queryConfig = config.query\n return typeof queryConfig === `function` ? queryConfig(q) : queryConfig\n }\n\n // Create collection with minimal GC time; preload handles sync start\n const collection = createLiveQueryCollection({\n query,\n gcTime: 1, // Cleanup in next tick when no subscribers (0 disables GC)\n })\n\n try {\n // Wait for initial data load\n await collection.preload()\n\n // Check if this is a single-result query (findOne was called)\n const isSingleResult =\n (collection.config as { singleResult?: boolean }).singleResult === true\n\n // Extract and return results\n if (isSingleResult) {\n const first = collection.values().next().value as\n | InferResultType<TContext>\n | undefined\n return first as InferResultType<TContext>\n }\n return collection.toArray as InferResultType<TContext>\n } finally {\n // Always cleanup, even on error\n await collection.cleanup()\n }\n}\n"],"names":["createLiveQueryCollection"],"mappings":";;;AAwEA,eAAsB,UACpB,eAGoC;AAEpC,QAAM,SACJ,OAAO,kBAAkB,aACrB,EAAE,OAAO,kBACT;AAEN,QAAM,QAAQ,CAAC,MAA2B;AACxC,UAAM,cAAc,OAAO;AAC3B,WAAO,OAAO,gBAAgB,aAAa,YAAY,CAAC,IAAI;AAAA,EAC9D;AAGA,QAAM,aAAaA,oBAAAA,0BAA0B;AAAA,IAC3C;AAAA,IACA,QAAQ;AAAA;AAAA,EAAA,CACT;AAED,MAAI;AAEF,UAAM,WAAW,QAAA;AAGjB,UAAM,iBACH,WAAW,OAAsC,iBAAiB;AAGrE,QAAI,gBAAgB;AAClB,YAAM,QAAQ,WAAW,OAAA,EAAS,OAAO;AAGzC,aAAO;AAAA,IACT;AACA,WAAO,WAAW;AAAA,EACpB,UAAA;AAEE,UAAM,WAAW,QAAA;AAAA,EACnB;AACF;;"}