@angular-architects/ngrx-toolkit 20.1.0 → 20.4.0

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
@@ -1,8 +1,9 @@
1
1
  import * as _ngrx_signals from '@ngrx/signals';
2
2
  import { StateSource, patchState as patchState$1, WritableStateSource, PartialStateUpdater, SignalStoreFeature, EmptyFeatureResult, SignalStoreFeatureResult, StateSignals } from '@ngrx/signals';
3
- import { ValueProvider, Signal, ProviderToken, WritableSignal, ResourceStatus, Resource, ResourceRef } from '@angular/core';
4
- import { Observable } from 'rxjs';
3
+ import { ValueProvider, Signal, ProviderToken, WritableSignal, Injector, ResourceStatus, Resource, ResourceRef } from '@angular/core';
4
+ import { Observable, ObservableInput, OperatorFunction, ObservedValueOf } from 'rxjs';
5
5
  import { EntityId, NamedEntityState } from '@ngrx/signals/entities';
6
+ import { HttpHeaders, HttpContext, HttpParams, HttpProgressEvent } from '@angular/common/http';
6
7
 
7
8
  /**
8
9
  * Provides the configuration options for connecting to the Redux DevTools Extension.
@@ -941,6 +942,161 @@ type StoreForFactory<Input extends SignalStoreFeatureResult> = StateSignals<Inpu
941
942
  */
942
943
  declare function withFeatureFactory<Input extends SignalStoreFeatureResult, Output extends SignalStoreFeatureResult>(factoryFn: (store: StoreForFactory<Input>) => SignalStoreFeature<Input, Output>): SignalStoreFeature<Input, Output>;
943
944
 
945
+ type RxJsFlatteningOperator = <T, O extends ObservableInput<unknown>>(project: (value: T, index: number) => O) => OperatorFunction<T, ObservedValueOf<O>>;
946
+ /**
947
+ * A wrapper for an RxJS flattening operator.
948
+ * This wrapper informs about whether the operator has exhaust semantics or not.
949
+ */
950
+ type FlatteningOperator = {
951
+ rxJsOperator: RxJsFlatteningOperator;
952
+ exhaustSemantics: boolean;
953
+ };
954
+ declare const switchOp: FlatteningOperator;
955
+ declare const mergeOp: FlatteningOperator;
956
+ declare const concatOp: FlatteningOperator;
957
+ declare const exhaustOp: FlatteningOperator;
958
+
959
+ type MutationResult<Result> = {
960
+ status: 'success';
961
+ value: Result;
962
+ } | {
963
+ status: 'error';
964
+ error: unknown;
965
+ } | {
966
+ status: 'aborted';
967
+ };
968
+ type MutationStatus = 'idle' | 'pending' | 'error' | 'success';
969
+ type Mutation<Parameter, Result> = {
970
+ (params: Parameter): Promise<MutationResult<Result>>;
971
+ status: Signal<MutationStatus>;
972
+ value: Signal<Result | undefined>;
973
+ isPending: Signal<boolean>;
974
+ isSuccess: Signal<boolean>;
975
+ error: Signal<unknown>;
976
+ hasValue(): this is Mutation<Exclude<Parameter, undefined>, Result>;
977
+ };
978
+
979
+ type Operation<Parameter, Result> = (param: Parameter) => Result;
980
+ interface RxMutationOptions<Parameter, Result> {
981
+ operation: Operation<Parameter, Observable<Result>>;
982
+ onSuccess?: (result: Result, param: Parameter) => void;
983
+ onError?: (error: unknown, param: Parameter) => void;
984
+ operator?: FlatteningOperator;
985
+ injector?: Injector;
986
+ }
987
+ /**
988
+ * Creates a mutation that leverages RxJS.
989
+ *
990
+ * For each mutation the following options can be defined:
991
+ * - `operation`: A function that defines the mutation logic. It returns an Observable.
992
+ * - `onSuccess`: A callback that is called when the mutation is successful.
993
+ * - `onError`: A callback that is called when the mutation fails.
994
+ * - `operator`: An optional wrapper of an RxJS flattening operator. By default `concat` sematics are used.
995
+ * - `injector`: An optional Angular injector to use for dependency injection.
996
+ *
997
+ * The `operation` is the only mandatory option.
998
+ *
999
+ * The returned mutation can be called as an async function and returns a Promise.
1000
+ * This promise informs about whether the mutation was successful, failed, or aborted
1001
+ * (due to switchMap or exhaustMap semantics).
1002
+ *
1003
+ * The mutation also provides several Signals such as error, status or isPending (see below).
1004
+ *
1005
+ * Example usage without Store:
1006
+ *
1007
+ * ```typescript
1008
+ * const counterSignal = signal(0);
1009
+ *
1010
+ * const increment = rxMutation({
1011
+ * operation: (param: Param) => {
1012
+ * return calcSum(this.counterSignal(), param.value);
1013
+ * },
1014
+ * operator: concatOp,
1015
+ * onSuccess: (result) => {
1016
+ * this.counterSignal.set(result);
1017
+ * },
1018
+ * onError: (error) => {
1019
+ * console.error('Error occurred:', error);
1020
+ * },
1021
+ * });
1022
+ *
1023
+ * const error = increment.error;
1024
+ * const isPending = increment.isPending;
1025
+ * const status = increment.status;
1026
+ * const value = increment.value;
1027
+ * const hasValue = increment.hasValue;
1028
+ *
1029
+ * async function incrementCounter() {
1030
+ * const result = await increment({ value: 1 });
1031
+ * if (result.status === 'success') {
1032
+ * console.log('Success:', result.value);
1033
+ * }
1034
+ * if (result.status === 'error') {
1035
+ * console.log('Error:', result.error);
1036
+ * }
1037
+ * if (result.status === 'aborted') {
1038
+ * console.log('Operation aborted');
1039
+ * }
1040
+ * }
1041
+ *
1042
+ * function calcSum(a: number, b: number): Observable<number> {
1043
+ * return of(result).pipe(delay(500));
1044
+ * }
1045
+ * ```
1046
+ *
1047
+ * @param options
1048
+ * @returns the actual mutation function along tracking data as properties/methods
1049
+ */
1050
+ declare function rxMutation<Parameter, Result>(optionsOrOperation: RxMutationOptions<Parameter, Result> | Operation<Parameter, Observable<Result>>): Mutation<Parameter, Result>;
1051
+
1052
+ type MutationsDictionary = Record<string, Mutation<any, any>>;
1053
+ type MethodsDictionary = Record<string, Function>;
1054
+ type NamedMutationProps<T extends MutationsDictionary> = {
1055
+ [Prop in keyof T as `${Prop & string}IsPending`]: Signal<boolean>;
1056
+ } & {
1057
+ [Prop in keyof T as `${Prop & string}Status`]: Signal<MutationStatus>;
1058
+ } & {
1059
+ [Prop in keyof T as `${Prop & string}Error`]: Signal<Error | undefined>;
1060
+ };
1061
+ type NamedMutationMethods<T extends MutationsDictionary> = {
1062
+ [Prop in keyof T as `${Prop & string}`]: T[Prop] extends Mutation<infer P, infer R> ? Mutation<P, R> : never;
1063
+ };
1064
+ type NamedMutationResult<T extends MutationsDictionary> = EmptyFeatureResult & {
1065
+ props: NamedMutationProps<T>;
1066
+ methods: NamedMutationMethods<T>;
1067
+ };
1068
+ /**
1069
+ * Adds mutation methods to the store. Also, for each mutation method, several
1070
+ * Signals are added informing about the mutation's status and errors.
1071
+ *
1072
+ * ```typescript
1073
+ * export type Params = {
1074
+ * value: number;
1075
+ * };
1076
+ *
1077
+ * export const CounterStore = signalStore(
1078
+ * { providedIn: 'root' },
1079
+ * withState({ counter: 0 }),
1080
+ * withMutations((store) => ({
1081
+ * increment: rxMutation({ ... }),
1082
+ * })),
1083
+ * );
1084
+ * ```
1085
+ *
1086
+ * There are several types of mutations. In the example shown, an {@link module:rx-mutation.rxMutation | rxMutation}
1087
+ * leveraging RxJS is used
1088
+ *
1089
+ * For the defined `increment` mutation, several the following properties and
1090
+ * methods are added to the store:
1091
+ * - `increment(params: Params): Promise<MutationResult<number>>`: The mutation method.
1092
+ * - `incrementIsPending`: A signal indicating if the mutation is in progress.
1093
+ * - `incrementStatus`: A signal representing the current status of the mutation.
1094
+ * - `incrementError`: A signal containing any error that occurred during the mutation.
1095
+ *
1096
+ * @param mutationsFactory
1097
+ */
1098
+ declare function withMutations<Input extends SignalStoreFeatureResult, Result extends MutationsDictionary>(mutationsFactory: (store: Input['props'] & Input['methods'] & WritableStateSource<Input['state']> & StateSignals<Input['state']>) => Result): SignalStoreFeature<Input, NamedMutationResult<Result>>;
1099
+
944
1100
  type ResourceResult<T> = {
945
1101
  state: {
946
1102
  value: T;
@@ -1080,5 +1236,88 @@ type MappedResource<Store extends Record<string, unknown>, Name extends string>
1080
1236
  */
1081
1237
  declare function mapToResource<Name extends ResourceNames<Store>, Store extends Record<string, unknown>>(store: Store, name: Name): MappedResource<Store, Name>;
1082
1238
 
1083
- export { capitalize, createEffects, createPageArray, createReducer, deriveCallStateKeys, emptyFeature, firstPage, getCallStateKeys, getCollectionArray, getDataServiceKeys, getUndoRedoKeys, gotoPage, mapToResource, nextPage, noPayload, patchState, payload, previousPage, provideDevtoolsConfig, renameDevtoolsName, setError, setLoaded, setLoading, setMaxPageNavigationArrayItems, setPageSize, setResetState, updateState, withCallState, withConditional, withDataService, withDevToolsStub, withDevtools, withDisabledNameIndices, withFeatureFactory, withGlitchTracking, withImmutableState, withIndexedDB, withIndexedDB as withIndexeddb, withLocalStorage, withMapper, withPagination, withRedux, withReset, withResource, withSessionStorage, withStorageSync, withUndoRedo };
1084
- export type { CallState, CallStateSignals, CallStateSlice, DataService, DataServiceComputed, DataServiceMethods, DataServiceState, Entity, Filter, NamedCallStateSignals, NamedCallStateSlice, NamedDataServiceComputed, NamedDataServiceMethods, NamedDataServiceState, NamedPaginationServiceSignals, NamedPaginationServiceState, NormalizedUndoRedoOptions, Page, PaginationServiceSignals, PaginationServiceState, ReduxDevtoolsConfig, SetCallState, SetPaginationState, StackItem, SyncConfig };
1239
+ type HttpMutationRequest = {
1240
+ url: string;
1241
+ method: string;
1242
+ body?: unknown;
1243
+ headers?: HttpHeaders | Record<string, string | string[]>;
1244
+ context?: HttpContext;
1245
+ reportProgress?: boolean;
1246
+ params?: HttpParams | Record<string, string | number | boolean | ReadonlyArray<string | number | boolean>>;
1247
+ withCredentials?: boolean;
1248
+ credentials?: RequestCredentials;
1249
+ keepalive?: boolean;
1250
+ priority?: RequestPriority;
1251
+ cache?: RequestCache;
1252
+ mode?: RequestMode;
1253
+ redirect?: RequestRedirect;
1254
+ transferCache?: {
1255
+ includeHeaders?: string[];
1256
+ } | boolean;
1257
+ };
1258
+ type HttpMutationOptions<Parameter, Result> = Omit<RxMutationOptions<Parameter, NoInfer<Result>>, 'operation'> & {
1259
+ request: (param: Parameter) => HttpMutationRequest;
1260
+ parse?: (response: unknown) => Result;
1261
+ };
1262
+ type HttpMutation<Parameter, Result> = Mutation<Parameter, Result> & {
1263
+ uploadProgress: Signal<HttpProgressEvent | undefined>;
1264
+ downloadProgress: Signal<HttpProgressEvent | undefined>;
1265
+ headers: Signal<HttpHeaders | undefined>;
1266
+ statusCode: Signal<string | undefined>;
1267
+ };
1268
+ /**
1269
+ * Creates an HTTP mutation.
1270
+ *
1271
+ * ```typescript
1272
+ * export type Params = {
1273
+ * value: number;
1274
+ * };
1275
+ *
1276
+ * export type CounterResponse = {
1277
+ * // httpbin.org echos the request using the
1278
+ * // json property
1279
+ * json: { counter: number };
1280
+ * };
1281
+ *
1282
+ * const simpleSaveUser = httpMutation({
1283
+ * request: (userData: AddUserEntry) => ({
1284
+ * url: 'api/users',
1285
+ * body: userData,
1286
+ * }),
1287
+ * parse: Boolean,
1288
+ * })
1289
+ *
1290
+ * const saveUser = httpMutation({
1291
+ * request: (p: Params) => ({
1292
+ * url: `https://httpbin.org/post`,
1293
+ * method: 'POST',
1294
+ * body: { counter: p.value },
1295
+ * headers: { 'Content-Type': 'application/json' },
1296
+ * }),
1297
+ * onSuccess: (response: CounterResponse) => {
1298
+ * console.log('Counter sent to server:', response);
1299
+ * },
1300
+ * onError: (error) => {
1301
+ * console.error('Failed to send counter:', error);
1302
+ * },
1303
+ * });
1304
+ *
1305
+ * const result = await this.saveUser({ value: 17 });
1306
+ * if (result.status === 'success') {
1307
+ * console.log('Successfully saved to server:', result.value);
1308
+ * }
1309
+ * else if (result.status === 'error') {
1310
+ * console.log('Failed to save:', result.error);
1311
+ * }
1312
+ * else {
1313
+ * console.log('Operation aborted');
1314
+ * }
1315
+ * ```
1316
+ *
1317
+ * @param options The options for the HTTP mutation.
1318
+ * @returns The HTTP mutation.
1319
+ */
1320
+ declare function httpMutation<Parameter, Result>(optionsOrRequest: HttpMutationOptions<Parameter, Result> | ((param: Parameter) => HttpMutationRequest)): HttpMutation<Parameter, Result>;
1321
+
1322
+ export { capitalize, concatOp, createEffects, createPageArray, createReducer, deriveCallStateKeys, emptyFeature, exhaustOp, firstPage, getCallStateKeys, getCollectionArray, getDataServiceKeys, getUndoRedoKeys, gotoPage, httpMutation, mapToResource, mergeOp, nextPage, noPayload, patchState, payload, previousPage, provideDevtoolsConfig, renameDevtoolsName, rxMutation, setError, setLoaded, setLoading, setMaxPageNavigationArrayItems, setPageSize, setResetState, switchOp, updateState, withCallState, withConditional, withDataService, withDevToolsStub, withDevtools, withDisabledNameIndices, withFeatureFactory, withGlitchTracking, withImmutableState, withIndexedDB, withIndexedDB as withIndexeddb, withLocalStorage, withMapper, withMutations, withPagination, withRedux, withReset, withResource, withSessionStorage, withStorageSync, withUndoRedo };
1323
+ export type { CallState, CallStateSignals, CallStateSlice, DataService, DataServiceComputed, DataServiceMethods, DataServiceState, Entity, Filter, HttpMutation, HttpMutationOptions, HttpMutationRequest, MethodsDictionary, NamedCallStateSignals, NamedCallStateSlice, NamedDataServiceComputed, NamedDataServiceMethods, NamedDataServiceState, NamedMutationResult, NamedPaginationServiceSignals, NamedPaginationServiceState, NormalizedUndoRedoOptions, Operation, Page, PaginationServiceSignals, PaginationServiceState, ReduxDevtoolsConfig, RxMutationOptions, SetCallState, SetPaginationState, StackItem, SyncConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-architects/ngrx-toolkit",
3
- "version": "20.1.0",
3
+ "version": "20.4.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "GitHub",