@mmstack/resource 19.6.4 → 19.6.6

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.
@@ -2,14 +2,38 @@ import { type HttpResourceRequest } from '@angular/common/http';
2
2
  import { type Provider, type Signal, type ValueEqualityFn } from '@angular/core';
3
3
  import { type QueryResourceOptions, type QueryResourceRef } from './query-resource';
4
4
  /**
5
- * @internal
6
- * Helper type for inferring the request body type based on the HTTP method.
5
+ * Why a {@link MutationResourceRef.mutateAsync} promise was cancelled — a closed
6
+ * set so consumers can branch on the cause without parsing the message:
7
+ * - `'superseded'`: a newer mutation replaced it (latest-wins).
8
+ * - `'queue-cleared'`: dropped from the queue by `clearQueue()`.
9
+ * - `'queue-key-changed'`: dropped from the queue by a reactive `key` change.
10
+ * - `'destroyed'`: the resource was destroyed while it was pending/in flight.
11
+ * - `'no-request'`: `request()` returned `undefined`, so nothing was sent.
7
12
  */
8
- type NextRequest<TMethod extends HttpResourceRequest['method'], TMutation> = TMethod extends 'DELETE' | 'delete' ? Omit<HttpResourceRequest, 'body' | 'method'> & {
9
- method: TMethod;
10
- } : Omit<HttpResourceRequest, 'body' | 'method'> & {
11
- body: TMutation;
12
- method: TMethod;
13
+ export type MutationCancellationReason = 'superseded' | 'queue-cleared' | 'queue-key-changed' | 'destroyed' | 'no-request';
14
+ /**
15
+ * Rejection reason for a {@link MutationResourceRef.mutateAsync} promise whose
16
+ * mutation never completed. The {@link MutationCancelledError.type} discriminant
17
+ * carries the cause ({@link MutationCancellationReason}); the message is a
18
+ * human-readable elaboration of it.
19
+ *
20
+ * Only `mutateAsync` promises reject with this; plain `mutate()` calls have no
21
+ * promise and so produce no (potentially unhandled) rejection.
22
+ */
23
+ export declare class MutationCancelledError extends Error {
24
+ readonly type: MutationCancellationReason;
25
+ constructor(type: MutationCancellationReason, message: string);
26
+ }
27
+ /**
28
+ * Object form of the `queue` option. Enabling the queue serializes mutations
29
+ * into a FIFO that runs one-at-a-time.
30
+ */
31
+ export type MutationQueueOptions = {
32
+ /**
33
+ * Reactive queue key. When its returned value changes, the *pending* (not-yet-fired)
34
+ * queued mutations are dropped; an in-flight mutation is unaffected. e.g. `key: () => selectedId()`.
35
+ */
36
+ key?: () => string | number;
13
37
  };
14
38
  /**
15
39
  * Options for configuring a `mutationResource`. Inherits from
@@ -62,10 +86,13 @@ export type MutationResourceOptions<TResult, TRaw = TResult, TMutation = TResult
62
86
  */
63
87
  onSettled?: (ctx: NoInfer<TCTX>) => void;
64
88
  /**
65
- * Whether to queue the mutation requests and execute them in series. For example if network is unavailable or circuit breaker is open.
89
+ * Queue mutations and run them one-at-a-time in series, instead of latest-wins
90
+ * superseding (e.g. while offline or the circuit breaker is open). Pass
91
+ * {@link MutationQueueOptions} for a reactive `key` that resets the pending queue.
92
+ * The pending queue can also be cleared via `ref.clearQueue()`.
66
93
  * @default false
67
94
  */
68
- queue?: boolean;
95
+ queue?: boolean | MutationQueueOptions;
69
96
  /**
70
97
  * Cache entries to invalidate after a SUCCESSFUL mutation — the declarative
71
98
  * alternative to calling `injectQueryCache().invalidatePrefix(...)` in `onSuccess`.
@@ -120,11 +147,28 @@ export type MutationResourceRef<TResult, TMutation = TResult, TICTX = void> = Om
120
147
  * @param ctx An optional initial context value that will be passed to the `onMutate` callback.
121
148
  */
122
149
  mutate: (value: TMutation, ctx?: TICTX) => void;
150
+ /**
151
+ * Executes the mutation and returns a `Promise`
152
+ *
153
+ * If the mutation never completes — superseded by a newer `mutate`/`mutateAsync`
154
+ * (latest-wins), dropped from the queue (`clearQueue` / queue `key` change),
155
+ * abandoned on `destroy()`, or its `request()` returned `undefined` — the
156
+ * promise rejects with a {@link MutationCancelledError}.
157
+ *
158
+ * @param value The mutation value (usually the request body).
159
+ * @param ctx An optional initial context value that will be passed to the `onMutate` callback.
160
+ */
161
+ mutateAsync: (value: TMutation, ctx?: TICTX) => Promise<TResult>;
123
162
  /**
124
163
  * A signal that holds the current mutation request, or `null` if no mutation is in progress.
125
164
  * This can be useful for tracking the state of the mutation or for displaying loading indicators.
126
165
  */
127
166
  current: Signal<TMutation | null>;
167
+ /**
168
+ * Drops all *pending* queued mutations; an in-flight mutation is unaffected.
169
+ * Noops when `queue` is not enabled.
170
+ */
171
+ clearQueue: () => void;
128
172
  };
129
173
  /**
130
174
  * Creates a resource for performing mutations (e.g., POST, PUT, PATCH, DELETE requests).
@@ -175,5 +219,9 @@ export type MutationResourceRef<TResult, TMutation = TResult, TICTX = void> = Om
175
219
  * );
176
220
  * ```
177
221
  */
178
- export declare function mutationResource<TResult, TRaw = TResult, TMutation = TResult, TCTX = void, TICTX = TCTX, TMethod extends HttpResourceRequest['method'] = HttpResourceRequest['method']>(request: (params: TMutation) => Omit<NextRequest<TMethod, TMutation>, 'body'> | undefined | void, options0?: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX>): MutationResourceRef<TResult, TMutation, TICTX>;
179
- export {};
222
+ export declare function mutationResource<TResult, TRaw = TResult, TMutation = TResult, TCTX = void, TICTX = TCTX>(request: (params: TMutation) => (Omit<HttpResourceRequest, 'body' | 'method'> & {
223
+ method: 'DELETE' | 'delete';
224
+ }) | undefined | void, options0?: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX>): MutationResourceRef<TResult, TMutation, TICTX>;
225
+ export declare function mutationResource<TResult, TRaw = TResult, TMutation = TResult, TCTX = void, TICTX = TCTX>(request: (params: TMutation) => (Omit<HttpResourceRequest, 'body'> & {
226
+ body: TMutation;
227
+ }) | undefined | void, options0?: MutationResourceOptions<TResult, TRaw, TMutation, TCTX, TICTX>): MutationResourceRef<TResult, TMutation, TICTX>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmstack/resource",
3
- "version": "19.6.4",
3
+ "version": "19.6.6",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",