@angular-architects/ngrx-toolkit 20.3.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.
|
@@ -2,9 +2,10 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { Injectable, InjectionToken, signal, effect, inject, PLATFORM_ID, computed, isSignal, untracked, isDevMode as isDevMode$1, DestroyRef } from '@angular/core';
|
|
3
3
|
import { watchState, getState, signalStoreFeature, withMethods, withHooks, patchState as patchState$1, withState, withComputed, withProps, withLinkedState } from '@ngrx/signals';
|
|
4
4
|
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
|
|
5
|
-
import { Subject, switchMap, mergeMap, concatMap, exhaustMap, defer, tap, catchError, EMPTY, finalize } from 'rxjs';
|
|
5
|
+
import { Subject, switchMap, mergeMap, concatMap, exhaustMap, defer, tap, catchError, EMPTY, finalize, filter, map } from 'rxjs';
|
|
6
6
|
import { removeEntity, setAllEntities, updateEntity, addEntity } from '@ngrx/signals/entities';
|
|
7
7
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
8
|
+
import { HttpClient, HttpEventType, HttpResponse } from '@angular/common/http';
|
|
8
9
|
|
|
9
10
|
const DEVTOOLS_FEATURE = Symbol('DEVTOOLS_FEATURE');
|
|
10
11
|
function createDevtoolsFeature(options) {
|
|
@@ -1811,47 +1812,73 @@ const exhaustOp = {
|
|
|
1811
1812
|
*
|
|
1812
1813
|
* The `operation` is the only mandatory option.
|
|
1813
1814
|
*
|
|
1815
|
+
* The returned mutation can be called as an async function and returns a Promise.
|
|
1816
|
+
* This promise informs about whether the mutation was successful, failed, or aborted
|
|
1817
|
+
* (due to switchMap or exhaustMap semantics).
|
|
1818
|
+
*
|
|
1819
|
+
* The mutation also provides several Signals such as error, status or isPending (see below).
|
|
1820
|
+
*
|
|
1821
|
+
* Example usage without Store:
|
|
1822
|
+
*
|
|
1814
1823
|
* ```typescript
|
|
1815
|
-
*
|
|
1816
|
-
* value: number;
|
|
1817
|
-
* };
|
|
1824
|
+
* const counterSignal = signal(0);
|
|
1818
1825
|
*
|
|
1819
|
-
*
|
|
1820
|
-
*
|
|
1821
|
-
*
|
|
1822
|
-
*
|
|
1823
|
-
*
|
|
1824
|
-
*
|
|
1825
|
-
*
|
|
1826
|
-
*
|
|
1827
|
-
*
|
|
1828
|
-
*
|
|
1829
|
-
*
|
|
1830
|
-
*
|
|
1831
|
-
*
|
|
1832
|
-
*
|
|
1833
|
-
*
|
|
1834
|
-
*
|
|
1835
|
-
*
|
|
1836
|
-
*
|
|
1837
|
-
*
|
|
1826
|
+
* const increment = rxMutation({
|
|
1827
|
+
* operation: (param: Param) => {
|
|
1828
|
+
* return calcSum(this.counterSignal(), param.value);
|
|
1829
|
+
* },
|
|
1830
|
+
* operator: concatOp,
|
|
1831
|
+
* onSuccess: (result) => {
|
|
1832
|
+
* this.counterSignal.set(result);
|
|
1833
|
+
* },
|
|
1834
|
+
* onError: (error) => {
|
|
1835
|
+
* console.error('Error occurred:', error);
|
|
1836
|
+
* },
|
|
1837
|
+
* });
|
|
1838
|
+
*
|
|
1839
|
+
* const error = increment.error;
|
|
1840
|
+
* const isPending = increment.isPending;
|
|
1841
|
+
* const status = increment.status;
|
|
1842
|
+
* const value = increment.value;
|
|
1843
|
+
* const hasValue = increment.hasValue;
|
|
1844
|
+
*
|
|
1845
|
+
* async function incrementCounter() {
|
|
1846
|
+
* const result = await increment({ value: 1 });
|
|
1847
|
+
* if (result.status === 'success') {
|
|
1848
|
+
* console.log('Success:', result.value);
|
|
1849
|
+
* }
|
|
1850
|
+
* if (result.status === 'error') {
|
|
1851
|
+
* console.log('Error:', result.error);
|
|
1852
|
+
* }
|
|
1853
|
+
* if (result.status === 'aborted') {
|
|
1854
|
+
* console.log('Operation aborted');
|
|
1855
|
+
* }
|
|
1856
|
+
* }
|
|
1838
1857
|
*
|
|
1839
1858
|
* function calcSum(a: number, b: number): Observable<number> {
|
|
1840
|
-
* return of(
|
|
1859
|
+
* return of(result).pipe(delay(500));
|
|
1841
1860
|
* }
|
|
1842
1861
|
* ```
|
|
1843
1862
|
*
|
|
1844
1863
|
* @param options
|
|
1845
|
-
* @returns
|
|
1864
|
+
* @returns the actual mutation function along tracking data as properties/methods
|
|
1846
1865
|
*/
|
|
1847
|
-
function rxMutation(
|
|
1866
|
+
function rxMutation(optionsOrOperation) {
|
|
1848
1867
|
const inputSubject = new Subject();
|
|
1868
|
+
const options = typeof optionsOrOperation === 'function'
|
|
1869
|
+
? { operation: optionsOrOperation }
|
|
1870
|
+
: optionsOrOperation;
|
|
1849
1871
|
const flatteningOp = options.operator ?? concatOp;
|
|
1850
1872
|
const destroyRef = options.injector?.get(DestroyRef) ?? inject(DestroyRef);
|
|
1851
1873
|
const callCount = signal(0, ...(ngDevMode ? [{ debugName: "callCount" }] : []));
|
|
1852
1874
|
const errorSignal = signal(undefined, ...(ngDevMode ? [{ debugName: "errorSignal" }] : []));
|
|
1853
1875
|
const idle = signal(true, ...(ngDevMode ? [{ debugName: "idle" }] : []));
|
|
1854
1876
|
const isPending = computed(() => callCount() > 0, ...(ngDevMode ? [{ debugName: "isPending" }] : []));
|
|
1877
|
+
const value = signal(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
1878
|
+
const isSuccess = computed(() => !idle() && !isPending() && !errorSignal(), ...(ngDevMode ? [{ debugName: "isSuccess" }] : []));
|
|
1879
|
+
const hasValue = function () {
|
|
1880
|
+
return typeof value() !== 'undefined';
|
|
1881
|
+
};
|
|
1855
1882
|
const status = computed(() => {
|
|
1856
1883
|
if (idle()) {
|
|
1857
1884
|
return 'idle';
|
|
@@ -1866,7 +1893,6 @@ function rxMutation(options) {
|
|
|
1866
1893
|
}, ...(ngDevMode ? [{ debugName: "status" }] : []));
|
|
1867
1894
|
const initialInnerStatus = 'idle';
|
|
1868
1895
|
let innerStatus = initialInnerStatus;
|
|
1869
|
-
let lastResult;
|
|
1870
1896
|
inputSubject
|
|
1871
1897
|
.pipe(flatteningOp.rxJsOperator((input) => defer(() => {
|
|
1872
1898
|
callCount.update((c) => c + 1);
|
|
@@ -1875,10 +1901,11 @@ function rxMutation(options) {
|
|
|
1875
1901
|
options.onSuccess?.(result, input.param);
|
|
1876
1902
|
innerStatus = 'success';
|
|
1877
1903
|
errorSignal.set(undefined);
|
|
1878
|
-
|
|
1904
|
+
value.set(result);
|
|
1879
1905
|
}), catchError((error) => {
|
|
1880
1906
|
options.onError?.(error, input.param);
|
|
1881
1907
|
errorSignal.set(error);
|
|
1908
|
+
value.set(undefined);
|
|
1882
1909
|
innerStatus = 'error';
|
|
1883
1910
|
return EMPTY;
|
|
1884
1911
|
}), finalize(() => {
|
|
@@ -1886,7 +1913,7 @@ function rxMutation(options) {
|
|
|
1886
1913
|
if (innerStatus === 'success') {
|
|
1887
1914
|
input.resolve({
|
|
1888
1915
|
status: 'success',
|
|
1889
|
-
value:
|
|
1916
|
+
value: value(),
|
|
1890
1917
|
});
|
|
1891
1918
|
}
|
|
1892
1919
|
else if (innerStatus === 'error') {
|
|
@@ -1923,6 +1950,9 @@ function rxMutation(options) {
|
|
|
1923
1950
|
mutation.status = status;
|
|
1924
1951
|
mutation.isPending = isPending;
|
|
1925
1952
|
mutation.error = errorSignal;
|
|
1953
|
+
mutation.value = value;
|
|
1954
|
+
mutation.hasValue = hasValue;
|
|
1955
|
+
mutation.isSuccess = isSuccess;
|
|
1926
1956
|
return mutation;
|
|
1927
1957
|
}
|
|
1928
1958
|
|
|
@@ -2060,9 +2090,107 @@ function mapToResource(store, name) {
|
|
|
2060
2090
|
};
|
|
2061
2091
|
}
|
|
2062
2092
|
|
|
2093
|
+
/**
|
|
2094
|
+
* Creates an HTTP mutation.
|
|
2095
|
+
*
|
|
2096
|
+
* ```typescript
|
|
2097
|
+
* export type Params = {
|
|
2098
|
+
* value: number;
|
|
2099
|
+
* };
|
|
2100
|
+
*
|
|
2101
|
+
* export type CounterResponse = {
|
|
2102
|
+
* // httpbin.org echos the request using the
|
|
2103
|
+
* // json property
|
|
2104
|
+
* json: { counter: number };
|
|
2105
|
+
* };
|
|
2106
|
+
*
|
|
2107
|
+
* const simpleSaveUser = httpMutation({
|
|
2108
|
+
* request: (userData: AddUserEntry) => ({
|
|
2109
|
+
* url: 'api/users',
|
|
2110
|
+
* body: userData,
|
|
2111
|
+
* }),
|
|
2112
|
+
* parse: Boolean,
|
|
2113
|
+
* })
|
|
2114
|
+
*
|
|
2115
|
+
* const saveUser = httpMutation({
|
|
2116
|
+
* request: (p: Params) => ({
|
|
2117
|
+
* url: `https://httpbin.org/post`,
|
|
2118
|
+
* method: 'POST',
|
|
2119
|
+
* body: { counter: p.value },
|
|
2120
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
2121
|
+
* }),
|
|
2122
|
+
* onSuccess: (response: CounterResponse) => {
|
|
2123
|
+
* console.log('Counter sent to server:', response);
|
|
2124
|
+
* },
|
|
2125
|
+
* onError: (error) => {
|
|
2126
|
+
* console.error('Failed to send counter:', error);
|
|
2127
|
+
* },
|
|
2128
|
+
* });
|
|
2129
|
+
*
|
|
2130
|
+
* const result = await this.saveUser({ value: 17 });
|
|
2131
|
+
* if (result.status === 'success') {
|
|
2132
|
+
* console.log('Successfully saved to server:', result.value);
|
|
2133
|
+
* }
|
|
2134
|
+
* else if (result.status === 'error') {
|
|
2135
|
+
* console.log('Failed to save:', result.error);
|
|
2136
|
+
* }
|
|
2137
|
+
* else {
|
|
2138
|
+
* console.log('Operation aborted');
|
|
2139
|
+
* }
|
|
2140
|
+
* ```
|
|
2141
|
+
*
|
|
2142
|
+
* @param options The options for the HTTP mutation.
|
|
2143
|
+
* @returns The HTTP mutation.
|
|
2144
|
+
*/
|
|
2145
|
+
function httpMutation(optionsOrRequest) {
|
|
2146
|
+
const httpClient = inject(HttpClient);
|
|
2147
|
+
const options = typeof optionsOrRequest === 'function'
|
|
2148
|
+
? { request: optionsOrRequest }
|
|
2149
|
+
: optionsOrRequest;
|
|
2150
|
+
const parse = options.parse ?? ((raw) => raw);
|
|
2151
|
+
const uploadProgress = signal(undefined, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
|
|
2152
|
+
const downloadProgress = signal(undefined, ...(ngDevMode ? [{ debugName: "downloadProgress" }] : []));
|
|
2153
|
+
const headers = signal(undefined, ...(ngDevMode ? [{ debugName: "headers" }] : []));
|
|
2154
|
+
const statusCode = signal(undefined, ...(ngDevMode ? [{ debugName: "statusCode" }] : []));
|
|
2155
|
+
const mutation = rxMutation({
|
|
2156
|
+
...options,
|
|
2157
|
+
operation: (param) => {
|
|
2158
|
+
const httpRequest = options.request(param);
|
|
2159
|
+
return defer(() => {
|
|
2160
|
+
uploadProgress.set(undefined);
|
|
2161
|
+
downloadProgress.set(undefined);
|
|
2162
|
+
headers.set(undefined);
|
|
2163
|
+
statusCode.set(undefined);
|
|
2164
|
+
return httpClient
|
|
2165
|
+
.request(httpRequest.method, httpRequest.url, {
|
|
2166
|
+
...httpRequest,
|
|
2167
|
+
observe: 'events',
|
|
2168
|
+
responseType: 'json',
|
|
2169
|
+
})
|
|
2170
|
+
.pipe(tap((response) => {
|
|
2171
|
+
if (response.type === HttpEventType.UploadProgress) {
|
|
2172
|
+
uploadProgress.set(response);
|
|
2173
|
+
}
|
|
2174
|
+
else if (response.type === HttpEventType.DownloadProgress) {
|
|
2175
|
+
downloadProgress.set(response);
|
|
2176
|
+
}
|
|
2177
|
+
}), filter((event) => event instanceof HttpResponse), tap((response) => {
|
|
2178
|
+
headers.set(response.headers);
|
|
2179
|
+
statusCode.set(response.status.toString());
|
|
2180
|
+
}), map((event) => parse(event.body)));
|
|
2181
|
+
});
|
|
2182
|
+
},
|
|
2183
|
+
});
|
|
2184
|
+
mutation.uploadProgress = uploadProgress;
|
|
2185
|
+
mutation.downloadProgress = downloadProgress;
|
|
2186
|
+
mutation.statusCode = statusCode;
|
|
2187
|
+
mutation.headers = headers;
|
|
2188
|
+
return mutation;
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2063
2191
|
/**
|
|
2064
2192
|
* Generated bundle index. Do not edit.
|
|
2065
2193
|
*/
|
|
2066
2194
|
|
|
2067
|
-
export { capitalize, concatOp, createEffects, createPageArray, createReducer, deriveCallStateKeys, emptyFeature, exhaustOp, firstPage, getCallStateKeys, getCollectionArray, getDataServiceKeys, getUndoRedoKeys, gotoPage, 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 };
|
|
2195
|
+
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 };
|
|
2068
2196
|
//# sourceMappingURL=angular-architects-ngrx-toolkit.mjs.map
|