@ethlete/query 6.0.0-next.59 → 6.0.0-next.60
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/CHANGELOG.md +6 -0
- package/fesm2022/ethlete-query-devtools-contract.mjs +1 -6
- package/fesm2022/ethlete-query-ngrx-toolkit.mjs +371 -353
- package/fesm2022/ethlete-query-ngrx-toolkit.mjs.map +1 -1
- package/fesm2022/ethlete-query-testing.mjs +525 -612
- package/fesm2022/ethlete-query-testing.mjs.map +1 -1
- package/fesm2022/ethlete-query.mjs +13466 -18089
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/package.json +2 -2
- package/types/ethlete-query-devtools-contract.d.ts +2 -1
- package/types/ethlete-query-ngrx-toolkit.d.ts +78 -90
- package/types/ethlete-query-testing.d.ts +218 -227
- package/types/ethlete-query.d.ts +6935 -7083
- package/fesm2022/ethlete-query-devtools-contract.mjs.map +0 -1
|
@@ -1,393 +1,411 @@
|
|
|
1
|
-
import * as i0 from
|
|
2
|
-
import {
|
|
3
|
-
import { Subscription, combineLatest,
|
|
4
|
-
import { resolveQueryHeaders } from
|
|
5
|
-
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectorRef, DestroyRef, EnvironmentInjector, NgModule, Pipe, assertInInjectionContext, computed, effect, inject, isDevMode, signal, untracked } from "@angular/core";
|
|
3
|
+
import { Subject, Subscription, combineLatest, defer, distinctUntilChanged, filter, finalize, interval, map, of, startWith, takeUntil } from "rxjs";
|
|
4
|
+
import { resolveQueryHeaders } from "@ethlete/query";
|
|
6
5
|
const createToolkitPipeTransform = (options) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return state;
|
|
33
|
-
};
|
|
6
|
+
const cdr = inject(ChangeDetectorRef);
|
|
7
|
+
let subscription = Subscription.EMPTY;
|
|
8
|
+
let current = null;
|
|
9
|
+
let state = options.initialState;
|
|
10
|
+
const dispose = () => {
|
|
11
|
+
subscription.unsubscribe();
|
|
12
|
+
current = null;
|
|
13
|
+
state = options.disposedState;
|
|
14
|
+
};
|
|
15
|
+
const subscribe = (value) => {
|
|
16
|
+
current = value;
|
|
17
|
+
subscription = options.state$(value).subscribe((next) => {
|
|
18
|
+
state = next;
|
|
19
|
+
cdr.markForCheck();
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
inject(DestroyRef).onDestroy(dispose);
|
|
23
|
+
return (value) => {
|
|
24
|
+
if (!current && value) subscribe(value);
|
|
25
|
+
if (current !== value) {
|
|
26
|
+
dispose();
|
|
27
|
+
if (value) subscribe(value);
|
|
28
|
+
}
|
|
29
|
+
return state;
|
|
30
|
+
};
|
|
34
31
|
};
|
|
35
|
-
|
|
36
|
-
const noop = () => undefined;
|
|
32
|
+
const noop = () => void 0;
|
|
37
33
|
const DEFAULT_STATE = {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
args: null,
|
|
35
|
+
cachedResponse: null,
|
|
36
|
+
callState: null,
|
|
37
|
+
error: null,
|
|
38
|
+
isError: false,
|
|
39
|
+
isInit: false,
|
|
40
|
+
isLoading: false,
|
|
41
|
+
isSuccess: false,
|
|
42
|
+
response: null,
|
|
43
|
+
timestamp: null,
|
|
44
|
+
refresh: noop,
|
|
45
|
+
remove: noop,
|
|
46
|
+
startPolling: noop,
|
|
47
|
+
stopPolling: noop
|
|
52
48
|
};
|
|
53
49
|
const suspenseState$ = (handle) => combineLatest({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
args: handle.args$,
|
|
51
|
+
cachedResponse: handle.cachedResponse$.pipe(startWith(null)),
|
|
52
|
+
callState: handle.callState$,
|
|
53
|
+
error: handle.error$,
|
|
54
|
+
isError: handle.isError$,
|
|
55
|
+
isInit: handle.isInit$,
|
|
56
|
+
isLoading: handle.isLoading$,
|
|
57
|
+
isSuccess: handle.isSuccess$,
|
|
58
|
+
response: handle.response$,
|
|
59
|
+
timestamp: handle.timestamp$
|
|
64
60
|
}).pipe(map((values) => ({
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
...values,
|
|
62
|
+
refresh: handle.refresh,
|
|
63
|
+
remove: handle.remove,
|
|
64
|
+
startPolling: handle.startPolling,
|
|
65
|
+
stopPolling: handle.stopPolling
|
|
70
66
|
})));
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
67
|
+
var SuspensePipe = class SuspensePipe {
|
|
68
|
+
constructor() {
|
|
69
|
+
this.transform = createToolkitPipeTransform({
|
|
70
|
+
initialState: DEFAULT_STATE,
|
|
71
|
+
disposedState: null,
|
|
72
|
+
state$: suspenseState$
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
static {
|
|
76
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
77
|
+
minVersion: "12.0.0",
|
|
78
|
+
version: "22.2.3",
|
|
79
|
+
ngImport: i0,
|
|
80
|
+
type: SuspensePipe,
|
|
81
|
+
deps: [],
|
|
82
|
+
target: i0.ɵɵFactoryTarget.Pipe
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
static {
|
|
86
|
+
this.ɵpipe = i0.ɵɵngDeclarePipe({
|
|
87
|
+
minVersion: "14.0.0",
|
|
88
|
+
version: "22.2.3",
|
|
89
|
+
ngImport: i0,
|
|
90
|
+
type: SuspensePipe,
|
|
91
|
+
isStandalone: true,
|
|
92
|
+
name: "suspense",
|
|
93
|
+
pure: false
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
98
|
+
minVersion: "12.0.0",
|
|
99
|
+
version: "22.2.3",
|
|
100
|
+
ngImport: i0,
|
|
101
|
+
type: SuspensePipe,
|
|
102
|
+
decorators: [{
|
|
103
|
+
type: Pipe,
|
|
104
|
+
args: [{
|
|
105
|
+
name: "suspense",
|
|
106
|
+
pure: false
|
|
107
|
+
}]
|
|
108
|
+
}]
|
|
109
|
+
});
|
|
88
110
|
const suspenseMultiState$ = (handles) => combineLatest(Object.entries(handles).flatMap(([key, handle]) => handle ? [suspenseState$(handle).pipe(map((state) => [key, state]))] : [])).pipe(map((states) => Object.fromEntries(states)));
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
i0.ɵɵ
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
111
|
+
var SuspenseMultiPipe = class SuspenseMultiPipe {
|
|
112
|
+
constructor() {
|
|
113
|
+
this.transform = createToolkitPipeTransform({
|
|
114
|
+
initialState: {},
|
|
115
|
+
disposedState: {},
|
|
116
|
+
state$: suspenseMultiState$
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
static {
|
|
120
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
121
|
+
minVersion: "12.0.0",
|
|
122
|
+
version: "22.2.3",
|
|
123
|
+
ngImport: i0,
|
|
124
|
+
type: SuspenseMultiPipe,
|
|
125
|
+
deps: [],
|
|
126
|
+
target: i0.ɵɵFactoryTarget.Pipe
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
static {
|
|
130
|
+
this.ɵpipe = i0.ɵɵngDeclarePipe({
|
|
131
|
+
minVersion: "14.0.0",
|
|
132
|
+
version: "22.2.3",
|
|
133
|
+
ngImport: i0,
|
|
134
|
+
type: SuspenseMultiPipe,
|
|
135
|
+
isStandalone: true,
|
|
136
|
+
name: "suspenseMulti",
|
|
137
|
+
pure: false
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
142
|
+
minVersion: "12.0.0",
|
|
143
|
+
version: "22.2.3",
|
|
144
|
+
ngImport: i0,
|
|
145
|
+
type: SuspenseMultiPipe,
|
|
146
|
+
decorators: [{
|
|
147
|
+
type: Pipe,
|
|
148
|
+
args: [{
|
|
149
|
+
name: "suspenseMulti",
|
|
150
|
+
pure: false
|
|
151
|
+
}]
|
|
152
|
+
}]
|
|
153
|
+
});
|
|
154
|
+
var NgRxToolkitModule = class NgRxToolkitModule {
|
|
155
|
+
static {
|
|
156
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
157
|
+
minVersion: "12.0.0",
|
|
158
|
+
version: "22.2.3",
|
|
159
|
+
ngImport: i0,
|
|
160
|
+
type: NgRxToolkitModule,
|
|
161
|
+
deps: [],
|
|
162
|
+
target: i0.ɵɵFactoryTarget.NgModule
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
static {
|
|
166
|
+
this.ɵmod = i0.ɵɵngDeclareNgModule({
|
|
167
|
+
minVersion: "14.0.0",
|
|
168
|
+
version: "22.2.3",
|
|
169
|
+
ngImport: i0,
|
|
170
|
+
type: NgRxToolkitModule,
|
|
171
|
+
imports: [SuspensePipe, SuspenseMultiPipe],
|
|
172
|
+
exports: [SuspensePipe, SuspenseMultiPipe]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
static {
|
|
176
|
+
this.ɵinj = i0.ɵɵngDeclareInjector({
|
|
177
|
+
minVersion: "12.0.0",
|
|
178
|
+
version: "22.2.3",
|
|
179
|
+
ngImport: i0,
|
|
180
|
+
type: NgRxToolkitModule
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
185
|
+
minVersion: "12.0.0",
|
|
186
|
+
version: "22.2.3",
|
|
187
|
+
ngImport: i0,
|
|
188
|
+
type: NgRxToolkitModule,
|
|
189
|
+
decorators: [{
|
|
190
|
+
type: NgModule,
|
|
191
|
+
args: [{
|
|
192
|
+
imports: [SuspensePipe, SuspenseMultiPipe],
|
|
193
|
+
exports: [SuspensePipe, SuspenseMultiPipe]
|
|
194
|
+
}]
|
|
195
|
+
}]
|
|
196
|
+
});
|
|
124
197
|
const CallState = {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
198
|
+
INIT: "INIT",
|
|
199
|
+
LOADING: "LOADING",
|
|
200
|
+
SUCCESS: "SUCCESS",
|
|
201
|
+
ERROR: "ERROR"
|
|
129
202
|
};
|
|
130
|
-
|
|
131
203
|
const EMPTY_SNAPSHOT = {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
204
|
+
args: null,
|
|
205
|
+
callState: null,
|
|
206
|
+
response: null,
|
|
207
|
+
error: null,
|
|
208
|
+
timestamp: null
|
|
137
209
|
};
|
|
138
210
|
const toCallState = (state) => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
default:
|
|
145
|
-
return CallState.LOADING;
|
|
146
|
-
}
|
|
211
|
+
switch (state?.type) {
|
|
212
|
+
case "success": return CallState.SUCCESS;
|
|
213
|
+
case "failure": return CallState.ERROR;
|
|
214
|
+
default: return CallState.LOADING;
|
|
215
|
+
}
|
|
147
216
|
};
|
|
148
217
|
const toToolkitError = (error) => ({
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
218
|
+
status: error.raw.status,
|
|
219
|
+
message: error.raw.message,
|
|
220
|
+
data: error.raw.error ?? null
|
|
152
221
|
});
|
|
153
|
-
const handleReleasedMessage = (method) => `${method}() was called on a toolkit handle that a newer toolkitCall() released. Args that cannot be hashed
|
|
154
|
-
`(FormData, Blob, Map, ...) never share a handle, so the next call for the same creator releases the previous ` +
|
|
155
|
-
`handle once its request settles. The call was ignored - call toolkitCall() again with the args instead of ` +
|
|
156
|
-
`reusing the old handle. This warning is shown once per handle.`;
|
|
222
|
+
const handleReleasedMessage = (method) => `${method}() was called on a toolkit handle that a newer toolkitCall() released. Args that cannot be hashed (FormData, Blob, Map, ...) never share a handle, so the next call for the same creator releases the previous handle once its request settles. The call was ignored - call toolkitCall() again with the args instead of reusing the old handle. This warning is shown once per handle.`;
|
|
157
223
|
const toQueryArgs = (args) => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
queryArgs['body'] = args['body'];
|
|
166
|
-
if (actionOptions?.headers !== undefined)
|
|
167
|
-
queryArgs['headers'] = actionOptions.headers;
|
|
168
|
-
return queryArgs;
|
|
224
|
+
const actionOptions = args["actionOptions"];
|
|
225
|
+
const queryArgs = {};
|
|
226
|
+
if (args["queryParams"] !== void 0) queryArgs["pathParams"] = args["queryParams"];
|
|
227
|
+
if (args["params"] !== void 0) queryArgs["queryParams"] = args["params"];
|
|
228
|
+
if (args["body"] !== void 0) queryArgs["body"] = args["body"];
|
|
229
|
+
if (actionOptions?.headers !== void 0) queryArgs["headers"] = actionOptions.headers;
|
|
230
|
+
return queryArgs;
|
|
169
231
|
};
|
|
170
232
|
const createToolkitHandle = (creator, injector) => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
233
|
+
const query = creator({
|
|
234
|
+
injector,
|
|
235
|
+
onlyManualExecution: true,
|
|
236
|
+
silenceMissingWithArgsFeatureError: true
|
|
237
|
+
});
|
|
238
|
+
const calledArgs = signal(null, ...ngDevMode ? [{ debugName: "calledArgs" }] : /* istanbul ignore next */ []);
|
|
239
|
+
const toolkitError = computed(() => {
|
|
240
|
+
const error = query.error();
|
|
241
|
+
return error ? toToolkitError(error) : null;
|
|
242
|
+
}, ...ngDevMode ? [{ debugName: "toolkitError" }] : /* istanbul ignore next */ []);
|
|
243
|
+
const snapshot = computed(() => {
|
|
244
|
+
const currentArgs = calledArgs();
|
|
245
|
+
if (!currentArgs) return EMPTY_SNAPSHOT;
|
|
246
|
+
const state = query.executionState();
|
|
247
|
+
const callState = toCallState(state);
|
|
248
|
+
return {
|
|
249
|
+
args: currentArgs,
|
|
250
|
+
callState,
|
|
251
|
+
response: state?.type === "success" ? state.response : null,
|
|
252
|
+
error: callState === CallState.ERROR ? toolkitError() : null,
|
|
253
|
+
timestamp: Date.now()
|
|
254
|
+
};
|
|
255
|
+
}, ...ngDevMode ? [{ debugName: "snapshot" }] : /* istanbul ignore next */ []);
|
|
256
|
+
const changes = new Subject();
|
|
257
|
+
const changesEffect = effect(() => {
|
|
258
|
+
const current = snapshot();
|
|
259
|
+
untracked(() => changes.next(current));
|
|
260
|
+
}, {
|
|
261
|
+
...ngDevMode ? { debugName: "changesEffect" } : /* istanbul ignore next */ {},
|
|
262
|
+
injector
|
|
263
|
+
});
|
|
264
|
+
let releasedSnapshot = null;
|
|
265
|
+
let warnedAboutRelease = false;
|
|
266
|
+
const ignoredAfterRelease = (method) => {
|
|
267
|
+
if (!releasedSnapshot) return false;
|
|
268
|
+
if (isDevMode() && !warnedAboutRelease) {
|
|
269
|
+
warnedAboutRelease = true;
|
|
270
|
+
console.warn(handleReleasedMessage(method));
|
|
271
|
+
}
|
|
272
|
+
return true;
|
|
273
|
+
};
|
|
274
|
+
const select = (pick) => defer(() => releasedSnapshot ? of(releasedSnapshot) : changes.pipe(startWith(untracked(snapshot)))).pipe(map(pick), distinctUntilChanged());
|
|
275
|
+
const call = (args) => {
|
|
276
|
+
calledArgs.set(args);
|
|
277
|
+
query.execute({ args: toQueryArgs(args) });
|
|
278
|
+
};
|
|
279
|
+
const refresh = () => {
|
|
280
|
+
if (ignoredAfterRelease("refresh")) return;
|
|
281
|
+
const lastArgs = untracked(calledArgs);
|
|
282
|
+
if (lastArgs) call(lastArgs);
|
|
283
|
+
};
|
|
284
|
+
let pollingSubscription = Subscription.EMPTY;
|
|
285
|
+
const stopPolling = () => pollingSubscription.unsubscribe();
|
|
286
|
+
const startPolling = ({ intervalDuration, killSwitch }) => {
|
|
287
|
+
if (ignoredAfterRelease("startPolling") || !pollingSubscription.closed) return;
|
|
288
|
+
pollingSubscription = interval(intervalDuration).pipe(takeUntil(killSwitch), finalize(() => pollingSubscription = Subscription.EMPTY)).subscribe(() => refresh());
|
|
289
|
+
};
|
|
290
|
+
const remove = () => {
|
|
291
|
+
stopPolling();
|
|
292
|
+
calledArgs.set(null);
|
|
293
|
+
query.reset();
|
|
294
|
+
};
|
|
295
|
+
const removeDestroyListener = injector.get(DestroyRef).onDestroy(() => {
|
|
296
|
+
stopPolling();
|
|
297
|
+
changes.complete();
|
|
298
|
+
});
|
|
299
|
+
const release = () => {
|
|
300
|
+
releasedSnapshot = untracked(snapshot);
|
|
301
|
+
stopPolling();
|
|
302
|
+
changesEffect.destroy();
|
|
303
|
+
removeDestroyListener();
|
|
304
|
+
changes.complete();
|
|
305
|
+
query.subtle.destroy();
|
|
306
|
+
};
|
|
307
|
+
const releaseWhenSettled = () => {
|
|
308
|
+
const releaseEffect = effect(() => {
|
|
309
|
+
if (snapshot().callState === CallState.LOADING) return;
|
|
310
|
+
releaseEffect.destroy();
|
|
311
|
+
untracked(release);
|
|
312
|
+
}, {
|
|
313
|
+
...ngDevMode ? { debugName: "releaseEffect" } : /* istanbul ignore next */ {},
|
|
314
|
+
injector
|
|
315
|
+
});
|
|
316
|
+
};
|
|
317
|
+
const response$ = select((current) => current.response);
|
|
318
|
+
return {
|
|
319
|
+
handle: {
|
|
320
|
+
response$,
|
|
321
|
+
cachedResponse$: response$.pipe(filter((response) => !!response)),
|
|
322
|
+
error$: select((current) => current.error),
|
|
323
|
+
args$: select((current) => current.args),
|
|
324
|
+
isInit$: select((current) => current.callState === CallState.INIT),
|
|
325
|
+
isLoading$: select((current) => current.callState === CallState.LOADING),
|
|
326
|
+
isSuccess$: select((current) => current.callState === CallState.SUCCESS),
|
|
327
|
+
isError$: select((current) => current.callState === CallState.ERROR),
|
|
328
|
+
timestamp$: select((current) => current.timestamp),
|
|
329
|
+
callState$: select((current) => current.callState),
|
|
330
|
+
refresh,
|
|
331
|
+
remove,
|
|
332
|
+
startPolling,
|
|
333
|
+
stopPolling
|
|
334
|
+
},
|
|
335
|
+
call,
|
|
336
|
+
releaseWhenSettled
|
|
337
|
+
};
|
|
274
338
|
};
|
|
275
|
-
|
|
276
339
|
const registries = /* @__PURE__ */ new WeakMap();
|
|
277
|
-
|
|
278
|
-
}
|
|
340
|
+
var UnhashableValueError = class extends Error {};
|
|
279
341
|
const isPlainObject = (value) => {
|
|
280
|
-
|
|
281
|
-
|
|
342
|
+
const prototype = Object.getPrototypeOf(value);
|
|
343
|
+
return prototype === Object.prototype || prototype === null;
|
|
282
344
|
};
|
|
283
345
|
const hashableValue = (value) => {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return { '\u0000date': value.getTime() };
|
|
290
|
-
if (!isPlainObject(value))
|
|
291
|
-
throw new UnhashableValueError();
|
|
292
|
-
return Object.fromEntries(Object.keys(value)
|
|
293
|
-
.sort()
|
|
294
|
-
.map((key) => [key, hashableValue(value[key])]));
|
|
346
|
+
if (Array.isArray(value)) return value.map(hashableValue);
|
|
347
|
+
if (typeof value !== "object" || value === null) return value;
|
|
348
|
+
if (value instanceof Date) return { "\0date": value.getTime() };
|
|
349
|
+
if (!isPlainObject(value)) throw new UnhashableValueError();
|
|
350
|
+
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, hashableValue(value[key])]));
|
|
295
351
|
};
|
|
296
352
|
const hashableHeaders = (headers) => {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
?.keys()
|
|
300
|
-
.map((name) => name.toLowerCase())
|
|
301
|
-
.sort()
|
|
302
|
-
.map((name) => [name, resolved.getAll(name)]);
|
|
353
|
+
const resolved = resolveQueryHeaders(headers);
|
|
354
|
+
return resolved?.keys().map((name) => name.toLowerCase()).sort().map((name) => [name, resolved.getAll(name)]);
|
|
303
355
|
};
|
|
304
|
-
/**
|
|
305
|
-
* Returns `null` for args holding a value JSON cannot represent (FormData, Blob, Map, ...). Those never share a handle,
|
|
306
|
-
* and each one is released once the next one for the same creator starts and its own call has settled.
|
|
307
|
-
*/
|
|
308
356
|
const hashArgs = (args) => {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
throw error;
|
|
317
|
-
}
|
|
357
|
+
const { headers, ...rest } = args;
|
|
358
|
+
try {
|
|
359
|
+
return JSON.stringify([hashableValue(rest), hashableHeaders(headers) ?? null]);
|
|
360
|
+
} catch (error) {
|
|
361
|
+
if (error instanceof UnhashableValueError) return null;
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
318
364
|
};
|
|
319
365
|
const resolveEnvironmentInjector = (fn, options) => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
return inject(EnvironmentInjector);
|
|
366
|
+
if (options?.injector) return options.injector.get(EnvironmentInjector);
|
|
367
|
+
assertInInjectionContext(fn);
|
|
368
|
+
return inject(EnvironmentInjector);
|
|
324
369
|
};
|
|
325
370
|
const resolveEntry = (creator, args, injector) => {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
371
|
+
let registry = registries.get(injector);
|
|
372
|
+
if (!registry) {
|
|
373
|
+
registry = {
|
|
374
|
+
shared: /* @__PURE__ */ new WeakMap(),
|
|
375
|
+
latestUnshared: /* @__PURE__ */ new WeakMap()
|
|
376
|
+
};
|
|
377
|
+
registries.set(injector, registry);
|
|
378
|
+
}
|
|
379
|
+
const key = hashArgs(toQueryArgs(args));
|
|
380
|
+
if (key === null) {
|
|
381
|
+
const entry = createToolkitHandle(creator, injector);
|
|
382
|
+
registry.latestUnshared.get(creator)?.releaseWhenSettled();
|
|
383
|
+
registry.latestUnshared.set(creator, entry);
|
|
384
|
+
return entry;
|
|
385
|
+
}
|
|
386
|
+
let entries = registry.shared.get(creator);
|
|
387
|
+
if (!entries) {
|
|
388
|
+
entries = /* @__PURE__ */ new Map();
|
|
389
|
+
registry.shared.set(creator, entries);
|
|
390
|
+
}
|
|
391
|
+
let entry = entries.get(key);
|
|
392
|
+
if (!entry) {
|
|
393
|
+
entry = createToolkitHandle(creator, injector);
|
|
394
|
+
entries.set(key, entry);
|
|
395
|
+
}
|
|
396
|
+
return entry;
|
|
349
397
|
};
|
|
350
|
-
/**
|
|
351
|
-
* Returns the handle for a creator and args without executing it - the `FacadeBase.select(group, actionId)` of
|
|
352
|
-
* `@tomtomb/ngrx-toolkit`. Args that build the same request (in any key order, other keys ignored) give the same
|
|
353
|
-
* handle `toolkitCall` returns, so `toolkitSelect(getTeam, args, { injector }).refresh()` re-runs a request another
|
|
354
|
-
* component started.
|
|
355
|
-
*/
|
|
356
398
|
const toolkitSelect = (creator, args, options) => resolveEntry(creator, args, resolveEnvironmentInjector(toolkitSelect, options)).handle;
|
|
357
|
-
/**
|
|
358
|
-
* Executes a query creator with toolkit-shaped args and returns its handle - the `FacadeBase.call(group, args)` of
|
|
359
|
-
* `@tomtomb/ngrx-toolkit`. Every call sends the request again, unless one with equal args is still in flight, which it
|
|
360
|
-
* joins; equal args return the same handle, which lives as long as the injector.
|
|
361
|
-
*
|
|
362
|
-
* @example
|
|
363
|
-
* ```ts
|
|
364
|
-
* @Injectable({ providedIn: 'root' })
|
|
365
|
-
* export class TeamFacade {
|
|
366
|
-
* private injector = inject(Injector);
|
|
367
|
-
*
|
|
368
|
-
* getTeam(args: ActionCallArgs<typeof getTeam>) {
|
|
369
|
-
* return toolkitCall(getTeam, args, { injector: this.injector });
|
|
370
|
-
* }
|
|
371
|
-
* }
|
|
372
|
-
* ```
|
|
373
|
-
*/
|
|
374
399
|
const toolkitCall = (creator, args, options) => {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
400
|
+
const entry = resolveEntry(creator, args, resolveEnvironmentInjector(toolkitCall, options));
|
|
401
|
+
entry.call(args);
|
|
402
|
+
return entry.handle;
|
|
378
403
|
};
|
|
379
|
-
|
|
380
|
-
/** Emits `true` while any of the given loading streams is `true`. Nullish entries are skipped. */
|
|
381
404
|
const joinLoading = (observables) => combineLatest(observables.filter((o) => !!o)).pipe(map((values) => values.some((value) => !!value)));
|
|
382
|
-
/** Emits every non-null error of the given error streams, or `null` when there is none. Nullish entries are skipped. */
|
|
383
405
|
const joinErrors = (observables) => combineLatest(observables.filter((o) => !!o)).pipe(map((values) => {
|
|
384
|
-
|
|
385
|
-
|
|
406
|
+
const errors = values.filter((value) => !!value);
|
|
407
|
+
return errors.length ? errors : null;
|
|
386
408
|
}));
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Generated bundle index. Do not edit.
|
|
390
|
-
*/
|
|
391
|
-
|
|
392
409
|
export { CallState, NgRxToolkitModule, SuspenseMultiPipe, SuspensePipe, joinErrors, joinLoading, toolkitCall, toolkitSelect };
|
|
393
|
-
|
|
410
|
+
|
|
411
|
+
//# sourceMappingURL=ethlete-query-ngrx-toolkit.mjs.map
|