@ethlete/query 6.0.0-next.61 → 6.0.0-next.63
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 +60 -0
- package/fesm2022/ethlete-query-devtools-contract.mjs +1 -1
- package/fesm2022/ethlete-query-ngrx-toolkit.mjs +30 -7
- package/fesm2022/ethlete-query-ngrx-toolkit.mjs.map +1 -1
- package/fesm2022/ethlete-query.mjs +183 -43
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/generators/migrate-from-ngrx-toolkit/args-assignability.js +55 -8
- package/generators/migrate-from-ngrx-toolkit/consumers.js +133 -37
- package/generators/migrate-from-ngrx-toolkit/creators.js +8 -4
- package/generators/migrate-from-ngrx-toolkit/feature.js +31 -4
- package/generators/migrate-from-ngrx-toolkit/migration.js +3 -1
- package/generators/migrate-from-ngrx-toolkit/module-resolution.js +23 -0
- package/generators/migrate-from-ngrx-toolkit/store-removal.js +64 -11
- package/generators/migrate-to-query-v3/auth-consumers-migration.js +64 -0
- package/generators/migrate-to-query-v3/auth-provider-scaffold.js +93 -1
- package/generators/migrate-to-query-v3/cleanup-migration.js +135 -15
- package/generators/migrate-to-query-v3/legacy-prepare-migration.js +275 -27
- package/generators/migrate-to-query-v3/legacy-query-creator-migration.js +171 -25
- package/generators/migrate-to-query-v3/migration.js +9 -3
- package/generators/migrate-to-query-v3/module-resolution.js +131 -0
- package/generators/migrate-to-query-v3/query-client-migration.js +82 -14
- package/generators/migrate-to-query-v3/rename-symbols.js +16 -11
- package/generators/move-devtools-contract-imports/moved-names.js +1 -0
- package/migrations.json +10 -0
- package/package.json +1 -1
- package/types/ethlete-query-devtools-contract.d.ts +2 -2
- package/types/ethlete-query-ngrx-toolkit.d.ts +13 -0
- package/types/ethlete-query.d.ts +40 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# @ethlete/query
|
|
2
2
|
|
|
3
|
+
## 6.0.0-next.63
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- `provideQueryDevtools({ ui: () => import('@ethlete/query-devtools/lazy') })` mounts the devtools once the app has rendered, with no template tag. `@ethlete/query-devtools/lazy` exports `mountQueryDevtools`.
|
|
8
|
+
- The `migrate-from-ngrx-toolkit` generator rewrites `facade.on(x.success)` on a migrated facade to `toolkitOnSuccess(x)`.
|
|
9
|
+
- The ngrx-toolkit interop adds `toolkitOnSuccess(creatorOrCreators)`, which emits the response on every success of a `toolkitCall` handle of those creators - the replacement for `facade.on(action.success)`.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- `migrate-to-query-v3` writes `provideQueryDevtools({ ui })` and removes the v2 devtools tag and component import. Without a legacy provider call it still switches to the lazy component.
|
|
14
|
+
- The ET800 error names the query's route and says that repeated `execute({ skipCache: true })` calls count, e.g. a test that fakes responses in a tight loop.
|
|
15
|
+
- The v3 migration names every `gqlQuery` and `gqlMutate` call in a task, also on an aliased client, in a class property or
|
|
16
|
+
inside a function, and warns about the implicit-any errors (TS7006) they leave.
|
|
17
|
+
- A legacy `prepare()` on `createLegacyQueryCreator` queries now honours its `mock` argument: the query settles with the mock response or error after the delay and reports its progress.
|
|
18
|
+
- A legacy query from `createLegacyQueryCreator` types `rawState` with the response of the wrapped creator again, not `unknown`. Templates that read it, such as `*etInfinityQuery`, typecheck again.
|
|
19
|
+
- A subscriber that attaches to a legacy query's `state$` right after `execute()` no longer receives the previous `Success` after `Loading`, so `filterSuccess(), take(1)` waits for the new response.
|
|
20
|
+
- The query v3 migration now casts the `responseAdapter` result in the scaffolded `extractTokens`, so the generated code no longer fails with TS2339 on `token`.
|
|
21
|
+
- The `migrate-to-query-v3` report now flags a legacy `<et-query-devtools>`, `QueryDevtoolsComponent` or `provideQueryClientForDevtools` that the migration left behind.
|
|
22
|
+
- The `migrate-from-ngrx-toolkit` generator no longer leaves a whole consumer file on the toolkit when it also names converted creators.
|
|
23
|
+
- `migrate-from-ngrx-toolkit` reuses a creator whose args name the same branded type, and `NTK-DUPLICATE-ROUTE-MISMATCH` names the member that differs and where both types are declared.
|
|
24
|
+
- The `NTK-SERVICE-HEADERS` task of the `migrate-from-ngrx-toolkit` generator now names the headers, the service property they come from, and the condition the service set them under, with the line of the request.
|
|
25
|
+
- The `migrate-from-ngrx-toolkit` generator no longer keeps a whole feature store when code outside the feature uses only its service. It keeps the used file and the store files it imports, converts the rest, and names each kept file in `NTK-STORE-FILE-KEPT`.
|
|
26
|
+
- `migrate-from-ngrx-toolkit`: `NTK-MODULE-RESOLUTION` now also flags a project that resolves modules with `node` and reaches a file importing `@ethlete/query/ngrx-toolkit` through a workspace `paths` alias, and names that alias.
|
|
27
|
+
- `migrate-from-ngrx-toolkit` records an `NTK-MODULE-RESOLUTION` task for each project tsconfig that resolves modules with `node`, which cannot find `@ethlete/query/ngrx-toolkit`.
|
|
28
|
+
- `migrate-to-query-v3` now migrates a creator declared next to its client, adds `destroyOnResponse` to `prepare()` inside async validators returned by a factory, and drops imports the devtools and `queryComputed` rewrites leave unused.
|
|
29
|
+
- `migrate-to-query-v3` reports every tsconfig that resolves modules with `node` while its project imports an `@ethlete/*` subpath such as `@ethlete/query-devtools/lazy`, directly or through a `paths` alias.
|
|
30
|
+
|
|
31
|
+
## 6.0.0-next.62
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Add the manifest field `addsWhenFound`: `et update` adds a package only when a `.ts` file names one of the listed identifiers. The `to-query-v3` migration adds `@ethlete/query-devtools` only for repos that use `QueryDevtoolsComponent`.
|
|
36
|
+
- A migration can list `adds`, packages its codemod imports. `et update` adds a missing one before the codemod, and `to-query-v3` adds `@ethlete/query-devtools`.
|
|
37
|
+
- A migrated query writes its response to the entity store before `onSuccess` and `state$` subscribers see the success.
|
|
38
|
+
- `migrate-to-query-v3` turns a plain `computed` that returns a prepared query into `queryComputed`, and adds `destroyOnResponse` to a `prepare()` in an async validator.
|
|
39
|
+
- `migrate-to-query-v3` adds the injector member before the leading comments of the first class member, so an `eslint-disable-next-line` comment stays on its member.
|
|
40
|
+
- `et migrations` now lists `migrate-create-destroy`, `migrate-color-theme-variants` and `migrate-from-ngrx-toolkit`, all at level `optional`.
|
|
41
|
+
- The v2 migration adds `destroyOnResponse` only to a query that is provably one-shot, so a stored, returned or re-executed query keeps working after its first response.
|
|
42
|
+
- The v2 migration writes `reportErrors: false` into migrated creators and copies `cookieDomain` into `cookie.domain`.
|
|
43
|
+
- `withPersistentAuth` retries a rejected refresh once with the token a sibling host wrote to the shared cookie, instead of deleting it.
|
|
44
|
+
- The devtools panel, toggle and pills hide under `navigator.webdriver`. Set `provideQueryDevtools({ showInAutomation: true })` to keep them.
|
|
45
|
+
- A legacy creator's `prepare()` returns the same query for equal arguments in one injector scope, as v2 did. A `queryComputed` that calls `prepare()` no longer loops on NG0103.
|
|
46
|
+
- `V2BearerAuthProvider` writes the refresh cookie on the parent domain of the host again when `refreshConfig.cookieDomain` is not set. An earlier 6.0.0 prerelease wrote a host-only cookie, so apps on sibling subdomains lost the session and looped back to the login.
|
|
47
|
+
- The `state$` of a legacy query no longer replays its previous `Success` to a subscriber that attaches right after `execute()`. Like v2, the subscriber now sees `Loading` first.
|
|
48
|
+
- `toQuerySignal` subscribes its source once. A cold source no longer runs twice, so the template no longer shows a query that no container manages.
|
|
49
|
+
- The `migrate-to-query-v3` report lists every call site of the v2 auth hooks (`setAuthProvider`, `clearAuthProvider`, `authProvider$`, `isBearerAuthProvider`) and every `HttpInterceptor` that sets an `Authorization` header.
|
|
50
|
+
- The `migrate-to-query-v3` generator writes `retryConfig: { maxAttempts: 8 }` into the refresh query of the auth scaffold and warns that the login cookie is per host. The migration guide names both behaviors.
|
|
51
|
+
- The `migrate-to-query-v3` auth provider scaffold imports the names its copied config uses (adapters, cookie name and domain) into the client file, and reports a name that the v2 file declares at its top level.
|
|
52
|
+
- The `migrate-to-query-v3` generator maps the v2 `responseAdapter` result `{ token, refreshToken }` to `{ accessToken, refreshToken }` in `extractTokens`, and writes `defaultRememberMe: true` so the login cookie stays as long as in v2.
|
|
53
|
+
- `migrate-to-query-v3` no longer copies a v2 `retryFn` into `createQueryClient` and no longer adds `withEthleteApiErrors()` to Contentful, Shopify or Bynder clients. It reports a task for each instead.
|
|
54
|
+
- `migrate-to-query-v3` also passes an injector to `createSubject()`, `createSignal()` and `behaviorSubject()` calls on a legacy creator that run outside an injection context, as it did for `prepare()`.
|
|
55
|
+
- The `migrate-to-query-v3` generator keeps `AnyV2Query` in a file that already names `AnyLegacyQuery`, so a union of both no longer collapses into one type with a duplicate import.
|
|
56
|
+
- The `migrate-to-query-v3` generator moves `QueryDevtoolsComponent` to `QueryDevtoolsLazyComponent` from `@ethlete/query-devtools/lazy` and rewrites `<et-query-devtools>` to `<et-query-devtools-lazy>`, so the panel loads on first open.
|
|
57
|
+
- `migrate-to-query-v3` names `createGqlQueryViaGet` in the task for a GraphQL creator whose v2 client set `request.gql.transferVia: 'GET'`, and no longer warns about that dropped option.
|
|
58
|
+
- The `migrate-to-query-v3` report flags every `new V2QueryClient(...)` left after a run as a migrator error, and the migration guide no longer presents a client that stays on v2 as supported.
|
|
59
|
+
- `migrate-to-query-v3` reports each `prepare()`, `createSignal()` and `behaviorSubject()` call on a `legacy*` property receiver outside an injection context, with `file:line`.
|
|
60
|
+
- `migrate-to-query-v3` now points a consumer at the right `legacy*` wrapper when two projects declare a creator with the same name. Before, the last declaration in the workspace won and consumers of the other one were left on the v3 creator.
|
|
61
|
+
- The `migrate-to-query-v3` task for a `prepare()` call in a standalone function now names the fix: add `const injector = inject(Injector)` at the top of the factory and pass `{ injector }`, or use `provideLegacyPrepareFallback()`.
|
|
62
|
+
|
|
3
63
|
## 6.0.0-next.61
|
|
4
64
|
|
|
5
65
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { ɵEMPTY_QUERY_DEVTOOLS_FAULT as EMPTY_QUERY_DEVTOOLS_FAULT, ɵMAX_QUERY_BATCH_TOMBSTONES as MAX_QUERY_BATCH_TOMBSTONES, ɵMAX_QUERY_BATCH_TOMBSTONE_BUCKETS as MAX_QUERY_BATCH_TOMBSTONE_BUCKETS, ɵMAX_QUERY_DEVTOOLS_TOMBSTONES as MAX_QUERY_DEVTOOLS_TOMBSTONES, ɵQUERY_DEVTOOLS_FAULT_STATUSES as QUERY_DEVTOOLS_FAULT_STATUSES, ɵQUERY_DEVTOOLS_TOKEN_TTL_LIMIT as QUERY_DEVTOOLS_TOKEN_TTL_LIMIT, ɵaddQueryDevtoolsAuthAccount as addQueryDevtoolsAuthAccount, ɵapplyQueryDevtoolsOverrides as applyQueryDevtoolsOverrides, ɵapplyQueryDevtoolsTokenTtl as applyQueryDevtoolsTokenTtl, ɵarmAllQueryDevtoolsMocks as armAllQueryDevtoolsMocks, ɵarmQueryDevtoolsMock as armQueryDevtoolsMock, ɵarmQueryDevtoolsOverrideTransfer as armQueryDevtoolsOverrideTransfer, ɵcanOverrideQueryDevtoolsTokenTtl as canOverrideQueryDevtoolsTokenTtl, ɵclearQueryDevtoolsArmedMocks as clearQueryDevtoolsArmedMocks, ɵclearQueryDevtoolsAuthCredentials as clearQueryDevtoolsAuthCredentials, ɵclearQueryDevtoolsAuthSessions as clearQueryDevtoolsAuthSessions, ɵclearQueryDevtoolsFaults as clearQueryDevtoolsFaults, ɵclearQueryDevtoolsMockStore as clearQueryDevtoolsMockStore, ɵclearQueryDevtoolsOverrideStore as clearQueryDevtoolsOverrideStore, ɵclearQueryDevtoolsStore as clearQueryDevtoolsStore, ɵclearQueryDevtoolsTombstones as clearQueryDevtoolsTombstones, ɵclearRestoredQueryDevtoolsOverrides as clearRestoredQueryDevtoolsOverrides, ɵcollectLeafPaths as collectLeafPaths, ɵcollectQueryDevtoolsSchemaComponents as collectQueryDevtoolsSchemaComponents, ɵcountUnresolvedQueryDevtoolsOverrides as countUnresolvedQueryDevtoolsOverrides, ɵcreateQueryDevtoolsOverrides as createQueryDevtoolsOverrides, ɵdeleteQueryDevtoolsMock as deleteQueryDevtoolsMock, ɵdetectPaginationShape as detectPaginationShape, ɵforgetQueryDevtoolsAuthSession as forgetQueryDevtoolsAuthSession, ɵforgetQueryDevtoolsAuthSessionsFor as forgetQueryDevtoolsAuthSessionsFor, ɵgenerateQueryDevtoolsNumberPreset as generateQueryDevtoolsNumberPreset, ɵgenerateQueryDevtoolsSampleNumber as generateQueryDevtoolsSampleNumber, ɵgenerateQueryDevtoolsStringPreset as generateQueryDevtoolsStringPreset, ɵhasQueryDevtoolsOverridesAtPath as hasQueryDevtoolsOverridesAtPath, ɵisDateShapedLeaf as isDateShapedLeaf, ɵisQueryDevtoolsEnabled as isQueryDevtoolsEnabled, ɵisQueryDevtoolsFaultArmed as isQueryDevtoolsFaultArmed, ɵisQueryDevtoolsRepositoryLive as isQueryDevtoolsRepositoryLive, ɵloadQueryDevtoolsSchema as loadQueryDevtoolsSchema, ɵloginQueryDevtoolsAuthAccount as loginQueryDevtoolsAuthAccount, ɵlogoutQueryDevtoolsAuthSession as logoutQueryDevtoolsAuthSession, ɵmatchesQueryDevtoolsMockPattern as matchesQueryDevtoolsMockPattern, ɵmatchesQueryDevtoolsMockQuery as matchesQueryDevtoolsMockQuery, ɵmeasureQueryDevtoolsPayload as measureQueryDevtoolsPayload, ɵparseQueryDevtoolsOverrideTransfer as parseQueryDevtoolsOverrideTransfer, ɵqueryDevtoolsAbout as queryDevtoolsAbout, ɵqueryDevtoolsAllowsLocalAuthSessions as queryDevtoolsAllowsLocalAuthSessions, ɵqueryDevtoolsApiEnvIds as queryDevtoolsApiEnvIds, ɵqueryDevtoolsApiEnvIsProduction as queryDevtoolsApiEnvIsProduction, ɵqueryDevtoolsApiEnvScope as queryDevtoolsApiEnvScope, ɵqueryDevtoolsApiEnvValues as queryDevtoolsApiEnvValues, ɵqueryDevtoolsApiEnvs as queryDevtoolsApiEnvs, ɵqueryDevtoolsArmedMocks as queryDevtoolsArmedMocks, ɵqueryDevtoolsArmedMocksRestored as queryDevtoolsArmedMocksRestored, ɵqueryDevtoolsAuthAccountsFor as queryDevtoolsAuthAccountsFor, ɵqueryDevtoolsAuthActive as queryDevtoolsAuthActive, ɵqueryDevtoolsAuthFieldsFor as queryDevtoolsAuthFieldsFor, ɵqueryDevtoolsAuthOtherScopeCount as queryDevtoolsAuthOtherScopeCount, ɵqueryDevtoolsAuthSessions as queryDevtoolsAuthSessions, ɵqueryDevtoolsAuthSessionsFor as queryDevtoolsAuthSessionsFor, ɵqueryDevtoolsAuthTabLocal as queryDevtoolsAuthTabLocal, ɵqueryDevtoolsEntries as queryDevtoolsEntries, ɵqueryDevtoolsFaults as queryDevtoolsFaults, ɵqueryDevtoolsFaultsRestored as queryDevtoolsFaultsRestored, ɵqueryDevtoolsMockId as queryDevtoolsMockId, ɵqueryDevtoolsMocks as queryDevtoolsMocks, ɵqueryDevtoolsOverridePersistence as queryDevtoolsOverridePersistence, ɵqueryDevtoolsRequestPath as queryDevtoolsRequestPath, ɵqueryDevtoolsResponseHistory as queryDevtoolsResponseHistory, ɵqueryDevtoolsRestoredOverridesScope as queryDevtoolsRestoredOverridesScope, ɵqueryDevtoolsSchemaNames as queryDevtoolsSchemaNames, ɵqueryDevtoolsSchemaRoutes as queryDevtoolsSchemaRoutes, ɵqueryDevtoolsSchemaState as queryDevtoolsSchemaState, ɵqueryDevtoolsSettings as queryDevtoolsSettings, ɵqueryDevtoolsStorage as queryDevtoolsStorage, ɵqueryDevtoolsTokenTtls as queryDevtoolsTokenTtls, ɵreadQueryDevtoolsStore as readQueryDevtoolsStore, ɵregisterEthleteVersion as registerEthleteVersion, ɵremoveQueryDevtoolsAuthAccount as removeQueryDevtoolsAuthAccount, ɵrenameQueryDevtoolsAuthSession as renameQueryDevtoolsAuthSession, ɵrestoredQueryDevtoolsOverrides as restoredQueryDevtoolsOverrides, ɵsaveQueryDevtoolsMock as saveQueryDevtoolsMock, ɵseedQueryDevtoolsSchemaBody as seedQueryDevtoolsSchemaBody, ɵseedQueryDevtoolsSchemaRoute as seedQueryDevtoolsSchemaRoute, ɵserializeQueryDevtoolsOverrideTransfer as serializeQueryDevtoolsOverrideTransfer, ɵsetQueryDevtoolsApiEnv as setQueryDevtoolsApiEnv, ɵsetQueryDevtoolsAppInfo as setQueryDevtoolsAppInfo, ɵsetQueryDevtoolsArmedMocksScope as setQueryDevtoolsArmedMocksScope, ɵsetQueryDevtoolsAuthCredentials as setQueryDevtoolsAuthCredentials, ɵsetQueryDevtoolsAuthTabLocal as setQueryDevtoolsAuthTabLocal, ɵsetQueryDevtoolsFault as setQueryDevtoolsFault, ɵsetQueryDevtoolsFaultsScope as setQueryDevtoolsFaultsScope, ɵsetQueryDevtoolsOverridePersistence as setQueryDevtoolsOverridePersistence, ɵsetQueryDevtoolsOverridesScope as setQueryDevtoolsOverridesScope, ɵsetQueryDevtoolsSettings as setQueryDevtoolsSettings, ɵsmartDuplicateArrayItem as smartDuplicateArrayItem, ɵsnapshotQueryDevtoolsHandle as snapshotQueryDevtoolsHandle, ɵstringifyQueryRouteParts as stringifyQueryRouteParts, ɵsumQueryDevtoolsStats as sumQueryDevtoolsStats, ɵswitchQueryDevtoolsAuthSession as switchQueryDevtoolsAuthSession, ɵtombstoneOf as tombstoneOf, ɵwriteQueryDevtoolsStore as writeQueryDevtoolsStore } from "@ethlete/query";
|
|
1
|
+
export { ɵEMPTY_QUERY_DEVTOOLS_FAULT as EMPTY_QUERY_DEVTOOLS_FAULT, ɵMAX_QUERY_BATCH_TOMBSTONES as MAX_QUERY_BATCH_TOMBSTONES, ɵMAX_QUERY_BATCH_TOMBSTONE_BUCKETS as MAX_QUERY_BATCH_TOMBSTONE_BUCKETS, ɵMAX_QUERY_DEVTOOLS_TOMBSTONES as MAX_QUERY_DEVTOOLS_TOMBSTONES, ɵQUERY_DEVTOOLS_FAULT_STATUSES as QUERY_DEVTOOLS_FAULT_STATUSES, ɵQUERY_DEVTOOLS_TOKEN_TTL_LIMIT as QUERY_DEVTOOLS_TOKEN_TTL_LIMIT, ɵaddQueryDevtoolsAuthAccount as addQueryDevtoolsAuthAccount, ɵapplyQueryDevtoolsOverrides as applyQueryDevtoolsOverrides, ɵapplyQueryDevtoolsTokenTtl as applyQueryDevtoolsTokenTtl, ɵarmAllQueryDevtoolsMocks as armAllQueryDevtoolsMocks, ɵarmQueryDevtoolsMock as armQueryDevtoolsMock, ɵarmQueryDevtoolsOverrideTransfer as armQueryDevtoolsOverrideTransfer, ɵcanOverrideQueryDevtoolsTokenTtl as canOverrideQueryDevtoolsTokenTtl, ɵclearQueryDevtoolsArmedMocks as clearQueryDevtoolsArmedMocks, ɵclearQueryDevtoolsAuthCredentials as clearQueryDevtoolsAuthCredentials, ɵclearQueryDevtoolsAuthSessions as clearQueryDevtoolsAuthSessions, ɵclearQueryDevtoolsFaults as clearQueryDevtoolsFaults, ɵclearQueryDevtoolsMockStore as clearQueryDevtoolsMockStore, ɵclearQueryDevtoolsOverrideStore as clearQueryDevtoolsOverrideStore, ɵclearQueryDevtoolsStore as clearQueryDevtoolsStore, ɵclearQueryDevtoolsTombstones as clearQueryDevtoolsTombstones, ɵclearRestoredQueryDevtoolsOverrides as clearRestoredQueryDevtoolsOverrides, ɵcollectLeafPaths as collectLeafPaths, ɵcollectQueryDevtoolsSchemaComponents as collectQueryDevtoolsSchemaComponents, ɵcountUnresolvedQueryDevtoolsOverrides as countUnresolvedQueryDevtoolsOverrides, ɵcreateQueryDevtoolsOverrides as createQueryDevtoolsOverrides, ɵdeleteQueryDevtoolsMock as deleteQueryDevtoolsMock, ɵdetectPaginationShape as detectPaginationShape, ɵforgetQueryDevtoolsAuthSession as forgetQueryDevtoolsAuthSession, ɵforgetQueryDevtoolsAuthSessionsFor as forgetQueryDevtoolsAuthSessionsFor, ɵgenerateQueryDevtoolsNumberPreset as generateQueryDevtoolsNumberPreset, ɵgenerateQueryDevtoolsSampleNumber as generateQueryDevtoolsSampleNumber, ɵgenerateQueryDevtoolsStringPreset as generateQueryDevtoolsStringPreset, ɵhasQueryDevtoolsOverridesAtPath as hasQueryDevtoolsOverridesAtPath, ɵisDateShapedLeaf as isDateShapedLeaf, ɵisQueryDevtoolsEnabled as isQueryDevtoolsEnabled, ɵisQueryDevtoolsFaultArmed as isQueryDevtoolsFaultArmed, ɵisQueryDevtoolsHiddenInAutomation as isQueryDevtoolsHiddenInAutomation, ɵisQueryDevtoolsRepositoryLive as isQueryDevtoolsRepositoryLive, ɵloadQueryDevtoolsSchema as loadQueryDevtoolsSchema, ɵloginQueryDevtoolsAuthAccount as loginQueryDevtoolsAuthAccount, ɵlogoutQueryDevtoolsAuthSession as logoutQueryDevtoolsAuthSession, ɵmatchesQueryDevtoolsMockPattern as matchesQueryDevtoolsMockPattern, ɵmatchesQueryDevtoolsMockQuery as matchesQueryDevtoolsMockQuery, ɵmeasureQueryDevtoolsPayload as measureQueryDevtoolsPayload, ɵparseQueryDevtoolsOverrideTransfer as parseQueryDevtoolsOverrideTransfer, ɵqueryDevtoolsAbout as queryDevtoolsAbout, ɵqueryDevtoolsAllowsLocalAuthSessions as queryDevtoolsAllowsLocalAuthSessions, ɵqueryDevtoolsApiEnvIds as queryDevtoolsApiEnvIds, ɵqueryDevtoolsApiEnvIsProduction as queryDevtoolsApiEnvIsProduction, ɵqueryDevtoolsApiEnvScope as queryDevtoolsApiEnvScope, ɵqueryDevtoolsApiEnvValues as queryDevtoolsApiEnvValues, ɵqueryDevtoolsApiEnvs as queryDevtoolsApiEnvs, ɵqueryDevtoolsArmedMocks as queryDevtoolsArmedMocks, ɵqueryDevtoolsArmedMocksRestored as queryDevtoolsArmedMocksRestored, ɵqueryDevtoolsAuthAccountsFor as queryDevtoolsAuthAccountsFor, ɵqueryDevtoolsAuthActive as queryDevtoolsAuthActive, ɵqueryDevtoolsAuthFieldsFor as queryDevtoolsAuthFieldsFor, ɵqueryDevtoolsAuthOtherScopeCount as queryDevtoolsAuthOtherScopeCount, ɵqueryDevtoolsAuthSessions as queryDevtoolsAuthSessions, ɵqueryDevtoolsAuthSessionsFor as queryDevtoolsAuthSessionsFor, ɵqueryDevtoolsAuthTabLocal as queryDevtoolsAuthTabLocal, ɵqueryDevtoolsEntries as queryDevtoolsEntries, ɵqueryDevtoolsFaults as queryDevtoolsFaults, ɵqueryDevtoolsFaultsRestored as queryDevtoolsFaultsRestored, ɵqueryDevtoolsMockId as queryDevtoolsMockId, ɵqueryDevtoolsMocks as queryDevtoolsMocks, ɵqueryDevtoolsOverridePersistence as queryDevtoolsOverridePersistence, ɵqueryDevtoolsRequestPath as queryDevtoolsRequestPath, ɵqueryDevtoolsResponseHistory as queryDevtoolsResponseHistory, ɵqueryDevtoolsRestoredOverridesScope as queryDevtoolsRestoredOverridesScope, ɵqueryDevtoolsSchemaNames as queryDevtoolsSchemaNames, ɵqueryDevtoolsSchemaRoutes as queryDevtoolsSchemaRoutes, ɵqueryDevtoolsSchemaState as queryDevtoolsSchemaState, ɵqueryDevtoolsSettings as queryDevtoolsSettings, ɵqueryDevtoolsStorage as queryDevtoolsStorage, ɵqueryDevtoolsTokenTtls as queryDevtoolsTokenTtls, ɵreadQueryDevtoolsStore as readQueryDevtoolsStore, ɵregisterEthleteVersion as registerEthleteVersion, ɵremoveQueryDevtoolsAuthAccount as removeQueryDevtoolsAuthAccount, ɵrenameQueryDevtoolsAuthSession as renameQueryDevtoolsAuthSession, ɵrestoredQueryDevtoolsOverrides as restoredQueryDevtoolsOverrides, ɵsaveQueryDevtoolsMock as saveQueryDevtoolsMock, ɵseedQueryDevtoolsSchemaBody as seedQueryDevtoolsSchemaBody, ɵseedQueryDevtoolsSchemaRoute as seedQueryDevtoolsSchemaRoute, ɵserializeQueryDevtoolsOverrideTransfer as serializeQueryDevtoolsOverrideTransfer, ɵsetQueryDevtoolsApiEnv as setQueryDevtoolsApiEnv, ɵsetQueryDevtoolsAppInfo as setQueryDevtoolsAppInfo, ɵsetQueryDevtoolsArmedMocksScope as setQueryDevtoolsArmedMocksScope, ɵsetQueryDevtoolsAuthCredentials as setQueryDevtoolsAuthCredentials, ɵsetQueryDevtoolsAuthTabLocal as setQueryDevtoolsAuthTabLocal, ɵsetQueryDevtoolsFault as setQueryDevtoolsFault, ɵsetQueryDevtoolsFaultsScope as setQueryDevtoolsFaultsScope, ɵsetQueryDevtoolsOverridePersistence as setQueryDevtoolsOverridePersistence, ɵsetQueryDevtoolsOverridesScope as setQueryDevtoolsOverridesScope, ɵsetQueryDevtoolsSettings as setQueryDevtoolsSettings, ɵsmartDuplicateArrayItem as smartDuplicateArrayItem, ɵsnapshotQueryDevtoolsHandle as snapshotQueryDevtoolsHandle, ɵstringifyQueryRouteParts as stringifyQueryRouteParts, ɵsumQueryDevtoolsStats as sumQueryDevtoolsStats, ɵswitchQueryDevtoolsAuthSession as switchQueryDevtoolsAuthSession, ɵtombstoneOf as tombstoneOf, ɵwriteQueryDevtoolsStore as writeQueryDevtoolsStore } from "@ethlete/query";
|
|
@@ -229,7 +229,7 @@ const toQueryArgs = (args) => {
|
|
|
229
229
|
if (actionOptions?.headers !== void 0) queryArgs["headers"] = actionOptions.headers;
|
|
230
230
|
return queryArgs;
|
|
231
231
|
};
|
|
232
|
-
const createToolkitHandle = (creator, injector) => {
|
|
232
|
+
const createToolkitHandle = (creator, injector, onSuccess) => {
|
|
233
233
|
const query = creator({
|
|
234
234
|
injector,
|
|
235
235
|
onlyManualExecution: true,
|
|
@@ -254,9 +254,17 @@ const createToolkitHandle = (creator, injector) => {
|
|
|
254
254
|
};
|
|
255
255
|
}, ...ngDevMode ? [{ debugName: "snapshot" }] : /* istanbul ignore next */ []);
|
|
256
256
|
const changes = new Subject();
|
|
257
|
+
let lastSuccess = null;
|
|
257
258
|
const changesEffect = effect(() => {
|
|
258
259
|
const current = snapshot();
|
|
259
|
-
|
|
260
|
+
const state = query.executionState();
|
|
261
|
+
untracked(() => {
|
|
262
|
+
changes.next(current);
|
|
263
|
+
if (current.callState === CallState.SUCCESS && state !== lastSuccess) {
|
|
264
|
+
lastSuccess = state;
|
|
265
|
+
onSuccess(current.response);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
260
268
|
}, {
|
|
261
269
|
...ngDevMode ? { debugName: "changesEffect" } : /* istanbul ignore next */ {},
|
|
262
270
|
injector
|
|
@@ -367,18 +375,29 @@ const resolveEnvironmentInjector = (fn, options) => {
|
|
|
367
375
|
assertInInjectionContext(fn);
|
|
368
376
|
return inject(EnvironmentInjector);
|
|
369
377
|
};
|
|
370
|
-
const
|
|
378
|
+
const registryOf = (injector) => {
|
|
371
379
|
let registry = registries.get(injector);
|
|
372
380
|
if (!registry) {
|
|
381
|
+
const successes = new Subject();
|
|
373
382
|
registry = {
|
|
374
383
|
shared: /* @__PURE__ */ new WeakMap(),
|
|
375
|
-
latestUnshared: /* @__PURE__ */ new WeakMap()
|
|
384
|
+
latestUnshared: /* @__PURE__ */ new WeakMap(),
|
|
385
|
+
successes
|
|
376
386
|
};
|
|
377
387
|
registries.set(injector, registry);
|
|
388
|
+
injector.get(DestroyRef).onDestroy(() => successes.complete());
|
|
378
389
|
}
|
|
390
|
+
return registry;
|
|
391
|
+
};
|
|
392
|
+
const handleFor = (creator, injector, registry) => createToolkitHandle(creator, injector, (response) => registry.successes.next({
|
|
393
|
+
creator,
|
|
394
|
+
response
|
|
395
|
+
}));
|
|
396
|
+
const resolveEntry = (creator, args, injector) => {
|
|
397
|
+
const registry = registryOf(injector);
|
|
379
398
|
const key = hashArgs(toQueryArgs(args));
|
|
380
399
|
if (key === null) {
|
|
381
|
-
const entry =
|
|
400
|
+
const entry = handleFor(creator, injector, registry);
|
|
382
401
|
registry.latestUnshared.get(creator)?.releaseWhenSettled();
|
|
383
402
|
registry.latestUnshared.set(creator, entry);
|
|
384
403
|
return entry;
|
|
@@ -390,7 +409,7 @@ const resolveEntry = (creator, args, injector) => {
|
|
|
390
409
|
}
|
|
391
410
|
let entry = entries.get(key);
|
|
392
411
|
if (!entry) {
|
|
393
|
-
entry =
|
|
412
|
+
entry = handleFor(creator, injector, registry);
|
|
394
413
|
entries.set(key, entry);
|
|
395
414
|
}
|
|
396
415
|
return entry;
|
|
@@ -401,11 +420,15 @@ const toolkitCall = (creator, args, options) => {
|
|
|
401
420
|
entry.call(args);
|
|
402
421
|
return entry.handle;
|
|
403
422
|
};
|
|
423
|
+
const toolkitOnSuccess = (creators, options) => {
|
|
424
|
+
const watched = new Set(Array.isArray(creators) ? creators : [creators]);
|
|
425
|
+
return registryOf(resolveEnvironmentInjector(toolkitOnSuccess, options)).successes.pipe(filter((success) => watched.has(success.creator)), map((success) => success.response));
|
|
426
|
+
};
|
|
404
427
|
const joinLoading = (observables) => combineLatest(observables.filter((o) => !!o)).pipe(map((values) => values.some((value) => !!value)));
|
|
405
428
|
const joinErrors = (observables) => combineLatest(observables.filter((o) => !!o)).pipe(map((values) => {
|
|
406
429
|
const errors = values.filter((value) => !!value);
|
|
407
430
|
return errors.length ? errors : null;
|
|
408
431
|
}));
|
|
409
|
-
export { CallState, NgRxToolkitModule, SuspenseMultiPipe, SuspensePipe, joinErrors, joinLoading, toolkitCall, toolkitSelect };
|
|
432
|
+
export { CallState, NgRxToolkitModule, SuspenseMultiPipe, SuspensePipe, joinErrors, joinLoading, toolkitCall, toolkitOnSuccess, toolkitSelect };
|
|
410
433
|
|
|
411
434
|
//# sourceMappingURL=ethlete-query-ngrx-toolkit.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ethlete-query-ngrx-toolkit.mjs","names":[],"sources":["../../../../libs/query/ngrx-toolkit/toolkit-pipe-transform.ts","../../../../libs/query/ngrx-toolkit/suspense.pipe.ts","../../../../libs/query/ngrx-toolkit/suspense-multi.pipe.ts","../../../../libs/query/ngrx-toolkit/ngrx-toolkit.module.ts","../../../../libs/query/ngrx-toolkit/toolkit-types.ts","../../../../libs/query/ngrx-toolkit/toolkit-handle.ts","../../../../libs/query/ngrx-toolkit/toolkit-call.ts","../../../../libs/query/ngrx-toolkit/toolkit-join.ts"],"sourcesContent":["import { ChangeDetectorRef, DestroyRef, inject } from '@angular/core';\nimport { Observable, Subscription } from 'rxjs';\n\nexport type CreateToolkitPipeTransformOptions<TValue, TState> = {\n initialState: TState;\n disposedState: TState;\n state$: (value: TValue) => Observable<TState>;\n};\n\nexport const createToolkitPipeTransform = <TValue extends object, TState>(\n options: CreateToolkitPipeTransformOptions<TValue, TState>,\n) => {\n const cdr = inject(ChangeDetectorRef);\n let subscription = Subscription.EMPTY;\n let current: TValue | null = null;\n let state = options.initialState;\n\n const dispose = () => {\n subscription.unsubscribe();\n current = null;\n state = options.disposedState;\n };\n\n const subscribe = (value: TValue) => {\n current = value;\n subscription = options.state$(value).subscribe((next) => {\n state = next;\n cdr.markForCheck();\n });\n };\n\n inject(DestroyRef).onDestroy(dispose);\n\n return (value: TValue | null | undefined) => {\n if (!current && value) subscribe(value);\n\n if (current !== value) {\n dispose();\n if (value) subscribe(value);\n }\n\n return state;\n };\n};\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { combineLatest, map, Observable, startWith } from 'rxjs';\nimport { createToolkitPipeTransform } from './toolkit-pipe-transform';\nimport { AnyMappedEntityState, ToolkitPollingOptions } from './toolkit-types';\n\ntype ExtractFrom<T> = T extends Observable<infer U> ? U : never;\n\n/** What `suspense` and `suspenseMulti` render for a handle: every stream's current value, plus the handle's methods. */\nexport type ToolkitSuspenseState<T extends AnyMappedEntityState | null | undefined> = T extends AnyMappedEntityState\n ? {\n args: ExtractFrom<T['args$']>;\n cachedResponse: ExtractFrom<T['cachedResponse$']> | null;\n callState: ExtractFrom<T['callState$']>;\n error: ExtractFrom<T['error$']>;\n isError: ExtractFrom<T['isError$']>;\n isInit: ExtractFrom<T['isInit$']>;\n isLoading: ExtractFrom<T['isLoading$']>;\n isSuccess: ExtractFrom<T['isSuccess$']>;\n response: ExtractFrom<T['response$']>;\n timestamp: ExtractFrom<T['timestamp$']>;\n refresh: () => void;\n remove: () => void;\n startPolling: (options: ToolkitPollingOptions) => void;\n stopPolling: () => void;\n }\n : T;\n\ntype AnySuspenseState = ToolkitSuspenseState<AnyMappedEntityState>;\n\nconst noop = () => undefined;\n\nconst DEFAULT_STATE: AnySuspenseState = {\n args: null,\n cachedResponse: null,\n callState: null,\n error: null,\n isError: false,\n isInit: false,\n isLoading: false,\n isSuccess: false,\n response: null,\n timestamp: null,\n refresh: noop,\n remove: noop,\n startPolling: noop,\n stopPolling: noop,\n};\n\nexport const suspenseState$ = (handle: AnyMappedEntityState): Observable<AnySuspenseState> =>\n combineLatest({\n args: handle.args$,\n cachedResponse: handle.cachedResponse$.pipe(startWith(null)),\n callState: handle.callState$,\n error: handle.error$,\n isError: handle.isError$,\n isInit: handle.isInit$,\n isLoading: handle.isLoading$,\n isSuccess: handle.isSuccess$,\n response: handle.response$,\n timestamp: handle.timestamp$,\n }).pipe(\n map((values) => ({\n ...values,\n refresh: handle.refresh,\n remove: handle.remove,\n startPolling: handle.startPolling,\n stopPolling: handle.stopPolling,\n })),\n );\n\n/** Subscribes to a toolkit handle and renders its current state, like the `suspense` pipe of `@tomtomb/ngrx-toolkit`. */\n@Pipe({ name: 'suspense', pure: false })\nexport class SuspensePipe implements PipeTransform {\n transform = createToolkitPipeTransform<AnyMappedEntityState, AnySuspenseState | null>({\n initialState: DEFAULT_STATE,\n disposedState: null,\n state$: suspenseState$,\n }) as <T extends AnyMappedEntityState>(value: T | null | undefined) => ToolkitSuspenseState<T>;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { combineLatest, map } from 'rxjs';\nimport { suspenseState$, ToolkitSuspenseState } from './suspense.pipe';\nimport { createToolkitPipeTransform } from './toolkit-pipe-transform';\nimport { AnyMappedEntityState } from './toolkit-types';\n\ntype AnyHandleRecord = Record<string, AnyMappedEntityState | null | undefined>;\n\nexport type ToolkitSuspenseMultiState<T extends AnyHandleRecord> = {\n [K in keyof T]: ToolkitSuspenseState<T[K]>;\n};\n\nconst suspenseMultiState$ = (handles: AnyHandleRecord) =>\n combineLatest(\n Object.entries(handles).flatMap(([key, handle]) =>\n handle ? [suspenseState$(handle).pipe(map((state) => [key, state] as const))] : [],\n ),\n ).pipe(map((states) => Object.fromEntries(states)));\n\n/**\n * Subscribes to a record of toolkit handles and renders each one's current state, like the `suspenseMulti` pipe of\n * `@tomtomb/ngrx-toolkit`. Nothing renders until every non-null handle has emitted.\n */\n@Pipe({ name: 'suspenseMulti', pure: false })\nexport class SuspenseMultiPipe implements PipeTransform {\n transform = createToolkitPipeTransform<AnyHandleRecord, Record<string, unknown>>({\n initialState: {},\n disposedState: {},\n state$: suspenseMultiState$,\n }) as <T extends AnyHandleRecord>(value: T | null | undefined) => ToolkitSuspenseMultiState<T>;\n}\n","import { NgModule } from '@angular/core';\nimport { SuspenseMultiPipe } from './suspense-multi.pipe';\nimport { SuspensePipe } from './suspense.pipe';\n\n/** Exports the `suspense` and `suspenseMulti` pipes, like the `NgRxToolkitModule` of `@tomtomb/ngrx-toolkit`. */\n@NgModule({\n imports: [SuspensePipe, SuspenseMultiPipe],\n exports: [SuspensePipe, SuspenseMultiPipe],\n})\nexport class NgRxToolkitModule {}\n","import { AnyQueryCreator, QueryArgsOf, QueryHeaders, ResponseType } from '@ethlete/query';\nimport { Observable, Subject } from 'rxjs';\n\n/** The call state of a toolkit handle, as `@tomtomb/ngrx-toolkit` names it. */\nexport const CallState = {\n INIT: 'INIT',\n LOADING: 'LOADING',\n SUCCESS: 'SUCCESS',\n ERROR: 'ERROR',\n} as const;\n\nexport type CallState = (typeof CallState)[keyof typeof CallState];\n\n/** The error shape of `@tomtomb/ngrx-toolkit`: the HTTP status, the error message and the response body. */\nexport type ToolkitError<T = unknown> = {\n status: number | string;\n message: string;\n data: T | null;\n};\n\nexport type ToolkitActionOptions = {\n headers?: QueryHeaders;\n extras?: { skipCache?: boolean };\n};\n\n/**\n * The toolkit-shaped args of a query creator: `queryParams` holds the path params, `params` the query string and\n * `body` the body, the way `@tomtomb/ngrx-toolkit` action groups named them.\n */\nexport type ActionCallArgs<TCreator extends AnyQueryCreator> = {\n [\n K in keyof QueryArgsOf<TCreator> as K extends 'pathParams'\n ? 'queryParams'\n : K extends 'queryParams'\n ? 'params'\n : K extends 'body'\n ? 'body'\n : never\n ]: QueryArgsOf<TCreator>[K];\n} & { actionOptions?: ToolkitActionOptions };\n\nexport type ToolkitPollingOptions = {\n intervalDuration: number;\n killSwitch: Subject<boolean>;\n};\n\n/** The handle `toolkitCall` returns, shaped like the `MappedEntityState` of `@tomtomb/ngrx-toolkit`. */\nexport type MappedEntityState<TCreator extends AnyQueryCreator> = {\n response$: Observable<ResponseType<QueryArgsOf<TCreator>> | null>;\n cachedResponse$: Observable<ResponseType<QueryArgsOf<TCreator>>>;\n error$: Observable<ToolkitError | null>;\n args$: Observable<ActionCallArgs<TCreator> | null>;\n isInit$: Observable<boolean | null>;\n isLoading$: Observable<boolean | null>;\n isSuccess$: Observable<boolean | null>;\n isError$: Observable<boolean | null>;\n timestamp$: Observable<number | null>;\n callState$: Observable<CallState | null>;\n refresh: () => void;\n remove: () => void;\n startPolling: (options: ToolkitPollingOptions) => void;\n stopPolling: () => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyMappedEntityState = MappedEntityState<any>;\n","import { computed, DestroyRef, effect, EnvironmentInjector, isDevMode, signal, untracked } from '@angular/core';\nimport {\n AnyQueryCreator,\n QueryArgsOf,\n QueryErrorResponse,\n QueryExecutionState,\n RequestArgs,\n ResponseType,\n} from '@ethlete/query';\nimport {\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n interval,\n map,\n Observable,\n of,\n startWith,\n Subject,\n Subscription,\n takeUntil,\n} from 'rxjs';\nimport {\n ActionCallArgs,\n AnyMappedEntityState,\n CallState,\n MappedEntityState,\n ToolkitError,\n ToolkitPollingOptions,\n} from './toolkit-types';\n\ntype ToolkitHandleSnapshot = {\n args: unknown;\n callState: CallState | null;\n response: unknown;\n error: ToolkitError | null;\n timestamp: number | null;\n};\n\nexport type ToolkitHandleEntry = {\n handle: AnyMappedEntityState;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call: (args: ActionCallArgs<any>) => void;\n releaseWhenSettled: () => void;\n};\n\nconst EMPTY_SNAPSHOT: ToolkitHandleSnapshot = {\n args: null,\n callState: null,\n response: null,\n error: null,\n timestamp: null,\n};\n\nconst toCallState = (state: QueryExecutionState<never> | null): CallState => {\n switch (state?.type) {\n case 'success':\n return CallState.SUCCESS;\n case 'failure':\n return CallState.ERROR;\n default:\n return CallState.LOADING;\n }\n};\n\nconst toToolkitError = (error: QueryErrorResponse): ToolkitError => ({\n status: error.raw.status,\n message: error.raw.message,\n data: error.raw.error ?? null,\n});\n\nconst handleReleasedMessage = (method: 'refresh' | 'startPolling') =>\n `${method}() was called on a toolkit handle that a newer toolkitCall() released. Args that cannot be hashed ` +\n `(FormData, Blob, Map, ...) never share a handle, so the next call for the same creator releases the previous ` +\n `handle once its request settles. The call was ignored - call toolkitCall() again with the args instead of ` +\n `reusing the old handle. This warning is shown once per handle.`;\n\nexport const toQueryArgs = (args: Record<string, unknown>) => {\n const actionOptions = args['actionOptions'] as { headers?: unknown } | undefined;\n const queryArgs: Record<string, unknown> = {};\n\n if (args['queryParams'] !== undefined) queryArgs['pathParams'] = args['queryParams'];\n if (args['params'] !== undefined) queryArgs['queryParams'] = args['params'];\n if (args['body'] !== undefined) queryArgs['body'] = args['body'];\n if (actionOptions?.headers !== undefined) queryArgs['headers'] = actionOptions.headers;\n\n return queryArgs as RequestArgs<never>;\n};\n\nexport const createToolkitHandle = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n injector: EnvironmentInjector,\n): ToolkitHandleEntry => {\n const query = creator({ injector, onlyManualExecution: true, silenceMissingWithArgsFeatureError: true });\n\n const calledArgs = signal<ActionCallArgs<TCreator> | null>(null);\n const toolkitError = computed(() => {\n const error = query.error();\n\n return error ? toToolkitError(error) : null;\n });\n const snapshot = computed<ToolkitHandleSnapshot>(() => {\n const currentArgs = calledArgs();\n\n if (!currentArgs) return EMPTY_SNAPSHOT;\n\n const state = query.executionState();\n const callState = toCallState(state);\n\n return {\n args: currentArgs,\n callState,\n response: state?.type === 'success' ? state.response : null,\n error: callState === CallState.ERROR ? toolkitError() : null,\n timestamp: Date.now(),\n };\n });\n\n const changes = new Subject<ToolkitHandleSnapshot>();\n\n const changesEffect = effect(\n () => {\n const current = snapshot();\n untracked(() => changes.next(current));\n },\n { injector },\n );\n\n let releasedSnapshot: ToolkitHandleSnapshot | null = null;\n let warnedAboutRelease = false;\n\n const ignoredAfterRelease = (method: 'refresh' | 'startPolling') => {\n if (!releasedSnapshot) return false;\n\n if (isDevMode() && !warnedAboutRelease) {\n warnedAboutRelease = true;\n console.warn(handleReleasedMessage(method));\n }\n\n return true;\n };\n\n const select = <T>(pick: (current: ToolkitHandleSnapshot) => T): Observable<T> =>\n defer(() => (releasedSnapshot ? of(releasedSnapshot) : changes.pipe(startWith(untracked(snapshot))))).pipe(\n map(pick),\n distinctUntilChanged(),\n );\n\n const call = (args: ActionCallArgs<TCreator>) => {\n calledArgs.set(args);\n query.execute({ args: toQueryArgs(args as Record<string, unknown>) });\n };\n\n const refresh = () => {\n if (ignoredAfterRelease('refresh')) return;\n\n const lastArgs = untracked(calledArgs);\n\n if (lastArgs) call(lastArgs);\n };\n\n let pollingSubscription = Subscription.EMPTY;\n\n const stopPolling = () => pollingSubscription.unsubscribe();\n\n const startPolling = ({ intervalDuration, killSwitch }: ToolkitPollingOptions) => {\n if (ignoredAfterRelease('startPolling') || !pollingSubscription.closed) return;\n\n pollingSubscription = interval(intervalDuration)\n .pipe(\n takeUntil(killSwitch),\n finalize(() => (pollingSubscription = Subscription.EMPTY)),\n )\n .subscribe(() => refresh());\n };\n\n const remove = () => {\n stopPolling();\n calledArgs.set(null);\n query.reset();\n };\n\n const removeDestroyListener = injector.get(DestroyRef).onDestroy(() => {\n stopPolling();\n changes.complete();\n });\n\n const release = () => {\n releasedSnapshot = untracked(snapshot);\n stopPolling();\n changesEffect.destroy();\n removeDestroyListener();\n changes.complete();\n query.subtle.destroy();\n };\n\n const releaseWhenSettled = () => {\n const releaseEffect = effect(\n () => {\n if (snapshot().callState === CallState.LOADING) return;\n\n releaseEffect.destroy();\n untracked(release);\n },\n { injector },\n );\n };\n\n type TResponse = ResponseType<QueryArgsOf<TCreator>>;\n\n const response$ = select((current) => current.response as TResponse | null);\n\n const handle: MappedEntityState<TCreator> = {\n response$,\n cachedResponse$: response$.pipe(filter((response): response is TResponse => !!response)),\n error$: select((current) => current.error),\n args$: select((current) => current.args as ActionCallArgs<TCreator> | null),\n isInit$: select((current) => current.callState === CallState.INIT),\n isLoading$: select((current) => current.callState === CallState.LOADING),\n isSuccess$: select((current) => current.callState === CallState.SUCCESS),\n isError$: select((current) => current.callState === CallState.ERROR),\n timestamp$: select((current) => current.timestamp),\n callState$: select((current) => current.callState),\n refresh,\n remove,\n startPolling,\n stopPolling,\n };\n\n return { handle, call, releaseWhenSettled };\n};\n","import { assertInInjectionContext, EnvironmentInjector, inject, Injector } from '@angular/core';\nimport { AnyQueryCreator, QueryHeaders, RequestArgs, resolveQueryHeaders } from '@ethlete/query';\nimport { createToolkitHandle, ToolkitHandleEntry, toQueryArgs } from './toolkit-handle';\nimport { ActionCallArgs, MappedEntityState } from './toolkit-types';\n\nexport type ToolkitCallOptions = {\n /**\n * The injector the handle's query lives in. Required outside an injection context, which is where a\n * `providedIn: 'root'` facade calls from; pass the facade's `inject(Injector)`.\n */\n injector?: Injector;\n};\n\ntype ToolkitRegistry = {\n shared: WeakMap<AnyQueryCreator, Map<string, ToolkitHandleEntry>>;\n latestUnshared: WeakMap<AnyQueryCreator, ToolkitHandleEntry>;\n};\n\nconst registries = /* @__PURE__ */ new WeakMap<EnvironmentInjector, ToolkitRegistry>();\n\nclass UnhashableValueError extends Error {}\n\nconst isPlainObject = (value: object) => {\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n};\n\nconst hashableValue = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(hashableValue);\n if (typeof value !== 'object' || value === null) return value;\n if (value instanceof Date) return { '\\u0000date': value.getTime() };\n if (!isPlainObject(value)) throw new UnhashableValueError();\n\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, hashableValue((value as Record<string, unknown>)[key])]),\n );\n};\n\nconst hashableHeaders = (headers: QueryHeaders | undefined) => {\n const resolved = resolveQueryHeaders(headers);\n\n return resolved\n ?.keys()\n .map((name) => name.toLowerCase())\n .sort()\n .map((name) => [name, resolved.getAll(name)]);\n};\n\n/**\n * Returns `null` for args holding a value JSON cannot represent (FormData, Blob, Map, ...). Those never share a handle,\n * and each one is released once the next one for the same creator starts and its own call has settled.\n */\nconst hashArgs = (args: RequestArgs<never>) => {\n const { headers, ...rest } = args as { headers?: QueryHeaders };\n\n try {\n return JSON.stringify([hashableValue(rest), hashableHeaders(headers) ?? null]);\n } catch (error) {\n if (error instanceof UnhashableValueError) return null;\n\n throw error;\n }\n};\n\nconst resolveEnvironmentInjector = (fn: (...args: never[]) => unknown, options?: ToolkitCallOptions) => {\n if (options?.injector) return options.injector.get(EnvironmentInjector);\n\n assertInInjectionContext(fn);\n\n return inject(EnvironmentInjector);\n};\n\nconst resolveEntry = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n args: ActionCallArgs<TCreator>,\n injector: EnvironmentInjector,\n) => {\n let registry = registries.get(injector);\n\n if (!registry) {\n registry = { shared: new WeakMap(), latestUnshared: new WeakMap() };\n registries.set(injector, registry);\n }\n\n const key = hashArgs(toQueryArgs(args as Record<string, unknown>));\n\n if (key === null) {\n const entry = createToolkitHandle(creator, injector);\n\n registry.latestUnshared.get(creator)?.releaseWhenSettled();\n registry.latestUnshared.set(creator, entry);\n\n return entry;\n }\n\n let entries = registry.shared.get(creator);\n\n if (!entries) {\n entries = new Map();\n registry.shared.set(creator, entries);\n }\n\n let entry = entries.get(key);\n\n if (!entry) {\n entry = createToolkitHandle(creator, injector);\n entries.set(key, entry);\n }\n\n return entry;\n};\n\n/**\n * Returns the handle for a creator and args without executing it - the `FacadeBase.select(group, actionId)` of\n * `@tomtomb/ngrx-toolkit`. Args that build the same request (in any key order, other keys ignored) give the same\n * handle `toolkitCall` returns, so `toolkitSelect(getTeam, args, { injector }).refresh()` re-runs a request another\n * component started.\n */\nexport const toolkitSelect = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n args: ActionCallArgs<TCreator>,\n options?: ToolkitCallOptions,\n): MappedEntityState<TCreator> =>\n resolveEntry(creator, args, resolveEnvironmentInjector(toolkitSelect, options)).handle;\n\n/**\n * Executes a query creator with toolkit-shaped args and returns its handle - the `FacadeBase.call(group, args)` of\n * `@tomtomb/ngrx-toolkit`. Every call sends the request again, unless one with equal args is still in flight, which it\n * joins; equal args return the same handle, which lives as long as the injector.\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class TeamFacade {\n * private injector = inject(Injector);\n *\n * getTeam(args: ActionCallArgs<typeof getTeam>) {\n * return toolkitCall(getTeam, args, { injector: this.injector });\n * }\n * }\n * ```\n */\nexport const toolkitCall = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n args: ActionCallArgs<TCreator>,\n options?: ToolkitCallOptions,\n): MappedEntityState<TCreator> => {\n const entry = resolveEntry(creator, args, resolveEnvironmentInjector(toolkitCall, options));\n\n entry.call(args);\n\n return entry.handle;\n};\n","import { combineLatest, map, Observable } from 'rxjs';\nimport { ToolkitError } from './toolkit-types';\n\n/** Emits `true` while any of the given loading streams is `true`. Nullish entries are skipped. */\nexport const joinLoading = (observables: (Observable<boolean | null> | null | undefined)[]): Observable<boolean> =>\n combineLatest(observables.filter((o): o is Observable<boolean | null> => !!o)).pipe(\n map((values) => values.some((value) => !!value)),\n );\n\n/** Emits every non-null error of the given error streams, or `null` when there is none. Nullish entries are skipped. */\nexport const joinErrors = (\n observables: (Observable<ToolkitError | null> | null | undefined)[],\n): Observable<ToolkitError[] | null> =>\n combineLatest(observables.filter((o): o is Observable<ToolkitError | null> => !!o)).pipe(\n map((values) => {\n const errors = values.filter((value): value is ToolkitError => !!value);\n\n return errors.length ? errors : null;\n }),\n );\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ethlete-query-ngrx-toolkit.mjs","names":[],"sources":["../../../../libs/query/ngrx-toolkit/toolkit-pipe-transform.ts","../../../../libs/query/ngrx-toolkit/suspense.pipe.ts","../../../../libs/query/ngrx-toolkit/suspense-multi.pipe.ts","../../../../libs/query/ngrx-toolkit/ngrx-toolkit.module.ts","../../../../libs/query/ngrx-toolkit/toolkit-types.ts","../../../../libs/query/ngrx-toolkit/toolkit-handle.ts","../../../../libs/query/ngrx-toolkit/toolkit-call.ts","../../../../libs/query/ngrx-toolkit/toolkit-join.ts"],"sourcesContent":["import { ChangeDetectorRef, DestroyRef, inject } from '@angular/core';\nimport { Observable, Subscription } from 'rxjs';\n\nexport type CreateToolkitPipeTransformOptions<TValue, TState> = {\n initialState: TState;\n disposedState: TState;\n state$: (value: TValue) => Observable<TState>;\n};\n\nexport const createToolkitPipeTransform = <TValue extends object, TState>(\n options: CreateToolkitPipeTransformOptions<TValue, TState>,\n) => {\n const cdr = inject(ChangeDetectorRef);\n let subscription = Subscription.EMPTY;\n let current: TValue | null = null;\n let state = options.initialState;\n\n const dispose = () => {\n subscription.unsubscribe();\n current = null;\n state = options.disposedState;\n };\n\n const subscribe = (value: TValue) => {\n current = value;\n subscription = options.state$(value).subscribe((next) => {\n state = next;\n cdr.markForCheck();\n });\n };\n\n inject(DestroyRef).onDestroy(dispose);\n\n return (value: TValue | null | undefined) => {\n if (!current && value) subscribe(value);\n\n if (current !== value) {\n dispose();\n if (value) subscribe(value);\n }\n\n return state;\n };\n};\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { combineLatest, map, Observable, startWith } from 'rxjs';\nimport { createToolkitPipeTransform } from './toolkit-pipe-transform';\nimport { AnyMappedEntityState, ToolkitPollingOptions } from './toolkit-types';\n\ntype ExtractFrom<T> = T extends Observable<infer U> ? U : never;\n\n/** What `suspense` and `suspenseMulti` render for a handle: every stream's current value, plus the handle's methods. */\nexport type ToolkitSuspenseState<T extends AnyMappedEntityState | null | undefined> = T extends AnyMappedEntityState\n ? {\n args: ExtractFrom<T['args$']>;\n cachedResponse: ExtractFrom<T['cachedResponse$']> | null;\n callState: ExtractFrom<T['callState$']>;\n error: ExtractFrom<T['error$']>;\n isError: ExtractFrom<T['isError$']>;\n isInit: ExtractFrom<T['isInit$']>;\n isLoading: ExtractFrom<T['isLoading$']>;\n isSuccess: ExtractFrom<T['isSuccess$']>;\n response: ExtractFrom<T['response$']>;\n timestamp: ExtractFrom<T['timestamp$']>;\n refresh: () => void;\n remove: () => void;\n startPolling: (options: ToolkitPollingOptions) => void;\n stopPolling: () => void;\n }\n : T;\n\ntype AnySuspenseState = ToolkitSuspenseState<AnyMappedEntityState>;\n\nconst noop = () => undefined;\n\nconst DEFAULT_STATE: AnySuspenseState = {\n args: null,\n cachedResponse: null,\n callState: null,\n error: null,\n isError: false,\n isInit: false,\n isLoading: false,\n isSuccess: false,\n response: null,\n timestamp: null,\n refresh: noop,\n remove: noop,\n startPolling: noop,\n stopPolling: noop,\n};\n\nexport const suspenseState$ = (handle: AnyMappedEntityState): Observable<AnySuspenseState> =>\n combineLatest({\n args: handle.args$,\n cachedResponse: handle.cachedResponse$.pipe(startWith(null)),\n callState: handle.callState$,\n error: handle.error$,\n isError: handle.isError$,\n isInit: handle.isInit$,\n isLoading: handle.isLoading$,\n isSuccess: handle.isSuccess$,\n response: handle.response$,\n timestamp: handle.timestamp$,\n }).pipe(\n map((values) => ({\n ...values,\n refresh: handle.refresh,\n remove: handle.remove,\n startPolling: handle.startPolling,\n stopPolling: handle.stopPolling,\n })),\n );\n\n/** Subscribes to a toolkit handle and renders its current state, like the `suspense` pipe of `@tomtomb/ngrx-toolkit`. */\n@Pipe({ name: 'suspense', pure: false })\nexport class SuspensePipe implements PipeTransform {\n transform = createToolkitPipeTransform<AnyMappedEntityState, AnySuspenseState | null>({\n initialState: DEFAULT_STATE,\n disposedState: null,\n state$: suspenseState$,\n }) as <T extends AnyMappedEntityState>(value: T | null | undefined) => ToolkitSuspenseState<T>;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { combineLatest, map } from 'rxjs';\nimport { suspenseState$, ToolkitSuspenseState } from './suspense.pipe';\nimport { createToolkitPipeTransform } from './toolkit-pipe-transform';\nimport { AnyMappedEntityState } from './toolkit-types';\n\ntype AnyHandleRecord = Record<string, AnyMappedEntityState | null | undefined>;\n\nexport type ToolkitSuspenseMultiState<T extends AnyHandleRecord> = {\n [K in keyof T]: ToolkitSuspenseState<T[K]>;\n};\n\nconst suspenseMultiState$ = (handles: AnyHandleRecord) =>\n combineLatest(\n Object.entries(handles).flatMap(([key, handle]) =>\n handle ? [suspenseState$(handle).pipe(map((state) => [key, state] as const))] : [],\n ),\n ).pipe(map((states) => Object.fromEntries(states)));\n\n/**\n * Subscribes to a record of toolkit handles and renders each one's current state, like the `suspenseMulti` pipe of\n * `@tomtomb/ngrx-toolkit`. Nothing renders until every non-null handle has emitted.\n */\n@Pipe({ name: 'suspenseMulti', pure: false })\nexport class SuspenseMultiPipe implements PipeTransform {\n transform = createToolkitPipeTransform<AnyHandleRecord, Record<string, unknown>>({\n initialState: {},\n disposedState: {},\n state$: suspenseMultiState$,\n }) as <T extends AnyHandleRecord>(value: T | null | undefined) => ToolkitSuspenseMultiState<T>;\n}\n","import { NgModule } from '@angular/core';\nimport { SuspenseMultiPipe } from './suspense-multi.pipe';\nimport { SuspensePipe } from './suspense.pipe';\n\n/** Exports the `suspense` and `suspenseMulti` pipes, like the `NgRxToolkitModule` of `@tomtomb/ngrx-toolkit`. */\n@NgModule({\n imports: [SuspensePipe, SuspenseMultiPipe],\n exports: [SuspensePipe, SuspenseMultiPipe],\n})\nexport class NgRxToolkitModule {}\n","import { AnyQueryCreator, QueryArgsOf, QueryHeaders, ResponseType } from '@ethlete/query';\nimport { Observable, Subject } from 'rxjs';\n\n/** The call state of a toolkit handle, as `@tomtomb/ngrx-toolkit` names it. */\nexport const CallState = {\n INIT: 'INIT',\n LOADING: 'LOADING',\n SUCCESS: 'SUCCESS',\n ERROR: 'ERROR',\n} as const;\n\nexport type CallState = (typeof CallState)[keyof typeof CallState];\n\n/** The error shape of `@tomtomb/ngrx-toolkit`: the HTTP status, the error message and the response body. */\nexport type ToolkitError<T = unknown> = {\n status: number | string;\n message: string;\n data: T | null;\n};\n\nexport type ToolkitActionOptions = {\n headers?: QueryHeaders;\n extras?: { skipCache?: boolean };\n};\n\n/**\n * The toolkit-shaped args of a query creator: `queryParams` holds the path params, `params` the query string and\n * `body` the body, the way `@tomtomb/ngrx-toolkit` action groups named them.\n */\nexport type ActionCallArgs<TCreator extends AnyQueryCreator> = {\n [\n K in keyof QueryArgsOf<TCreator> as K extends 'pathParams'\n ? 'queryParams'\n : K extends 'queryParams'\n ? 'params'\n : K extends 'body'\n ? 'body'\n : never\n ]: QueryArgsOf<TCreator>[K];\n} & { actionOptions?: ToolkitActionOptions };\n\nexport type ToolkitPollingOptions = {\n intervalDuration: number;\n killSwitch: Subject<boolean>;\n};\n\n/** The handle `toolkitCall` returns, shaped like the `MappedEntityState` of `@tomtomb/ngrx-toolkit`. */\nexport type MappedEntityState<TCreator extends AnyQueryCreator> = {\n response$: Observable<ResponseType<QueryArgsOf<TCreator>> | null>;\n cachedResponse$: Observable<ResponseType<QueryArgsOf<TCreator>>>;\n error$: Observable<ToolkitError | null>;\n args$: Observable<ActionCallArgs<TCreator> | null>;\n isInit$: Observable<boolean | null>;\n isLoading$: Observable<boolean | null>;\n isSuccess$: Observable<boolean | null>;\n isError$: Observable<boolean | null>;\n timestamp$: Observable<number | null>;\n callState$: Observable<CallState | null>;\n refresh: () => void;\n remove: () => void;\n startPolling: (options: ToolkitPollingOptions) => void;\n stopPolling: () => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyMappedEntityState = MappedEntityState<any>;\n","import { computed, DestroyRef, effect, EnvironmentInjector, isDevMode, signal, untracked } from '@angular/core';\nimport {\n AnyQueryCreator,\n QueryArgsOf,\n QueryErrorResponse,\n QueryExecutionState,\n RequestArgs,\n ResponseType,\n} from '@ethlete/query';\nimport {\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n interval,\n map,\n Observable,\n of,\n startWith,\n Subject,\n Subscription,\n takeUntil,\n} from 'rxjs';\nimport {\n ActionCallArgs,\n AnyMappedEntityState,\n CallState,\n MappedEntityState,\n ToolkitError,\n ToolkitPollingOptions,\n} from './toolkit-types';\n\ntype ToolkitHandleSnapshot = {\n args: unknown;\n callState: CallState | null;\n response: unknown;\n error: ToolkitError | null;\n timestamp: number | null;\n};\n\nexport type ToolkitHandleEntry = {\n handle: AnyMappedEntityState;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call: (args: ActionCallArgs<any>) => void;\n releaseWhenSettled: () => void;\n};\n\nconst EMPTY_SNAPSHOT: ToolkitHandleSnapshot = {\n args: null,\n callState: null,\n response: null,\n error: null,\n timestamp: null,\n};\n\nconst toCallState = (state: QueryExecutionState<never> | null): CallState => {\n switch (state?.type) {\n case 'success':\n return CallState.SUCCESS;\n case 'failure':\n return CallState.ERROR;\n default:\n return CallState.LOADING;\n }\n};\n\nconst toToolkitError = (error: QueryErrorResponse): ToolkitError => ({\n status: error.raw.status,\n message: error.raw.message,\n data: error.raw.error ?? null,\n});\n\nconst handleReleasedMessage = (method: 'refresh' | 'startPolling') =>\n `${method}() was called on a toolkit handle that a newer toolkitCall() released. Args that cannot be hashed ` +\n `(FormData, Blob, Map, ...) never share a handle, so the next call for the same creator releases the previous ` +\n `handle once its request settles. The call was ignored - call toolkitCall() again with the args instead of ` +\n `reusing the old handle. This warning is shown once per handle.`;\n\nexport const toQueryArgs = (args: Record<string, unknown>) => {\n const actionOptions = args['actionOptions'] as { headers?: unknown } | undefined;\n const queryArgs: Record<string, unknown> = {};\n\n if (args['queryParams'] !== undefined) queryArgs['pathParams'] = args['queryParams'];\n if (args['params'] !== undefined) queryArgs['queryParams'] = args['params'];\n if (args['body'] !== undefined) queryArgs['body'] = args['body'];\n if (actionOptions?.headers !== undefined) queryArgs['headers'] = actionOptions.headers;\n\n return queryArgs as RequestArgs<never>;\n};\n\nexport const createToolkitHandle = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n injector: EnvironmentInjector,\n onSuccess: (response: unknown) => void,\n): ToolkitHandleEntry => {\n const query = creator({ injector, onlyManualExecution: true, silenceMissingWithArgsFeatureError: true });\n\n const calledArgs = signal<ActionCallArgs<TCreator> | null>(null);\n const toolkitError = computed(() => {\n const error = query.error();\n\n return error ? toToolkitError(error) : null;\n });\n const snapshot = computed<ToolkitHandleSnapshot>(() => {\n const currentArgs = calledArgs();\n\n if (!currentArgs) return EMPTY_SNAPSHOT;\n\n const state = query.executionState();\n const callState = toCallState(state);\n\n return {\n args: currentArgs,\n callState,\n response: state?.type === 'success' ? state.response : null,\n error: callState === CallState.ERROR ? toolkitError() : null,\n timestamp: Date.now(),\n };\n });\n\n const changes = new Subject<ToolkitHandleSnapshot>();\n\n let lastSuccess: QueryExecutionState<never> | null = null;\n\n const changesEffect = effect(\n () => {\n const current = snapshot();\n const state = query.executionState();\n\n untracked(() => {\n changes.next(current);\n\n if (current.callState === CallState.SUCCESS && state !== lastSuccess) {\n lastSuccess = state;\n onSuccess(current.response);\n }\n });\n },\n { injector },\n );\n\n let releasedSnapshot: ToolkitHandleSnapshot | null = null;\n let warnedAboutRelease = false;\n\n const ignoredAfterRelease = (method: 'refresh' | 'startPolling') => {\n if (!releasedSnapshot) return false;\n\n if (isDevMode() && !warnedAboutRelease) {\n warnedAboutRelease = true;\n console.warn(handleReleasedMessage(method));\n }\n\n return true;\n };\n\n const select = <T>(pick: (current: ToolkitHandleSnapshot) => T): Observable<T> =>\n defer(() => (releasedSnapshot ? of(releasedSnapshot) : changes.pipe(startWith(untracked(snapshot))))).pipe(\n map(pick),\n distinctUntilChanged(),\n );\n\n const call = (args: ActionCallArgs<TCreator>) => {\n calledArgs.set(args);\n query.execute({ args: toQueryArgs(args as Record<string, unknown>) });\n };\n\n const refresh = () => {\n if (ignoredAfterRelease('refresh')) return;\n\n const lastArgs = untracked(calledArgs);\n\n if (lastArgs) call(lastArgs);\n };\n\n let pollingSubscription = Subscription.EMPTY;\n\n const stopPolling = () => pollingSubscription.unsubscribe();\n\n const startPolling = ({ intervalDuration, killSwitch }: ToolkitPollingOptions) => {\n if (ignoredAfterRelease('startPolling') || !pollingSubscription.closed) return;\n\n pollingSubscription = interval(intervalDuration)\n .pipe(\n takeUntil(killSwitch),\n finalize(() => (pollingSubscription = Subscription.EMPTY)),\n )\n .subscribe(() => refresh());\n };\n\n const remove = () => {\n stopPolling();\n calledArgs.set(null);\n query.reset();\n };\n\n const removeDestroyListener = injector.get(DestroyRef).onDestroy(() => {\n stopPolling();\n changes.complete();\n });\n\n const release = () => {\n releasedSnapshot = untracked(snapshot);\n stopPolling();\n changesEffect.destroy();\n removeDestroyListener();\n changes.complete();\n query.subtle.destroy();\n };\n\n const releaseWhenSettled = () => {\n const releaseEffect = effect(\n () => {\n if (snapshot().callState === CallState.LOADING) return;\n\n releaseEffect.destroy();\n untracked(release);\n },\n { injector },\n );\n };\n\n type TResponse = ResponseType<QueryArgsOf<TCreator>>;\n\n const response$ = select((current) => current.response as TResponse | null);\n\n const handle: MappedEntityState<TCreator> = {\n response$,\n cachedResponse$: response$.pipe(filter((response): response is TResponse => !!response)),\n error$: select((current) => current.error),\n args$: select((current) => current.args as ActionCallArgs<TCreator> | null),\n isInit$: select((current) => current.callState === CallState.INIT),\n isLoading$: select((current) => current.callState === CallState.LOADING),\n isSuccess$: select((current) => current.callState === CallState.SUCCESS),\n isError$: select((current) => current.callState === CallState.ERROR),\n timestamp$: select((current) => current.timestamp),\n callState$: select((current) => current.callState),\n refresh,\n remove,\n startPolling,\n stopPolling,\n };\n\n return { handle, call, releaseWhenSettled };\n};\n","import { assertInInjectionContext, DestroyRef, EnvironmentInjector, inject, Injector } from '@angular/core';\nimport {\n AnyQueryCreator,\n QueryArgsOf,\n QueryHeaders,\n RequestArgs,\n ResponseType,\n resolveQueryHeaders,\n} from '@ethlete/query';\nimport { filter, map, Observable, Subject } from 'rxjs';\nimport { createToolkitHandle, ToolkitHandleEntry, toQueryArgs } from './toolkit-handle';\nimport { ActionCallArgs, MappedEntityState } from './toolkit-types';\n\nexport type ToolkitCallOptions = {\n /**\n * The injector the handle's query lives in. Required outside an injection context, which is where a\n * `providedIn: 'root'` facade calls from; pass the facade's `inject(Injector)`.\n */\n injector?: Injector;\n};\n\ntype ToolkitRegistry = {\n shared: WeakMap<AnyQueryCreator, Map<string, ToolkitHandleEntry>>;\n latestUnshared: WeakMap<AnyQueryCreator, ToolkitHandleEntry>;\n successes: Subject<{ creator: AnyQueryCreator; response: unknown }>;\n};\n\nconst registries = /* @__PURE__ */ new WeakMap<EnvironmentInjector, ToolkitRegistry>();\n\nclass UnhashableValueError extends Error {}\n\nconst isPlainObject = (value: object) => {\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n};\n\nconst hashableValue = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(hashableValue);\n if (typeof value !== 'object' || value === null) return value;\n if (value instanceof Date) return { '\\u0000date': value.getTime() };\n if (!isPlainObject(value)) throw new UnhashableValueError();\n\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, hashableValue((value as Record<string, unknown>)[key])]),\n );\n};\n\nconst hashableHeaders = (headers: QueryHeaders | undefined) => {\n const resolved = resolveQueryHeaders(headers);\n\n return resolved\n ?.keys()\n .map((name) => name.toLowerCase())\n .sort()\n .map((name) => [name, resolved.getAll(name)]);\n};\n\n/**\n * Returns `null` for args holding a value JSON cannot represent (FormData, Blob, Map, ...). Those never share a handle,\n * and each one is released once the next one for the same creator starts and its own call has settled.\n */\nconst hashArgs = (args: RequestArgs<never>) => {\n const { headers, ...rest } = args as { headers?: QueryHeaders };\n\n try {\n return JSON.stringify([hashableValue(rest), hashableHeaders(headers) ?? null]);\n } catch (error) {\n if (error instanceof UnhashableValueError) return null;\n\n throw error;\n }\n};\n\nconst resolveEnvironmentInjector = (fn: (...args: never[]) => unknown, options?: ToolkitCallOptions) => {\n if (options?.injector) return options.injector.get(EnvironmentInjector);\n\n assertInInjectionContext(fn);\n\n return inject(EnvironmentInjector);\n};\n\nconst registryOf = (injector: EnvironmentInjector) => {\n let registry = registries.get(injector);\n\n if (!registry) {\n const successes = new Subject<{ creator: AnyQueryCreator; response: unknown }>();\n\n registry = { shared: new WeakMap(), latestUnshared: new WeakMap(), successes };\n registries.set(injector, registry);\n injector.get(DestroyRef).onDestroy(() => successes.complete());\n }\n\n return registry;\n};\n\nconst handleFor = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n injector: EnvironmentInjector,\n registry: ToolkitRegistry,\n) => createToolkitHandle(creator, injector, (response) => registry.successes.next({ creator, response }));\n\nconst resolveEntry = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n args: ActionCallArgs<TCreator>,\n injector: EnvironmentInjector,\n) => {\n const registry = registryOf(injector);\n\n const key = hashArgs(toQueryArgs(args as Record<string, unknown>));\n\n if (key === null) {\n const entry = handleFor(creator, injector, registry);\n\n registry.latestUnshared.get(creator)?.releaseWhenSettled();\n registry.latestUnshared.set(creator, entry);\n\n return entry;\n }\n\n let entries = registry.shared.get(creator);\n\n if (!entries) {\n entries = new Map();\n registry.shared.set(creator, entries);\n }\n\n let entry = entries.get(key);\n\n if (!entry) {\n entry = handleFor(creator, injector, registry);\n entries.set(key, entry);\n }\n\n return entry;\n};\n\n/**\n * Returns the handle for a creator and args without executing it - the `FacadeBase.select(group, actionId)` of\n * `@tomtomb/ngrx-toolkit`. Args that build the same request (in any key order, other keys ignored) give the same\n * handle `toolkitCall` returns, so `toolkitSelect(getTeam, args, { injector }).refresh()` re-runs a request another\n * component started.\n */\nexport const toolkitSelect = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n args: ActionCallArgs<TCreator>,\n options?: ToolkitCallOptions,\n): MappedEntityState<TCreator> =>\n resolveEntry(creator, args, resolveEnvironmentInjector(toolkitSelect, options)).handle;\n\n/**\n * Executes a query creator with toolkit-shaped args and returns its handle - the `FacadeBase.call(group, args)` of\n * `@tomtomb/ngrx-toolkit`. Every call sends the request again, unless one with equal args is still in flight, which it\n * joins; equal args return the same handle, which lives as long as the injector.\n *\n * @example\n * ```ts\n * @Injectable({ providedIn: 'root' })\n * export class TeamFacade {\n * private injector = inject(Injector);\n *\n * getTeam(args: ActionCallArgs<typeof getTeam>) {\n * return toolkitCall(getTeam, args, { injector: this.injector });\n * }\n * }\n * ```\n */\nexport const toolkitCall = <TCreator extends AnyQueryCreator>(\n creator: TCreator,\n args: ActionCallArgs<TCreator>,\n options?: ToolkitCallOptions,\n): MappedEntityState<TCreator> => {\n const entry = resolveEntry(creator, args, resolveEnvironmentInjector(toolkitCall, options));\n\n entry.call(args);\n\n return entry.handle;\n};\n\ntype SuccessResponseOf<TCreator> = TCreator extends AnyQueryCreator ? ResponseType<QueryArgsOf<TCreator>> : never;\n\n/**\n * Emits the response every time a `toolkitCall` handle of one of the creators succeeds - the\n * `facade.on(action.success)` of `@tomtomb/ngrx-toolkit`. Only handles of the same environment injector count.\n *\n * @example\n * ```ts\n * toolkitOnSuccess([postAcceptClaim, postDeclineClaim])\n * .pipe(takeUntilDestroyed())\n * .subscribe(() => this.reloadRoster());\n * ```\n */\nexport const toolkitOnSuccess = <const TCreators extends AnyQueryCreator | readonly AnyQueryCreator[]>(\n creators: TCreators,\n options?: ToolkitCallOptions,\n): Observable<SuccessResponseOf<TCreators extends readonly AnyQueryCreator[] ? TCreators[number] : TCreators>> => {\n const watched = new Set<AnyQueryCreator>(Array.isArray(creators) ? creators : [creators as AnyQueryCreator]);\n\n return registryOf(resolveEnvironmentInjector(toolkitOnSuccess, options)).successes.pipe(\n filter((success) => watched.has(success.creator)),\n map((success) => success.response as never),\n );\n};\n","import { combineLatest, map, Observable } from 'rxjs';\nimport { ToolkitError } from './toolkit-types';\n\n/** Emits `true` while any of the given loading streams is `true`. Nullish entries are skipped. */\nexport const joinLoading = (observables: (Observable<boolean | null> | null | undefined)[]): Observable<boolean> =>\n combineLatest(observables.filter((o): o is Observable<boolean | null> => !!o)).pipe(\n map((values) => values.some((value) => !!value)),\n );\n\n/** Emits every non-null error of the given error streams, or `null` when there is none. Nullish entries are skipped. */\nexport const joinErrors = (\n observables: (Observable<ToolkitError | null> | null | undefined)[],\n): Observable<ToolkitError[] | null> =>\n combineLatest(observables.filter((o): o is Observable<ToolkitError | null> => !!o)).pipe(\n map((values) => {\n const errors = values.filter((value): value is ToolkitError => !!value);\n\n return errors.length ? errors : null;\n }),\n );\n"],"mappings":"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"}
|