ngx-signal-query 1.5.0-dev.2 → 1.5.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -46,6 +46,16 @@ type QueryFilters = {
46
46
  /** Require an exact key match instead of a prefix match. */
47
47
  exact?: boolean;
48
48
  };
49
+ /** Selects which queries `invalidateQueries` marks stale, and what it refetches. */
50
+ type InvalidateQueryFilters = QueryFilters & {
51
+ /**
52
+ * Which of the marked queries to refetch now: `'active'`, the default,
53
+ * refetches those a component shows; `'none'` refetches none, so each one
54
+ * refetches when stale data next would, e.g. as a component starts showing
55
+ * it. Queries nobody shows are only marked either way.
56
+ */
57
+ refetchType?: 'active' | 'none';
58
+ };
49
59
  /** A new value, or a function deriving it from the previous one. */
50
60
  type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput);
51
61
  /**
@@ -184,8 +194,16 @@ type QueryResult<TData, TError = Error> = {
184
194
  failureCount: Signal<number>;
185
195
  /** Error of the most recent failed attempt, or `null`. */
186
196
  failureReason: Signal<TError | null>;
187
- /** Forces a fresh fetch, cancelling any in-flight request. */
188
- refetch: () => void;
197
+ /**
198
+ * Forces a fresh fetch, cancelling any in-flight request. Resolves once the
199
+ * fetch has settled, or the fetch that replaced it has, with `data` and
200
+ * `error` as the signals above hold them then. It never rejects: a failure
201
+ * shows in `error`.
202
+ */
203
+ refetch: () => Promise<{
204
+ data: TData | undefined;
205
+ error: TError | null;
206
+ }>;
189
207
  };
190
208
  /** Default query options applied to every query unless overridden per-query. */
191
209
  interface DefaultQueryOptions {
@@ -265,7 +283,7 @@ declare class Query<TData, TError = Error> {
265
283
  setGcTime(ms: number): void;
266
284
  addObserver(observer: QuerySubscriber<TData, TError>): void;
267
285
  removeObserver(observer: QuerySubscriber<TData, TError>): void;
268
- activeFetchOptions(): ReturnType<QuerySubscriber<TData, TError>['fetchOptions']>;
286
+ refetchIfActive(): Promise<TData> | undefined;
269
287
  onFocus(): void;
270
288
  onOnline(): void;
271
289
  structuralSharing(): StructuralSharingValue<TData> | undefined;
@@ -364,6 +382,14 @@ type MutationOptions<TData, TError, TVariables, TContext> = {
364
382
  type MutationResult<TData, TError, TVariables> = {
365
383
  /** Triggers the mutation with the given variables. */
366
384
  mutate: (variables: TVariables) => void;
385
+ /**
386
+ * Triggers the mutation as `mutate()` does, and returns a promise of that
387
+ * run: it resolves with the data once the last hook is done, or rejects
388
+ * with the error once `onError` and `onSettled` are. Unlike `mutate()`, a
389
+ * failure nobody catches surfaces as an unhandled rejection, as with any
390
+ * async call.
391
+ */
392
+ mutateAsync: (variables: TVariables) => Promise<TData>;
367
393
  /**
368
394
  * Resets the state to `idle`. It forgets the result and doesn't stop the
369
395
  * request: a run in flight finishes and fires its hooks.
@@ -405,8 +431,12 @@ declare class Mutation<TData = unknown, TError = Error, TVariables = void, TCont
405
431
  * settled and been abandoned — whichever of the two happens last.
406
432
  */
407
433
  removeObserver(): void;
408
- /** Runs the mutation once. `variables` are passed straight to `mutationFn`. */
409
- execute(variables: TVariables): void;
434
+ /**
435
+ * Runs the mutation once. `variables` are passed straight to `mutationFn`.
436
+ * Returns a promise of the run, settled as the state is, once its last hook
437
+ * is done: with the data, or with the error.
438
+ */
439
+ execute(variables: TVariables): Promise<TData>;
410
440
  cancel(): void;
411
441
  }
412
442
 
@@ -463,12 +493,38 @@ declare class QueryClient {
463
493
  /**
464
494
  * Imperatively fetches and caches a query, unless fresh data already exists
465
495
  * (governed by `staleTime`). Prefer {@link injectQuery} in components; use
466
- * this to prefetch, from an event handler or an effect.
496
+ * this to prefetch, from an event handler or an effect, or to wait for the
497
+ * data, e.g. in a route resolver.
498
+ *
499
+ * Resolves with the data as the cache holds it: at once if it's fresh,
500
+ * otherwise once the fetch lands. A key already fetching is waited for,
501
+ * not fetched again, unless `cancelRefetch` is set. Rejects with the error
502
+ * if the fetch fails. A cancelled fetch resolves with the data the cache
503
+ * holds, or rejects with a {@link CancelledError} if it holds none; a
504
+ * removed query always rejects with one. Nothing has to wait for the
505
+ * promise: a prefetch that fails only leaves the query in `'error'`.
506
+ *
507
+ * Unlike a component's query, it doesn't retry a failure unless `retry` is
508
+ * set here or in {@link withDefaultOptions}, so whoever waits for the data
509
+ * hears of the failure at once.
467
510
  *
468
511
  * @param key - The query key to fetch and cache under.
469
512
  * @param queryFn - Function returning the data as an `Observable` or `Promise`.
470
513
  * @param options - Fetch tuning (`staleTime`, `retry`, `retryDelay`,
471
514
  * `structuralSharing`, `cancelRefetch`).
515
+ * @returns A promise of the data.
516
+ *
517
+ * @example
518
+ * ```ts
519
+ * export const todoResolver: ResolveFn<Todo> = (route) => {
520
+ * const http = inject(HttpClient)
521
+ * const id = Number(route.paramMap.get('id'))
522
+ *
523
+ * return injectQueryClient().fetchQuery(['todos', id], () =>
524
+ * http.get<Todo>(`/api/todos/${id}`),
525
+ * )
526
+ * }
527
+ * ```
472
528
  */
473
529
  fetchQuery<TData>(key: QueryKey, queryFn: () => Observable<TData> | Promise<TData>, options?: {
474
530
  staleTime?: number;
@@ -476,7 +532,7 @@ declare class QueryClient {
476
532
  retryDelay?: RetryDelayValue<any>;
477
533
  structuralSharing?: StructuralSharingValue<TData>;
478
534
  cancelRefetch?: boolean;
479
- }): void;
535
+ }): Promise<TData>;
480
536
  /**
481
537
  * Reads the current cached data for a query key, or `undefined` if the query
482
538
  * is not cached yet. A snapshot: it doesn't update a template, a `computed`
@@ -510,18 +566,41 @@ declare class QueryClient {
510
566
  * Marks matching queries as stale and refetches the actively observed ones,
511
567
  * once per query however many components observe it. The refetch starts
512
568
  * right away and replaces a fetch already in flight, which may predate the
513
- * change; this method doesn't wait for it. A query with no enabled observer
514
- * keeps the stale mark and refetches as soon as one appears. Commonly called
515
- * after a mutation succeeds.
569
+ * change. A query with no enabled observer keeps the stale mark and
570
+ * refetches as soon as one appears. Commonly called after a mutation
571
+ * succeeds.
572
+ *
573
+ * Resolves once those refetches have settled, so a mutation hook that
574
+ * returns it keeps the mutation pending until the data is fresh. It never
575
+ * rejects: a refetch that fails shows in its query's `error`.
516
576
  *
517
577
  * @param filters - Which queries to invalidate; omit to invalidate all.
578
+ * `refetchType: 'none'` only marks them, and resolves at once.
518
579
  *
519
580
  * @example
520
581
  * ```ts
521
582
  * client.invalidateQueries({ queryKey: ['todos'] })
522
583
  * ```
523
584
  */
524
- invalidateQueries(filters?: QueryFilters): void;
585
+ invalidateQueries(filters?: InvalidateQueryFilters): Promise<void>;
586
+ /**
587
+ * Refetches the matching queries that a component shows, whether their
588
+ * data is stale or not, once per query however many components show it. A
589
+ * fetch already in flight is replaced. Queries nobody shows are left as
590
+ * they are, not even marked stale: to have them refetch once they're shown,
591
+ * invalidate them with `invalidateQueries()`.
592
+ *
593
+ * Resolves once the refetches have settled. It never rejects: a refetch
594
+ * that fails shows in its query's `error`.
595
+ *
596
+ * @param filters - Which queries to refetch; omit to refetch all.
597
+ *
598
+ * @example
599
+ * ```ts
600
+ * await client.refetchQueries({ queryKey: ['todos'] })
601
+ * ```
602
+ */
603
+ refetchQueries(filters?: QueryFilters): Promise<void>;
525
604
  /**
526
605
  * Cancels any in-flight fetches for matching queries.
527
606
  *
@@ -737,9 +816,11 @@ declare function injectQueries<TData, TError = Error>(optionsFn: () => InjectQue
737
816
  * until it settles. Mutations do not retry by default (a retried write is not
738
817
  * idempotent); opt in via `options.retry`. Whatever of `retry`, `retryDelay`
739
818
  * and the `onSuccess` / `onError` / `onSettled` hooks a mutation leaves unset
740
- * comes from {@link withDefaultOptions}. `mutate()` and `reset()` are safe
741
- * to call from an effect: neither makes the effect depend on what it reads,
742
- * such as the options or the previous run. Bound to the current injection
819
+ * comes from {@link withDefaultOptions}. `mutateAsync(variables)` runs it
820
+ * the same way and returns a promise of the run's data. `mutate()`,
821
+ * `mutateAsync()` and `reset()` are safe to call from an effect: none makes
822
+ * the effect depend on what it reads, such as the options or the previous
823
+ * run. Bound to the current injection
743
824
  * context. Destroying it doesn't cancel a run in flight: the write has most
744
825
  * likely reached the server, so the run finishes and fires its hooks.
745
826
  *
@@ -751,8 +832,8 @@ declare function injectQueries<TData, TError = Error>(optionsFn: () => InjectQue
751
832
  * @typeParam TContext - Type returned by `onMutate`, passed to later hooks.
752
833
  * @param optionsFn - Factory returning the {@link MutationOptions}.
753
834
  * @param options - Optional `injector` to use outside an injection context.
754
- * @returns A {@link MutationResult}: `mutate()`, `reset()`, and state signals
755
- * (`status`, `data`, `error`, `isPending`, …).
835
+ * @returns A {@link MutationResult}: `mutate()`, `mutateAsync()`, `reset()`,
836
+ * and state signals (`status`, `data`, `error`, `isPending`, …).
756
837
  *
757
838
  * @example
758
839
  * ```ts
@@ -892,6 +973,20 @@ declare function keepPreviousData<TData>(previousData: TData | undefined): TData
892
973
  */
893
974
  declare function mutationOptions<TData, TError = Error, TVariables = void, TContext = unknown>(options: MutationOptions<TData, TError, TVariables, TContext>): MutationOptions<TData, TError, TVariables, TContext>;
894
975
 
976
+ /**
977
+ * The error a promise of a query's data rejects with when the fetch stops
978
+ * with no data to give: it was cancelled before the query had any
979
+ * (`cancelQueries()`, or the last component showing the query went away), or
980
+ * the query was removed (`removeQueries()`, e.g. on sign-out). The request
981
+ * didn't fail, so tell the two apart with `instanceof CancelledError`.
982
+ *
983
+ * A mutation's `mutateAsync()` rejects with one too, when the mutation cache
984
+ * is cleared while its run is in flight.
985
+ */
986
+ declare class CancelledError extends Error {
987
+ constructor(message?: string);
988
+ }
989
+
895
990
  /**
896
991
  * Feature for {@link provideQueryClient} that sets application-wide default
897
992
  * query and mutation options. A query's or mutation's own options take
@@ -914,5 +1009,5 @@ declare function mutationOptions<TData, TError = Error, TVariables = void, TCont
914
1009
  */
915
1010
  declare function withDefaultOptions(options: DefaultOptions): QueryClientFeature<QueryClientFeatureKind.DefaultOptions>;
916
1011
 
917
- export { QueryClient, QueryClientFeatureKind, injectIsFetching, injectIsMutating, injectMutation, injectQueries, injectQuery, injectQueryClient, keepPreviousData, mutationOptions, provideQueryClient, queryOptions, withDefaultOptions };
918
- export type { DefaultMutationOptions, DefaultOptions, DefaultQueryOptions, DefaultedQueryOptions, InjectQueriesOptions, MutationFilters, MutationOptions, MutationResult, MutationState, MutationStatus, PlaceholderDataFunction, QueryClientFeature, QueryFilters, QueryKey, QueryOptions, QueryResult, QueryState, QueryStatus, RefetchIntervalValue, RetryDelayValue, RetryValue, StructuralSharingValue, Updater };
1012
+ export { CancelledError, QueryClient, QueryClientFeatureKind, injectIsFetching, injectIsMutating, injectMutation, injectQueries, injectQuery, injectQueryClient, keepPreviousData, mutationOptions, provideQueryClient, queryOptions, withDefaultOptions };
1013
+ export type { DefaultMutationOptions, DefaultOptions, DefaultQueryOptions, DefaultedQueryOptions, InjectQueriesOptions, InvalidateQueryFilters, MutationFilters, MutationOptions, MutationResult, MutationState, MutationStatus, PlaceholderDataFunction, QueryClientFeature, QueryFilters, QueryKey, QueryOptions, QueryResult, QueryState, QueryStatus, RefetchIntervalValue, RetryDelayValue, RetryValue, StructuralSharingValue, Updater };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-signal-query",
3
- "version": "1.5.0-dev.2",
3
+ "version": "1.5.0-dev.3",
4
4
  "description": "Data fetching, caching and mutations for Angular, built on signals and RxJS. Observables end to end, TanStack Query concepts.",
5
5
  "keywords": [
6
6
  "angular",