@ethlete/query 6.0.0-next.53 → 6.0.0-next.54
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 +10 -0
- package/fesm2022/ethlete-query.mjs +68 -15
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ethlete-query.d.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @ethlete/query
|
|
2
2
|
|
|
3
|
+
## 6.0.0-next.54
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Stop a legacy `InfinityQuery` from aborting a non-cacheable page (such as a POST) that is still loading when it is reset or destroyed; the page now finishes and is destroyed once it settles.
|
|
8
|
+
- A legacy query container or collection destroyed while its mutation is in flight now lets the request finish instead of cancelling it.
|
|
9
|
+
- An interop mutation whose prepare injector is destroyed while its request is in flight now finishes before it is destroyed, as it did in v2.
|
|
10
|
+
- Destroying the owner of a legacy mutation that waits to settle after its container let go no longer throws NG0205.
|
|
11
|
+
- A mutation whose `withArgs` source returns `null` while its request is in flight is no longer aborted; it finishes and the query parks once it has settled.
|
|
12
|
+
|
|
3
13
|
## 6.0.0-next.53
|
|
4
14
|
|
|
5
15
|
### Major Changes
|
|
@@ -1186,7 +1186,7 @@ const setupQueryDependencies = (options) => {
|
|
|
1186
1186
|
const clientToken = options.client.token;
|
|
1187
1187
|
const dependencies = {
|
|
1188
1188
|
destroyRef: undefined, // Will be set after injector creation
|
|
1189
|
-
scopeDestroyRef: hostInjector.get(DestroyRef),
|
|
1189
|
+
scopeDestroyRef: options.queryConfig?.scopeDestroyRef ?? hostInjector.get(DestroyRef),
|
|
1190
1190
|
client: hostInjector.get(clientToken),
|
|
1191
1191
|
injector: undefined, // Will be set after injector creation
|
|
1192
1192
|
ngErrorHandler: hostInjector.get(ErrorHandler),
|
|
@@ -1457,7 +1457,8 @@ const createQueryFeature = (config) => {
|
|
|
1457
1457
|
* The arguments are read within a computed function, so you can use reactive values.
|
|
1458
1458
|
*
|
|
1459
1459
|
* Return `null` to park the query: it is reset (`response()` and `executionState()` become `null`),
|
|
1460
|
-
* and polling and auto refresh pause until args are set again.
|
|
1460
|
+
* and polling and auto refresh pause until args are set again. A mutation that is still in flight
|
|
1461
|
+
* finishes first and the query parks once it has settled.
|
|
1461
1462
|
*
|
|
1462
1463
|
* Changing arguments will automatically trigger a new execution of the query if it is eligible for auto execution (e.g. a GET request).
|
|
1463
1464
|
*/
|
|
@@ -1474,6 +1475,8 @@ const withArgs = (args) => {
|
|
|
1474
1475
|
nestedEffect(() => {
|
|
1475
1476
|
const currArgsNow = context.state.args();
|
|
1476
1477
|
if (currArgsNow === null) {
|
|
1478
|
+
if (!context.flags.shouldAutoExecuteMethod && context.state.loading() !== null)
|
|
1479
|
+
return;
|
|
1477
1480
|
untracked(() => {
|
|
1478
1481
|
if (context.state.subtle.request() !== null || context.state.loading() !== null)
|
|
1479
1482
|
context.execute.reset();
|
|
@@ -2495,7 +2498,10 @@ const trackRefreshedExecutions = (options) => {
|
|
|
2495
2498
|
};
|
|
2496
2499
|
const createQueryObject = (options) => {
|
|
2497
2500
|
const { state, execute, deps } = options;
|
|
2498
|
-
const destroy = () =>
|
|
2501
|
+
const destroy = () => {
|
|
2502
|
+
if (!deps.injector.destroyed)
|
|
2503
|
+
deps.injector.destroy();
|
|
2504
|
+
};
|
|
2499
2505
|
const setResponse = (response) => state.response.set(response);
|
|
2500
2506
|
const setLoading = (loading) => state.loading.set(loading);
|
|
2501
2507
|
const setError = (error) => state.error.set(error);
|
|
@@ -10976,7 +10982,7 @@ const withQueryDevtoolsOverridePersistence = (id, recorder) => {
|
|
|
10976
10982
|
|
|
10977
10983
|
// Generated from package.json by tools/scripts/generate-version.js - do not edit.
|
|
10978
10984
|
/** The version of `@ethlete/query` this build was cut from. */
|
|
10979
|
-
const QUERY_VERSION = '6.0.0-next.
|
|
10985
|
+
const QUERY_VERSION = '6.0.0-next.54';
|
|
10980
10986
|
|
|
10981
10987
|
/** How deep a schema is expanded before a nested branch is given up on. */
|
|
10982
10988
|
const MAX_DEPTH = 12;
|
|
@@ -13059,6 +13065,15 @@ const request = (config) => {
|
|
|
13059
13065
|
});
|
|
13060
13066
|
};
|
|
13061
13067
|
|
|
13068
|
+
/**
|
|
13069
|
+
* Destroying a legacy query tears down the underlying query's injector, which cancels its request - so
|
|
13070
|
+
* a superseded or released query that was not aborted (a mutation the server may already have accepted)
|
|
13071
|
+
* is torn down only once it has settled. `state$` completes with the query, so this ends either way.
|
|
13072
|
+
*/
|
|
13073
|
+
const destroyOnceSettled = (query) => {
|
|
13074
|
+
query.state$.pipe(takeUntilResponse()).subscribe({ complete: () => query.destroy() });
|
|
13075
|
+
};
|
|
13076
|
+
|
|
13062
13077
|
let nextQueryContainerOwnerId = 0;
|
|
13063
13078
|
const queryContainerOwnerIds = /* @__PURE__ */ new WeakMap();
|
|
13064
13079
|
const queryContainerOwnerId = (injector) => {
|
|
@@ -13070,14 +13085,6 @@ const queryContainerOwnerId = (injector) => {
|
|
|
13070
13085
|
queryContainerOwnerIds.set(injector, id);
|
|
13071
13086
|
return id;
|
|
13072
13087
|
};
|
|
13073
|
-
/**
|
|
13074
|
-
* Destroying a legacy query tears down the underlying query's injector, which cancels its request - so
|
|
13075
|
-
* a superseded query that was not aborted (a mutation the server may already have accepted) is torn
|
|
13076
|
-
* down only once it has settled. `state$` completes with the query, so this ends either way.
|
|
13077
|
-
*/
|
|
13078
|
-
const destroyOnceSettled = (query) => {
|
|
13079
|
-
query.state$.pipe(takeUntilResponse()).subscribe({ complete: () => query.destroy() });
|
|
13080
|
-
};
|
|
13081
13088
|
/**
|
|
13082
13089
|
* @deprecated Part of the legacy (v2) query system. Migrate to the current query API - see https://ethlete-sdk-docs.web.app/query/migrating-from-v2, and run `nx g @ethlete/query:migrate-to-query-v3` to rewrite the mechanical parts. Intent to remove in v7.
|
|
13083
13090
|
*/
|
|
@@ -13153,7 +13160,14 @@ const addQueryContainerHandling = (obs, valueFn, config) => {
|
|
|
13153
13160
|
if ((q?.canBeCached && abortOnDestroy === undefined) || abortOnDestroy) {
|
|
13154
13161
|
q?.abort();
|
|
13155
13162
|
}
|
|
13156
|
-
q
|
|
13163
|
+
const legacyQuery = q;
|
|
13164
|
+
if (!legacyQuery?.destroy)
|
|
13165
|
+
return;
|
|
13166
|
+
if (isQueryStateLoading(q?.rawState)) {
|
|
13167
|
+
destroyOnceSettled(legacyQuery);
|
|
13168
|
+
return;
|
|
13169
|
+
}
|
|
13170
|
+
legacyQuery.destroy();
|
|
13157
13171
|
};
|
|
13158
13172
|
if (isQuery(query)) {
|
|
13159
13173
|
handleQuery(query);
|
|
@@ -14204,6 +14218,35 @@ const isInjectorUsable = (injector) => {
|
|
|
14204
14218
|
return false;
|
|
14205
14219
|
}
|
|
14206
14220
|
};
|
|
14221
|
+
/**
|
|
14222
|
+
* The scope ends when its owner dies with no request in flight, when that request settles, or when the
|
|
14223
|
+
* owner's nearest environment injector dies - a destroyed injector does not destroy the environment
|
|
14224
|
+
* injectors made with `createEnvironmentInjector` below it.
|
|
14225
|
+
*/
|
|
14226
|
+
const createSettleScope = (owner) => {
|
|
14227
|
+
const anchor = owner.get(EnvironmentInjector);
|
|
14228
|
+
const scope = createEnvironmentInjector([], anchor);
|
|
14229
|
+
const end = () => {
|
|
14230
|
+
if (!scope.destroyed)
|
|
14231
|
+
scope.destroy();
|
|
14232
|
+
};
|
|
14233
|
+
const bind = (query, queryInjector) => {
|
|
14234
|
+
const stopOnAnchorDestroy = anchor.get(DestroyRef).onDestroy(end);
|
|
14235
|
+
const stopOnOwnerDestroy = owner.get(DestroyRef).onDestroy(() => {
|
|
14236
|
+
if (isQueryStateLoading(untracked(() => query.rawState))) {
|
|
14237
|
+
query.state$.pipe(takeUntilResponse()).subscribe({ complete: end });
|
|
14238
|
+
return;
|
|
14239
|
+
}
|
|
14240
|
+
end();
|
|
14241
|
+
});
|
|
14242
|
+
queryInjector.get(DestroyRef).onDestroy(() => {
|
|
14243
|
+
stopOnAnchorDestroy();
|
|
14244
|
+
stopOnOwnerDestroy();
|
|
14245
|
+
end();
|
|
14246
|
+
});
|
|
14247
|
+
};
|
|
14248
|
+
return { destroyRef: scope.get(DestroyRef), bind };
|
|
14249
|
+
};
|
|
14207
14250
|
/**
|
|
14208
14251
|
* Angular's NG0203, thrown by `inject()` outside an injection context. Matched on the code rather than
|
|
14209
14252
|
* the message: production builds strip the message, and NG0205 ("Injector has already been destroyed")
|
|
@@ -14278,14 +14321,17 @@ class LegacyQueryCreator {
|
|
|
14278
14321
|
}
|
|
14279
14322
|
return runInInjectionContext(injector, () => {
|
|
14280
14323
|
return untracked(() => {
|
|
14324
|
+
const settleScope = this.canBeCached ? null : createSettleScope(injector);
|
|
14281
14325
|
const newQuery = this.options.creator({
|
|
14282
14326
|
onlyManualExecution: true,
|
|
14283
14327
|
injector,
|
|
14328
|
+
...(settleScope ? { scopeDestroyRef: settleScope.destroyRef } : {}),
|
|
14284
14329
|
silenceMissingWithArgsFeatureError: true,
|
|
14285
14330
|
// `LegacyQuery.execute()` forwards v2's `skipCache` as `allowCache` for every method, cacheable or not.
|
|
14286
14331
|
silenceUncacheableAllowCacheError: true,
|
|
14287
14332
|
});
|
|
14288
14333
|
const legacyQuery = new LegacyQuery(newQuery, queryArgs, this.options.entity, false, this.canBeCached);
|
|
14334
|
+
settleScope?.bind(legacyQuery, newQuery.subtle.injector);
|
|
14289
14335
|
if (args?.config?.destroyOnResponse) {
|
|
14290
14336
|
// Owned by the query's own injector, not the caller's. Call sites are told to pass an injector
|
|
14291
14337
|
// that outlives them, so they hand over a root or environment one - and an effect that only
|
|
@@ -15490,9 +15536,16 @@ class InfinityQuery {
|
|
|
15490
15536
|
destroyQueries() {
|
|
15491
15537
|
for (const query of this.queries$.value) {
|
|
15492
15538
|
query.stopPolling();
|
|
15493
|
-
query.
|
|
15494
|
-
|
|
15539
|
+
if (query.canBeCached)
|
|
15540
|
+
query.abort();
|
|
15541
|
+
if (!('destroy' in query) || typeof query.destroy !== 'function')
|
|
15542
|
+
continue;
|
|
15543
|
+
if (!query.canBeCached && isQueryStateLoading(query.rawState)) {
|
|
15544
|
+
destroyOnceSettled(query);
|
|
15545
|
+
}
|
|
15546
|
+
else {
|
|
15495
15547
|
query.destroy();
|
|
15548
|
+
}
|
|
15496
15549
|
}
|
|
15497
15550
|
}
|
|
15498
15551
|
prepareArgs(config, page) {
|