{"version":3,"file":"inject-query.mjs","sources":["../src/inject-query.ts"],"sourcesContent":["import { QueryObserver } from '@tanstack/query-core'\nimport {\n  Injector,\n  assertInInjectionContext,\n  inject,\n  runInInjectionContext,\n} from '@angular/core'\nimport { createBaseQuery } from './create-base-query'\nimport type { DefaultError, QueryKey } from '@tanstack/query-core'\nimport type {\n  CreateQueryOptions,\n  CreateQueryResult,\n  DefinedCreateQueryResult,\n} from './types'\nimport type {\n  DefinedInitialDataOptions,\n  UndefinedInitialDataOptions,\n} from './query-options'\n\nexport interface InjectQueryOptions {\n  /**\n   * The `Injector` in which to create the query.\n   *\n   * If this is not provided, the current injection context will be used instead (via `inject`).\n   */\n  injector?: Injector\n}\n\n/**\n * This overload is selected when `initialData` is set on the options returned by `injectQueryFn`, so the\n * resulting `data` signal is never `undefined` (unless a `select` changes `TData` to include `undefined`).\n *\n * @see https://tanstack.com/query/latest/docs/framework/angular/guides/queries\n * @see {@link queryOptions} to share these options between `injectQuery` and imperative APIs like\n * `queryClient.fetchQuery`.\n * @param injectQueryFn - A function returning the {@link DefinedInitialDataOptions} to use — everything you\n * can pass to `injectQuery`, with `initialData` set. Similar to `computed` from Angular, this function runs\n * in the reactive context, so signals read inside it (in `queryKey`, `enabled`, etc.) drive the query.\n * @param options - Additional configuration\n * @returns The query result, typed so that `data` is never `undefined` (unless a `select` changes `TData` to\n * include `undefined`).\n *\n * @example\n * ```angular-ts\n * @Component({\n *   selector: 'posts',\n *   template: `\n *     <!-- `postsQuery.data()` is `Post[]`, never `undefined`, thanks to `initialData` — even if a\n *     refetch fails, so the list stays visible alongside the error. -->\n *     @if (postsQuery.isError()) {\n *       <span>Error: {{ postsQuery.error()?.message }}</span>\n *     }\n *     <ul>\n *       @for (post of postsQuery.data(); track post.id) {\n *         <li>{{ post.title }}</li>\n *       }\n *     </ul>\n *   `,\n * })\n * export class Posts {\n *   readonly postsQuery = injectQuery(() => ({\n *     queryKey: ['posts'],\n *     queryFn: fetchPosts,\n *     initialData: [],\n *   }))\n * }\n * ```\n */\nexport function injectQuery<\n  TQueryFnData = unknown,\n  TError = DefaultError,\n  TData = TQueryFnData,\n  TQueryKey extends QueryKey = QueryKey,\n>(\n  injectQueryFn: () => DefinedInitialDataOptions<\n    TQueryFnData,\n    TError,\n    TData,\n    TQueryKey\n  >,\n  options?: InjectQueryOptions,\n): DefinedCreateQueryResult<TData, TError>\n\n/**\n * Injects a query: a declarative dependency on an asynchronous source of data that is tied to a unique key.\n *\n * @see https://tanstack.com/query/latest/docs/framework/angular/guides/queries\n * @see {@link queryOptions} to share these options between `injectQuery` and imperative APIs like\n * `queryClient.fetchQuery`.\n * @param injectQueryFn - A function returning the {@link UndefinedInitialDataOptions} to use — everything\n * you can pass to `injectQuery`. Similar to `computed` from Angular, this function runs in the reactive\n * context, so signals read inside it (in `queryKey`, `enabled`, etc.) drive the query.\n * @param options - Additional configuration\n * @returns The query result. `status()` is `'pending'` if there is no cached data to display, `'error'` if\n * the last fetch attempt failed, or `'success'` if the query has data to display. `isPending`/`isSuccess`/\n * `isError` are type-guard methods for convenience.\n *\n * @example\n * ```angular-ts\n * @Component({\n *   selector: 'posts',\n *   template: `\n *     @if (postsQuery.isPending()) {\n *       Loading...\n *     } @else if (postsQuery.isError()) {\n *       <span>Error: {{ postsQuery.error()?.message }}</span>\n *     } @else {\n *       <ul>\n *         @for (post of postsQuery.data(); track post.id) {\n *           <li>{{ post.title }}</li>\n *         }\n *       </ul>\n *     }\n *   `,\n * })\n * export class Posts {\n *   readonly postsQuery = injectQuery(() => ({\n *     queryKey: ['posts'],\n *     queryFn: fetchPosts,\n *   }))\n * }\n * ```\n *\n * @example\n * Similar to `computed` from Angular, the function passed to `injectQuery` runs in the reactive context. In\n * the example below, the query is automatically enabled and executed when the filter signal changes to a\n * truthy value. When the filter signal changes back to a falsy value, the query is disabled.\n * ```angular-ts\n * @Component({\n *   selector: 'posts',\n *   template: `\n *     <input [ngModel]=\"filter()\" (ngModelChange)=\"filter.set($event)\" />\n *     @if (postsQuery.isPending()) {\n *       Loading...\n *     } @else if (postsQuery.isError()) {\n *       <span>Error: {{ postsQuery.error()?.message }}</span>\n *     } @else {\n *       <ul>\n *         @for (post of postsQuery.data(); track post.id) {\n *           <li>{{ post.title }}</li>\n *         }\n *       </ul>\n *     }\n *   `,\n * })\n * export class Posts {\n *   readonly filter = signal('')\n *\n *   readonly postsQuery = injectQuery(() => ({\n *     queryKey: ['posts', this.filter()],\n *     queryFn: () => fetchPosts(this.filter()),\n *     // Signals can be combined with expressions\n *     enabled: !!this.filter(),\n *   }))\n * }\n * ```\n */\nexport function injectQuery<\n  TQueryFnData = unknown,\n  TError = DefaultError,\n  TData = TQueryFnData,\n  TQueryKey extends QueryKey = QueryKey,\n>(\n  injectQueryFn: () => UndefinedInitialDataOptions<\n    TQueryFnData,\n    TError,\n    TData,\n    TQueryKey\n  >,\n  options?: InjectQueryOptions,\n): CreateQueryResult<TData, TError>\n\n/**\n * This overload accepts the general {@link CreateQueryOptions} shape rather than the `initialData`-aware\n * overloads above, so whether `data` is defined can't be inferred from the call site — useful when wrapping\n * `injectQuery` in your own helper function that forwards caller-provided options.\n *\n * @see https://tanstack.com/query/latest/docs/framework/angular/guides/queries\n * @param injectQueryFn - A function that returns query options. Similar to `computed` from Angular, this\n * function runs in the reactive context, so signals read inside it (in `queryKey`, `enabled`, etc.) drive\n * the query.\n * @param options - Additional configuration\n * @returns The query result.\n */\nexport function injectQuery<\n  TQueryFnData = unknown,\n  TError = DefaultError,\n  TData = TQueryFnData,\n  TQueryKey extends QueryKey = QueryKey,\n>(\n  injectQueryFn: () => CreateQueryOptions<\n    TQueryFnData,\n    TError,\n    TData,\n    TQueryKey\n  >,\n  options?: InjectQueryOptions,\n): CreateQueryResult<TData, TError>\n\nexport function injectQuery(\n  injectQueryFn: () => CreateQueryOptions,\n  options?: InjectQueryOptions,\n) {\n  !options?.injector && assertInInjectionContext(injectQuery)\n  return runInInjectionContext(options?.injector ?? inject(Injector), () =>\n    createBaseQuery(injectQueryFn, QueryObserver),\n  ) as unknown as CreateQueryResult\n}\n"],"names":[],"mappings":";;;AAuMO,SAAS,YACd,eACA,SACA;AACA,IAAC,mCAAS,aAAY,yBAAyB,WAAW;AAC1D,SAAO;AAAA,KAAsB,mCAAS,aAAY,OAAO,QAAQ;AAAA,IAAG,MAClE,gBAAgB,eAAe,aAAa;AAAA,EAAA;AAEhD;"}