@tanstack/query-core
Version:
The framework agnostic core that powers TanStack Query
1 lines • 3.4 kB
Source Map (JSON)
{"version":3,"sources":["../../src/streamedQuery.ts"],"sourcesContent":["import type { QueryFunction, QueryFunctionContext, QueryKey } from './types'\n\n/**\n * This is a helper function to create a query function that streams data from an AsyncIterable.\n * Data will be an Array of all the chunks received.\n * The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.\n * The query will stay in fetchStatus 'fetching' until the stream ends.\n * @param queryFn - The function that returns an AsyncIterable to stream data from.\n * @param refetchMode - Defines how re-fetches are handled.\n * Defaults to `'reset'`, erases all data and puts the query back into `pending` state.\n * Set to `'append'` to append new data to the existing data.\n * Set to `'replace'` to write the data to the cache at the end of the stream.\n */\nexport function streamedQuery<\n TQueryFnData = unknown,\n TQueryKey extends QueryKey = QueryKey,\n>({\n queryFn,\n refetchMode = 'reset',\n}: {\n queryFn: (\n context: QueryFunctionContext<TQueryKey>,\n ) => AsyncIterable<TQueryFnData> | Promise<AsyncIterable<TQueryFnData>>\n refetchMode?: 'append' | 'reset' | 'replace'\n}): QueryFunction<Array<TQueryFnData>, TQueryKey> {\n return async (context) => {\n const query = context.client\n .getQueryCache()\n .find({ queryKey: context.queryKey, exact: true })\n const isRefetch = !!query && query.state.data !== undefined\n\n if (isRefetch && refetchMode === 'reset') {\n query.setState({\n status: 'pending',\n data: undefined,\n error: null,\n fetchStatus: 'fetching',\n })\n }\n\n const result: Array<TQueryFnData> = []\n const stream = await queryFn(context)\n\n for await (const chunk of stream) {\n if (context.signal.aborted) {\n break\n }\n\n // don't append to the cache directly when replace-refetching\n if (!isRefetch || refetchMode !== 'replace') {\n context.client.setQueryData<Array<TQueryFnData>>(\n context.queryKey,\n (prev = []) => {\n return prev.concat([chunk])\n },\n )\n }\n result.push(chunk)\n }\n\n // finalize result: replace-refetching needs to write to the cache\n if (isRefetch && refetchMode === 'replace' && !context.signal.aborted) {\n context.client.setQueryData<Array<TQueryFnData>>(context.queryKey, result)\n }\n\n return context.client.getQueryData(context.queryKey)!\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,SAAS,cAGd;AAAA,EACA;AAAA,EACA,cAAc;AAChB,GAKkD;AAChD,SAAO,OAAO,YAAY;AACxB,UAAM,QAAQ,QAAQ,OACnB,cAAc,EACd,KAAK,EAAE,UAAU,QAAQ,UAAU,OAAO,KAAK,CAAC;AACnD,UAAM,YAAY,CAAC,CAAC,SAAS,MAAM,MAAM,SAAS;AAElD,QAAI,aAAa,gBAAgB,SAAS;AACxC,YAAM,SAAS;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAEA,UAAM,SAA8B,CAAC;AACrC,UAAM,SAAS,MAAM,QAAQ,OAAO;AAEpC,qBAAiB,SAAS,QAAQ;AAChC,UAAI,QAAQ,OAAO,SAAS;AAC1B;AAAA,MACF;AAGA,UAAI,CAAC,aAAa,gBAAgB,WAAW;AAC3C,gBAAQ,OAAO;AAAA,UACb,QAAQ;AAAA,UACR,CAAC,OAAO,CAAC,MAAM;AACb,mBAAO,KAAK,OAAO,CAAC,KAAK,CAAC;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAGA,QAAI,aAAa,gBAAgB,aAAa,CAAC,QAAQ,OAAO,SAAS;AACrE,cAAQ,OAAO,aAAkC,QAAQ,UAAU,MAAM;AAAA,IAC3E;AAEA,WAAO,QAAQ,OAAO,aAAa,QAAQ,QAAQ;AAAA,EACrD;AACF;","names":[]}