@ethlete/query 6.0.0-next.24 → 6.0.0-next.26

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.
@@ -10,7 +10,6 @@ import { validateAsync, form } from '@angular/forms/signals';
10
10
  import * as i1 from '@angular/forms';
11
11
  import { FormControl, ReactiveFormsModule, FormGroup } from '@angular/forms';
12
12
  import { Router, ActivatedRoute } from '@angular/router';
13
- import { io } from 'socket.io-client';
14
13
 
15
14
  /**
16
15
  * Turns the features applied at creation into their devtools representation.
@@ -104,6 +103,20 @@ const setQueryDevtoolsFormLinksFactory = (fn) => {
104
103
  * @internal
105
104
  */
106
105
  const createQueryDevtoolsFormLinksRecorder = () => formLinksFactory?.() ?? null;
106
+ let overridesFactory = null;
107
+ /**
108
+ * Installs the overrides recorder factory. Called by `provideQueryDevtools()`; nothing else may call it.
109
+ * @internal
110
+ */
111
+ const setQueryDevtoolsOverridesFactory = (fn) => {
112
+ overridesFactory = fn;
113
+ };
114
+ /**
115
+ * An overrides recorder for one query, or `null` unless {@link provideQueryDevtools} has been called.
116
+ * Reached only from the provider for the same reason {@link createQueryDevtoolsStatsRecorder} is.
117
+ * @internal
118
+ */
119
+ const createQueryDevtoolsOverridesRecorder = () => overridesFactory?.() ?? null;
107
120
  /** The ids of the query forms read by the args build currently running, or `null` outside of one. */
108
121
  let formLinkSink = null;
109
122
  /**
@@ -277,6 +290,10 @@ const QueryRuntimeErrorCode = {
277
290
  QUERY_SEQUENCE_ALREADY_RUNNING: 900,
278
291
  // Legacy interop
279
292
  LEGACY_PREPARE_WITHOUT_INJECTION_CONTEXT: 950,
293
+ LEGACY_QUERY_STATE_ALREADY_HAS_KEY: 951,
294
+ LEGACY_QUERY_STATE_DOES_NOT_CONTAIN_KEY: 952,
295
+ LEGACY_QUERY_STATE_CANNOT_TRANSFORM: 953,
296
+ LEGACY_INVALID_BODY: 954,
280
297
  };
281
298
  const queryFeatureUsedMultipleTimes = (type) => {
282
299
  return new RuntimeError(QueryRuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES, `The query feature "${type}()" was used multiple times.`);
@@ -708,7 +725,10 @@ const withPageResetOnError = (options) => {
708
725
  const setupQueryState = (options) => {
709
726
  const request = signal(null, /* @ts-ignore */
710
727
  ...(ngDevMode ? [{ debugName: "request" }] : /* istanbul ignore next */ []));
711
- const rawResponse = linkedSignal(() => request()?.response() ?? null, /* @ts-ignore */
728
+ const rawResponse = linkedSignal(() => {
729
+ const raw = request()?.response() ?? null;
730
+ return options.devtoolsOverrides ? options.devtoolsOverrides.apply(raw) : raw;
731
+ }, /* @ts-ignore */
712
732
  ...(ngDevMode ? [{ debugName: "rawResponse" }] : /* istanbul ignore next */ []));
713
733
  const response = computed(() => {
714
734
  const raw = rawResponse();
@@ -974,10 +994,12 @@ const createBaseQuery = (options) => {
974
994
  return runInInjectionContext(deps.injector, () => {
975
995
  const devtoolsStats = createQueryDevtoolsStatsRecorder();
976
996
  const devtoolsFormLinks = createQueryDevtoolsFormLinksRecorder();
997
+ const devtoolsOverrides = createQueryDevtoolsOverridesRecorder();
977
998
  const state = setupQueryState({
978
999
  transformResponse: options.creator?.transformResponse,
979
1000
  devtoolsStats,
980
1001
  devtoolsFormLinks,
1002
+ devtoolsOverrides,
981
1003
  });
982
1004
  const flags = getQueryFeatureUsage(options);
983
1005
  const execute = options.executeFactory({
@@ -1001,7 +1023,7 @@ const createBaseQuery = (options) => {
1001
1023
  if (devtoolsStats) {
1002
1024
  const statsSubscription = state.events$.subscribe((event) => {
1003
1025
  if (event.type === 'error') {
1004
- devtoolsStats.recordError();
1026
+ devtoolsStats.recordError({ faulted: event.faulted });
1005
1027
  }
1006
1028
  else if (event.type === HttpEventType.Response) {
1007
1029
  devtoolsStats.recordResponse({ headers: event.headers, body: event.body });
@@ -1022,6 +1044,7 @@ const createBaseQuery = (options) => {
1022
1044
  clientRef: client,
1023
1045
  stats: devtoolsStats,
1024
1046
  formLinks: devtoolsFormLinks ?? undefined,
1047
+ overrides: devtoolsOverrides ?? undefined,
1025
1048
  route: options.creatorInternals.route ??
1026
1049
  options.creator?.route ??
1027
1050
  null,
@@ -1195,17 +1218,15 @@ const createBaseQueryCreator = (config) => {
1195
1218
  * Route building, query-string serialization and the token clock - shared by the current generation and
1196
1219
  * the legacy V2 client, which re-exports them under their original names.
1197
1220
  */
1198
- const buildErrorMessage = (code, message) => `[@ethlete\\query:${code}] ${message}`;
1199
- class QueryError extends Error {
1200
- constructor(code, message, data) {
1201
- super(buildErrorMessage(code, message));
1202
- this.name = 'QueryError';
1203
- this.data = data;
1204
- }
1205
- }
1206
- const invalidBaseRouteError = (data) => new QueryError('001', 'The baseRoute must not end with a slash', data);
1207
- const invalidRouteError = (data) => new QueryError('002', 'The route must start with a slash', data);
1208
- const pathParamsMissingInRouteFunctionError = (data) => new QueryError('003', 'The route is a function but pathParams are missing', data);
1221
+ // codes 1-99 of the shared 0-999 `@ethlete/query` range - see `query-errors.ts` for the rest
1222
+ const RouteRuntimeErrorCode = {
1223
+ INVALID_BASE_ROUTE: 1,
1224
+ INVALID_ROUTE: 2,
1225
+ PATH_PARAMS_MISSING_IN_ROUTE_FUNCTION: 3,
1226
+ };
1227
+ const invalidBaseRouteError = (data) => new RuntimeError(RouteRuntimeErrorCode.INVALID_BASE_ROUTE, 'The baseRoute must not end with a slash', data);
1228
+ const invalidRouteError = (data) => new RuntimeError(RouteRuntimeErrorCode.INVALID_ROUTE, 'The route must start with a slash', data);
1229
+ const pathParamsMissingInRouteFunctionError = (data) => new RuntimeError(RouteRuntimeErrorCode.PATH_PARAMS_MISSING_IN_ROUTE_FUNCTION, 'The route is a function but pathParams are missing', data);
1209
1230
  const isNaN$1 = (value) => typeof value === 'number' && Number.isNaN(value);
1210
1231
  const isEmptyString = (value) => typeof value === 'string' && value.trim() === '';
1211
1232
  const buildQueryString = (params, config) => {
@@ -1524,6 +1545,11 @@ const createHttpRequest = (options) => {
1524
1545
  ...(ngDevMode ? [{ debugName: "attempts" }] : /* istanbul ignore next */ []));
1525
1546
  const retryState = signal(null, /* @ts-ignore */
1526
1547
  ...(ngDevMode ? [{ debugName: "retryState" }] : /* istanbul ignore next */ []));
1548
+ const lastDurationMs = signal(null, /* @ts-ignore */
1549
+ ...(ngDevMode ? [{ debugName: "lastDurationMs" }] : /* istanbul ignore next */ []));
1550
+ // Set at the top of every `sendWithFaults` attempt (including unfaulted ones), so it always reflects
1551
+ // whichever attempt most recently settled - not just the first one, or a stale earlier attempt's fault.
1552
+ let lastAttemptFaulted = false;
1527
1553
  // NOTE: This must be a plain function, not a `computed`. The freshness check compares against
1528
1554
  // `Date.now()`, which is not reactive, so a memoized computed would only ever recompute when
1529
1555
  // `expiresIn` changes - once it evaluated to `false` (fresh) it would stay `false` forever, even
@@ -1572,6 +1598,7 @@ const createHttpRequest = (options) => {
1572
1598
  method: options.method,
1573
1599
  url: options.fullPath,
1574
1600
  });
1601
+ lastAttemptFaulted = !!fault && fault.status !== null;
1575
1602
  if (!fault)
1576
1603
  return send(headers);
1577
1604
  const { status } = fault;
@@ -1621,6 +1648,7 @@ const createHttpRequest = (options) => {
1621
1648
  currentStreamSubscription.unsubscribe();
1622
1649
  lastExecuteTime.set(Date.now());
1623
1650
  lastLoadEventTime.set(lastExecuteTime());
1651
+ lastLoadEventAmount.set(0);
1624
1652
  loading.set({
1625
1653
  executeTime: lastExecuteTime(),
1626
1654
  progress: null,
@@ -1653,6 +1681,7 @@ const createHttpRequest = (options) => {
1653
1681
  {
1654
1682
  loading.set(null);
1655
1683
  response.set(event.body);
1684
+ lastDurationMs.set(Date.now() - lastExecuteTime());
1656
1685
  const expiresInSeconds = options.cacheAdapter
1657
1686
  ? options.cacheAdapter(event.headers)
1658
1687
  : extractExpiresInSeconds(event.headers);
@@ -1681,7 +1710,8 @@ const createHttpRequest = (options) => {
1681
1710
  const errorRes = createQueryErrorResponse(errorResponse);
1682
1711
  error.set(errorRes);
1683
1712
  loading.set(null);
1684
- const errorEvent = { type: 'error', error: errorRes };
1713
+ lastDurationMs.set(Date.now() - lastExecuteTime());
1714
+ const errorEvent = { type: 'error', error: errorRes, faulted: lastAttemptFaulted };
1685
1715
  currentEvent.set(errorEvent);
1686
1716
  event$.next(errorEvent);
1687
1717
  options.dependencies.ngErrorHandler.handleError(errorRes.raw);
@@ -1705,15 +1735,21 @@ const createHttpRequest = (options) => {
1705
1735
  const elapsedTimeSinceLastEvent = currentTime - lastLoadEventTime();
1706
1736
  const elapsedTimeSinceLastExecute = currentTime - lastExecuteTime();
1707
1737
  const loadedAmount = event.loaded - lastLoadEventAmount();
1738
+ // An event in the same millisecond as the last one, or one that carries no new bytes, has no rate
1739
+ // to report - dividing by either zero yields Infinity or NaN. Such an event also keeps the
1740
+ // baseline where it is, so the next one measures across the wider window instead of restarting.
1741
+ const isMeasurable = elapsedTimeSinceLastEvent > 0 && loadedAmount > 0;
1708
1742
  // We only want to calculate speed and remaining time after 2 seconds of the execution
1709
1743
  // This is to avoid showing incorrect speed and remaining time when the request is very fast
1710
- if (elapsedTimeSinceLastExecute > SPEED_BUFFER_TIME_IN_MS) {
1711
- const speed = (loadedAmount / elapsedTimeSinceLastEvent) * 1000;
1712
- progress.speed = speed * 1000;
1713
- progress.remainingTime = Math.round((event.total - event.loaded) / speed) * 1000;
1744
+ if (isMeasurable && elapsedTimeSinceLastExecute > SPEED_BUFFER_TIME_IN_MS) {
1745
+ const bytesPerSecond = (loadedAmount / elapsedTimeSinceLastEvent) * 1000;
1746
+ progress.speed = bytesPerSecond;
1747
+ progress.remainingTime = Math.round((event.total - event.loaded) / bytesPerSecond) * 1000;
1748
+ }
1749
+ if (isMeasurable) {
1750
+ lastLoadEventTime.set(currentTime);
1751
+ lastLoadEventAmount.set(event.loaded);
1714
1752
  }
1715
- lastLoadEventTime.set(currentTime);
1716
- lastLoadEventAmount.set(event.loaded);
1717
1753
  loading.set(state);
1718
1754
  };
1719
1755
  const lastExternalResponseAt = signal(null, /* @ts-ignore */
@@ -1752,6 +1788,7 @@ const createHttpRequest = (options) => {
1752
1788
  resolveHeaders,
1753
1789
  attempts: attempts.asReadonly(),
1754
1790
  retryState: retryState.asReadonly(),
1791
+ lastDurationMs: lastDurationMs.asReadonly(),
1755
1792
  },
1756
1793
  };
1757
1794
  return httpRequest;
@@ -4219,7 +4256,7 @@ const deriveExecutionStateType = (builder, triggeredBy) => {
4219
4256
  return 'revocation';
4220
4257
  return builder.key;
4221
4258
  };
4222
- const setupBearerQueryRegistry = (builders, injector, latestExecutedQuery, latestNonInternalQuery, setTokens, executionState) => {
4259
+ const setupBearerQueryRegistry = (builders, injector, latestExecutedQuery, latestNonInternalQuery, applyTokens, executionState) => {
4223
4260
  const queries = {};
4224
4261
  const querySnapshots = new Map();
4225
4262
  for (const builder of builders) {
@@ -4237,7 +4274,7 @@ const setupBearerQueryRegistry = (builders, injector, latestExecutedQuery, lates
4237
4274
  if (response && !loading && !error) {
4238
4275
  try {
4239
4276
  const tokens = extractTokens(response);
4240
- setTokens(tokens.accessToken, tokens.refreshToken);
4277
+ applyTokens(tokens.accessToken, tokens.refreshToken);
4241
4278
  }
4242
4279
  catch (extractError) {
4243
4280
  if (isDevMode()) {
@@ -4370,12 +4407,19 @@ const createBearerAuthProviderImpl = (config) => {
4370
4407
  ...(ngDevMode ? [{ debugName: "latestNonInternalQuery" }] : /* istanbul ignore next */ []));
4371
4408
  const executionState = signal(null, /* @ts-ignore */
4372
4409
  ...(ngDevMode ? [{ debugName: "executionState" }] : /* istanbul ignore next */ []));
4373
- const setTokens = (access, refresh) => {
4410
+ const applyTokens = (access, refresh) => {
4374
4411
  accessToken.set(access);
4375
4412
  refreshToken.set(refresh);
4376
4413
  afterTokenRefresh$.next();
4377
4414
  };
4378
- const { queries } = setupBearerQueryRegistry(config.queries, injector, latestExecutedQuery, latestNonInternalQuery, setTokens, executionState);
4415
+ // Public entry point only - a query-driven login already reports its own, more specific
4416
+ // executionState (e.g. `{ type: 'login', state: 'success' }`) via setupBearerQueryRegistry's
4417
+ // execute(), so that internal path calls applyTokens directly to avoid stomping it with this.
4418
+ const setTokens = (access, refresh) => {
4419
+ applyTokens(access, refresh);
4420
+ executionState.set({ type: 'tokenSeed', state: 'success' });
4421
+ };
4422
+ const { queries } = setupBearerQueryRegistry(config.queries, injector, latestExecutedQuery, latestNonInternalQuery, applyTokens, executionState);
4379
4423
  const logout = () => {
4380
4424
  accessToken.set(null);
4381
4425
  refreshToken.set(null);
@@ -5404,6 +5448,325 @@ const createQueryDevtoolsFormLinks = () => {
5404
5448
  };
5405
5449
  };
5406
5450
 
5451
+ const pathsEqual = (a, b) => a.length === b.length && a.every((step, index) => step === b[index]);
5452
+ /**
5453
+ * Walks `path` into `root`, stopping as soon as a step's container doesn't exist. An empty path
5454
+ * resolves to `root` itself, which is how an op targets the response's top-level value.
5455
+ */
5456
+ const resolvePath = (root, path) => {
5457
+ if (path.length === 0)
5458
+ return { ok: true, exists: true, value: root };
5459
+ let current = root;
5460
+ for (let index = 0; index < path.length - 1; index++) {
5461
+ if (current === null || typeof current !== 'object')
5462
+ return { ok: false };
5463
+ const step = path[index];
5464
+ const container = current;
5465
+ if (!(step in container))
5466
+ return { ok: false };
5467
+ current = container[step];
5468
+ }
5469
+ if (current === null || typeof current !== 'object')
5470
+ return { ok: false };
5471
+ const key = path[path.length - 1];
5472
+ const container = current;
5473
+ const exists = key in container;
5474
+ return { ok: true, exists, value: exists ? container[key] : undefined };
5475
+ };
5476
+ /**
5477
+ * Returns a copy of `root` with `value` written at `path`, cloning only the containers along the way -
5478
+ * every sibling branch keeps its original reference. The final path segment does not need to already
5479
+ * exist (a `set` can add a new key); every segment before it does.
5480
+ */
5481
+ const withValueAtPath = (root, path, value) => {
5482
+ if (path.length === 0)
5483
+ return value;
5484
+ const [head, ...rest] = path;
5485
+ if (Array.isArray(root)) {
5486
+ const next = [...root];
5487
+ next[head] = withValueAtPath(root[head], rest, value);
5488
+ return next;
5489
+ }
5490
+ const container = root && typeof root === 'object' ? root : {};
5491
+ return { ...container, [head]: withValueAtPath(container[head], rest, value) };
5492
+ };
5493
+ const IDENTITY_KEY_PATTERNS = [/^id$/i, /(^|[a-z])Id$/, /^uuid$/i, /^key$/i];
5494
+ const isIdentityKey = (key) => IDENTITY_KEY_PATTERNS.some((pattern) => pattern.test(key));
5495
+ /** Whether every sibling in `array` that has `key` holds a distinct string/number value for it. */
5496
+ const isSiblingUniqueKey = (array, key) => {
5497
+ const seen = new Set();
5498
+ for (const item of array) {
5499
+ const value = item?.[key];
5500
+ if (value === undefined)
5501
+ continue;
5502
+ if (typeof value !== 'string' && typeof value !== 'number')
5503
+ return false;
5504
+ if (seen.has(value))
5505
+ return false;
5506
+ seen.add(value);
5507
+ }
5508
+ return seen.size > 0;
5509
+ };
5510
+ const nextNumericId = (array, key) => {
5511
+ let max = -Infinity;
5512
+ for (const item of array) {
5513
+ const value = item?.[key];
5514
+ if (typeof value === 'number' && value > max)
5515
+ max = value;
5516
+ }
5517
+ return Number.isFinite(max) ? max + 1 : 1;
5518
+ };
5519
+ const nextStringId = (array, key, base) => {
5520
+ const existing = new Set(array.map((item) => item?.[key]));
5521
+ let suffix = 1;
5522
+ while (existing.has(`${base}-copy-${suffix}`))
5523
+ suffix++;
5524
+ return `${base}-copy-${suffix}`;
5525
+ };
5526
+ /**
5527
+ * Clones `item` (a plain object array element) with every identity-shaped field replaced by a fresh
5528
+ * value, so a duplicated row never collides with the one it was copied from. A field counts as identity
5529
+ * when its key looks like one (`id`, `fooId`, `uuid`, `key`) or every sibling in `siblings` holds a
5530
+ * distinct value for it - without this, `track` bindings and detail-by-id lookups can't tell the copy
5531
+ * from the original.
5532
+ */
5533
+ const smartDuplicateArrayItem = (item, siblings) => {
5534
+ if (!item || typeof item !== 'object' || Array.isArray(item))
5535
+ return item;
5536
+ const source = item;
5537
+ const result = { ...source };
5538
+ for (const key of Object.keys(source)) {
5539
+ const value = source[key];
5540
+ if (!isIdentityKey(key) && !isSiblingUniqueKey(siblings, key))
5541
+ continue;
5542
+ if (typeof value === 'number')
5543
+ result[key] = nextNumericId(siblings, key);
5544
+ else if (typeof value === 'string')
5545
+ result[key] = nextStringId(siblings, key, value);
5546
+ }
5547
+ return result;
5548
+ };
5549
+ const duplicateOneArrayItem = (array, index) => {
5550
+ const copy = smartDuplicateArrayItem(array[index], array);
5551
+ const next = [...array];
5552
+ next.splice(index + 1, 0, copy);
5553
+ return next;
5554
+ };
5555
+ const duplicateWholeArray = (array) => {
5556
+ let result = [...array];
5557
+ for (const item of array)
5558
+ result = [...result, smartDuplicateArrayItem(item, result)];
5559
+ return result;
5560
+ };
5561
+ /**
5562
+ * Whether `value` structurally matches one of the pagination shapes shrink/extend know how to resize -
5563
+ * an `items` array plus a recognized combination of total/page/limit counters. Exported so the panel's
5564
+ * menu can offer shrink/extend only where it would actually apply.
5565
+ */
5566
+ const detectPaginationShape = (value) => {
5567
+ if (!value || typeof value !== 'object' || Array.isArray(value))
5568
+ return null;
5569
+ const obj = value;
5570
+ if (!Array.isArray(obj['items']))
5571
+ return null;
5572
+ const hasNumbers = (...keys) => keys.every((key) => typeof obj[key] === 'number');
5573
+ if (hasNumbers('totalHits', 'currentPage', 'totalPageCount', 'itemsPerPage'))
5574
+ return 'gg-like';
5575
+ if (hasNumbers('totalHits', 'currentPage', 'totalPages', 'limit'))
5576
+ return 'dyn-like';
5577
+ if (hasNumbers('totalPages', 'totalHits', 'currentPage', 'itemsPerPage'))
5578
+ return 'normalized';
5579
+ if (hasNumbers('limit', 'skip', 'total'))
5580
+ return 'contentful-gql-like';
5581
+ return null;
5582
+ };
5583
+ const DATE_KEY_PATTERN = /date|At$|Timestamp/i;
5584
+ const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/;
5585
+ /**
5586
+ * Whether a leaf is offered date presets instead of string presets: its key looks date-shaped
5587
+ * (`date`, `fooAt`, `fooTimestamp`) and its value round-trips through `Date.parse`, or the value
5588
+ * itself matches an ISO-8601 date/datetime pattern regardless of what its key is called. Exported so
5589
+ * the panel's menu can decide which preset list to show without duplicating the check.
5590
+ */
5591
+ const isDateShapedLeaf = (key, value) => {
5592
+ if (typeof value !== 'string')
5593
+ return false;
5594
+ if (typeof key === 'string' && DATE_KEY_PATTERN.test(key) && !Number.isNaN(Date.parse(value)))
5595
+ return true;
5596
+ return ISO_DATE_PATTERN.test(value);
5597
+ };
5598
+ /**
5599
+ * Every path under `value` (relative to it, not absolute) whose leaf is of `kind` - the paths a "fill
5600
+ * recursively" menu action turns into one `set`-family op each. Exported so the panel's menu builds the
5601
+ * op list with the exact same walk the docs describe, rather than a second, possibly-drifted one.
5602
+ */
5603
+ const collectLeafPaths = (value, kind) => {
5604
+ const paths = [];
5605
+ const walk = (node, path) => {
5606
+ if (Array.isArray(node)) {
5607
+ node.forEach((item, index) => walk(item, [...path, index]));
5608
+ return;
5609
+ }
5610
+ if (node && typeof node === 'object') {
5611
+ for (const [key, child] of Object.entries(node))
5612
+ walk(child, [...path, key]);
5613
+ return;
5614
+ }
5615
+ if (typeof node === kind)
5616
+ paths.push(path);
5617
+ };
5618
+ walk(value, []);
5619
+ return paths;
5620
+ };
5621
+ const resizePagination = (value, shape, mode, amount) => {
5622
+ const items = value['items'];
5623
+ let nextItems;
5624
+ if (mode === 'shrink') {
5625
+ nextItems = items.slice(0, Math.max(0, items.length - amount));
5626
+ }
5627
+ else if (items.length === 0) {
5628
+ // Nothing to clone a new item from - degrade to a no-op rather than inventing data out of thin air.
5629
+ nextItems = items;
5630
+ }
5631
+ else {
5632
+ nextItems = items;
5633
+ for (let i = 0; i < amount; i++) {
5634
+ nextItems = [...nextItems, smartDuplicateArrayItem(items[i % items.length], nextItems)];
5635
+ }
5636
+ }
5637
+ const delta = nextItems.length - items.length;
5638
+ const result = { ...value, items: nextItems };
5639
+ if (shape === 'gg-like') {
5640
+ result['totalHits'] = value['totalHits'] + delta;
5641
+ result['totalPageCount'] = Math.max(1, Math.ceil(result['totalHits'] / (value['itemsPerPage'] || 1)));
5642
+ }
5643
+ else if (shape === 'dyn-like') {
5644
+ result['totalHits'] = value['totalHits'] + delta;
5645
+ result['totalPages'] = Math.max(1, Math.ceil(result['totalHits'] / (value['limit'] || 1)));
5646
+ }
5647
+ else if (shape === 'normalized') {
5648
+ result['totalHits'] = value['totalHits'] + delta;
5649
+ result['totalPages'] = Math.max(1, Math.ceil(result['totalHits'] / (value['itemsPerPage'] || 1)));
5650
+ }
5651
+ else {
5652
+ result['total'] = value['total'] + delta;
5653
+ }
5654
+ return result;
5655
+ };
5656
+ const STRING_PRESETS = {
5657
+ short: 'Ab',
5658
+ long: /* @__PURE__ */ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. '.repeat(4),
5659
+ unicode: 'مرحبا بالعالم 👋 日本語テスト 🎉 Ñoño',
5660
+ };
5661
+ const stringPresetValue = (preset, custom) => preset === 'custom' ? (custom ?? '') : STRING_PRESETS[preset];
5662
+ const NUMBER_PRESETS = {
5663
+ zero: 0,
5664
+ negative: -1,
5665
+ huge: Number.MAX_SAFE_INTEGER,
5666
+ };
5667
+ const numberPresetValue = (preset, custom) => preset === 'custom' ? (custom ?? 0) : NUMBER_PRESETS[preset];
5668
+ const DAY_MS = 24 * 60 * 60 * 1000;
5669
+ /** `invalid` is deliberately unparseable - "the API sent a date my code can't parse" is a real bug class. */
5670
+ const datePresetValue = (preset) => {
5671
+ switch (preset) {
5672
+ case 'now':
5673
+ return new Date().toISOString();
5674
+ case 'plusDay':
5675
+ return new Date(Date.now() + DAY_MS).toISOString();
5676
+ case 'minusDay':
5677
+ return new Date(Date.now() - DAY_MS).toISOString();
5678
+ case 'farFuture':
5679
+ return new Date('2099-01-01T00:00:00.000Z').toISOString();
5680
+ case 'farPast':
5681
+ return new Date(0).toISOString();
5682
+ case 'invalid':
5683
+ return 'not-a-date';
5684
+ }
5685
+ };
5686
+ const applyOp = (root, op) => {
5687
+ if (op.type === 'reset')
5688
+ return { root, ok: true };
5689
+ const resolution = resolvePath(root, op.path);
5690
+ if (!resolution.ok)
5691
+ return { root, ok: false };
5692
+ switch (op.type) {
5693
+ case 'set':
5694
+ return { root: withValueAtPath(root, op.path, op.value), ok: true };
5695
+ case 'booleanFlip':
5696
+ if (!resolution.exists || typeof resolution.value !== 'boolean')
5697
+ return { root, ok: false };
5698
+ return { root: withValueAtPath(root, op.path, !resolution.value), ok: true };
5699
+ case 'stringPreset':
5700
+ if (!resolution.exists)
5701
+ return { root, ok: false };
5702
+ return { root: withValueAtPath(root, op.path, stringPresetValue(op.preset, op.custom)), ok: true };
5703
+ case 'numberPreset':
5704
+ if (!resolution.exists)
5705
+ return { root, ok: false };
5706
+ return { root: withValueAtPath(root, op.path, numberPresetValue(op.preset, op.custom)), ok: true };
5707
+ case 'datePreset':
5708
+ if (!resolution.exists)
5709
+ return { root, ok: false };
5710
+ return { root: withValueAtPath(root, op.path, datePresetValue(op.preset)), ok: true };
5711
+ case 'duplicateArrayItem':
5712
+ if (!Array.isArray(resolution.value) || op.index < 0 || op.index >= resolution.value.length) {
5713
+ return { root, ok: false };
5714
+ }
5715
+ return { root: withValueAtPath(root, op.path, duplicateOneArrayItem(resolution.value, op.index)), ok: true };
5716
+ case 'duplicateArray':
5717
+ if (!Array.isArray(resolution.value))
5718
+ return { root, ok: false };
5719
+ return { root: withValueAtPath(root, op.path, duplicateWholeArray(resolution.value)), ok: true };
5720
+ case 'paginationResize': {
5721
+ const shape = detectPaginationShape(resolution.value);
5722
+ if (!shape)
5723
+ return { root, ok: false };
5724
+ return {
5725
+ root: withValueAtPath(root, op.path, resizePagination(resolution.value, shape, op.mode, op.amount)),
5726
+ ok: true,
5727
+ };
5728
+ }
5729
+ }
5730
+ };
5731
+ /**
5732
+ * Replays `entries` against `raw`, in order, and reports which ones no longer resolve. Shared by the
5733
+ * pipeline (which only needs {@link value}) and the panel's menu (which previews a value and marks stale
5734
+ * ops before arming a new one) - one implementation, so the two cannot drift.
5735
+ */
5736
+ const applyQueryDevtoolsOverrides = (entries, raw) => {
5737
+ let root = raw;
5738
+ const staleIds = [];
5739
+ for (const entry of entries) {
5740
+ const applied = applyOp(root, entry.op);
5741
+ root = applied.root;
5742
+ if (!applied.ok)
5743
+ staleIds.push(entry.id);
5744
+ }
5745
+ return { value: root, staleIds };
5746
+ };
5747
+ /**
5748
+ * Accumulates the response overrides armed on one query, for the devtools panel. Only ever created
5749
+ * while {@link provideQueryDevtools} is installed - like {@link createQueryDevtoolsStats}, an app
5750
+ * without devtools pays nothing for it.
5751
+ * @internal
5752
+ */
5753
+ const createQueryDevtoolsOverrides = () => {
5754
+ const list = signal([], /* @ts-ignore */
5755
+ ...(ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []));
5756
+ let counter = 0;
5757
+ const arm = (op) => {
5758
+ if (op.type === 'reset') {
5759
+ list.update((current) => current.filter((entry) => !pathsEqual(entry.op.path, op.path)));
5760
+ return;
5761
+ }
5762
+ list.update((current) => [...current, { id: `override-${++counter}`, op }]);
5763
+ };
5764
+ const clear = (id) => list.update((current) => current.filter((entry) => entry.id !== id));
5765
+ const clearAll = () => list.set([]);
5766
+ const apply = (raw) => applyQueryDevtoolsOverrides(list(), raw).value;
5767
+ return { list: list.asReadonly(), arm, clear, clearAll, apply };
5768
+ };
5769
+
5407
5770
  const EMPTY_STATS = {
5408
5771
  executions: 0,
5409
5772
  requests: 0,
@@ -5417,6 +5780,7 @@ const EMPTY_STATS = {
5417
5780
  lastResponseAt: null,
5418
5781
  lastDurationMs: null,
5419
5782
  totalDurationMs: 0,
5783
+ lastResponseWasFaulted: false,
5420
5784
  };
5421
5785
  const textEncoder = typeof TextEncoder === 'function' ? /* @__PURE__ */ new TextEncoder() : null;
5422
5786
  const byteLengthOf = (text) => textEncoder?.encode(text).length ?? text.length;
@@ -5474,7 +5838,9 @@ const trimRetainedResponses = (runs) => {
5474
5838
  /**
5475
5839
  * The size of a payload in bytes, and whether that size is the one that went over the wire. Only a
5476
5840
  * `content-length` header is exact; everything else is measured by serializing the body.
5477
- * @internal
5841
+ *
5842
+ * Part of the devtools contract - the panel measures the cache and the event log with it. **Not part of
5843
+ * the general public contract.**
5478
5844
  */
5479
5845
  const measureQueryDevtoolsPayload = (payload) => {
5480
5846
  const contentLength = Number(payload.headers?.get('content-length'));
@@ -5559,6 +5925,7 @@ const createQueryDevtoolsStats = () => {
5559
5925
  lastResponseAt: now,
5560
5926
  lastDurationMs: duration,
5561
5927
  totalDurationMs: current.totalDurationMs + (duration ?? 0),
5928
+ lastResponseWasFaulted: false,
5562
5929
  }));
5563
5930
  endRun({
5564
5931
  endedAt: now,
@@ -5568,8 +5935,12 @@ const createQueryDevtoolsStats = () => {
5568
5935
  hasResponse: true,
5569
5936
  });
5570
5937
  };
5571
- const recordError = () => {
5572
- stats.update((current) => ({ ...current, errors: current.errors + 1 }));
5938
+ const recordError = (options) => {
5939
+ stats.update((current) => ({
5940
+ ...current,
5941
+ errors: current.errors + 1,
5942
+ lastResponseWasFaulted: options?.faulted ?? false,
5943
+ }));
5573
5944
  endRun({ endedAt: Date.now(), status: 'error', receivedBytes: 0, response: null, hasResponse: false });
5574
5945
  };
5575
5946
  const recordRetry = ({ attempt }) => {
@@ -5749,6 +6120,7 @@ const registerEntry = (registration) => {
5749
6120
  createdAt: Date.now(),
5750
6121
  stats: registration.stats,
5751
6122
  formLinks: registration.formLinks,
6123
+ overrides: registration.overrides,
5752
6124
  };
5753
6125
  entries.update((list) => [...list, fullEntry]);
5754
6126
  return () => entries.update((list) => list.filter((e) => e.id !== fullEntry.id));
@@ -5772,6 +6144,7 @@ const provideQueryDevtools = () => {
5772
6144
  setQueryDevtoolsRegistrar(registerEntry);
5773
6145
  setQueryDevtoolsStatsFactory(createQueryDevtoolsStats);
5774
6146
  setQueryDevtoolsFormLinksFactory(createQueryDevtoolsFormLinks);
6147
+ setQueryDevtoolsOverridesFactory(createQueryDevtoolsOverrides);
5775
6148
  setQueryDevtoolsFaultResolver(resolveQueryDevtoolsFaultForAttempt);
5776
6149
  if (!isDevMode()) {
5777
6150
  console.warn('You are using the Query Devtools in production mode. This increases the size of your bundle and should only be used for development purposes.');
@@ -9523,19 +9896,19 @@ const removeFrom = (store, { where, id }) => {
9523
9896
  /**
9524
9897
  * @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.
9525
9898
  */
9526
- const queryStateAlreadyHasKeyError = (data) => new QueryError('004', 'The query state already contains the provided key', data);
9899
+ const queryStateAlreadyHasKeyError = (data) => new RuntimeError(QueryRuntimeErrorCode.LEGACY_QUERY_STATE_ALREADY_HAS_KEY, 'The query state already contains the provided key', data);
9527
9900
  /**
9528
9901
  * @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.
9529
9902
  */
9530
- const queryStateDoesNotContainKeyError = (data) => new QueryError('005', 'The query state does not contain the provided key', data);
9903
+ const queryStateDoesNotContainKeyError = (data) => new RuntimeError(QueryRuntimeErrorCode.LEGACY_QUERY_STATE_DOES_NOT_CONTAIN_KEY, 'The query state does not contain the provided key', data);
9531
9904
  /**
9532
9905
  * @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.
9533
9906
  */
9534
- const queryStateCannotTransformError = (data) => new QueryError('006', 'The query state cannot be transformed because it is not loading', data);
9907
+ const queryStateCannotTransformError = (data) => new RuntimeError(QueryRuntimeErrorCode.LEGACY_QUERY_STATE_CANNOT_TRANSFORM, 'The query state cannot be transformed because it is not loading', data);
9535
9908
  /**
9536
9909
  * @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.
9537
9910
  */
9538
- const invalidBodyError = (data) => new QueryError('007', 'The body is not valid or upsupported', data);
9911
+ const invalidBodyError = (data) => new RuntimeError(QueryRuntimeErrorCode.LEGACY_INVALID_BODY, 'The body is not valid or upsupported', data);
9539
9912
 
9540
9913
  /**
9541
9914
  * Binds a query-backed async validator to a signal-forms field, adapting a **legacy v2**
@@ -11145,7 +11518,7 @@ const messageMalformed = () => {
11145
11518
  const MAX_DEVTOOLS_MESSAGES = 100;
11146
11519
  const createWebSocketClient = (options) => {
11147
11520
  return defineRootProvider(() => {
11148
- const socket = io(options.url, {
11521
+ const socket = options.io(options.url, {
11149
11522
  withCredentials: true,
11150
11523
  autoConnect: false,
11151
11524
  transports: options.transports,
@@ -11164,13 +11537,28 @@ const createWebSocketClient = (options) => {
11164
11537
  if (devtoolsEnabled)
11165
11538
  devtoolsRooms.set([...rooms.keys()]);
11166
11539
  };
11540
+ const recordDevtoolsMessage = (message) => {
11541
+ if (!devtoolsEnabled)
11542
+ return;
11543
+ devtoolsMessages.update((log) => [{ ...message, id: devtoolsMessageId++, timestamp: Date.now() }, ...log].slice(0, MAX_DEVTOOLS_MESSAGES));
11544
+ };
11545
+ /** Every outgoing message goes through here, so the devtools log covers both directions. */
11546
+ const emit = (message) => {
11547
+ socket.emit(message.event, message.data);
11548
+ recordDevtoolsMessage({
11549
+ room: message.room ?? '',
11550
+ event: message.event,
11551
+ data: message.data,
11552
+ direction: 'out',
11553
+ });
11554
+ };
11167
11555
  const joinRoom = (room) => {
11168
11556
  const roomFn = typeof room === 'function' ? room : () => room;
11169
11557
  const pre = previousSignalValue(computed(() => roomFn()));
11170
11558
  const roomData = signal(null, /* @ts-ignore */
11171
11559
  ...(ngDevMode ? [{ debugName: "roomData" }] : /* istanbul ignore next */ []));
11172
11560
  const join = (name) => {
11173
- socket.emit('join-room', name);
11561
+ emit({ event: 'join-room', data: name, room: name });
11174
11562
  const existingRoom = rooms.get(name);
11175
11563
  if (existingRoom)
11176
11564
  return existingRoom;
@@ -11215,7 +11603,7 @@ const createWebSocketClient = (options) => {
11215
11603
  if (isDevMode())
11216
11604
  throw roomNotJoined(room);
11217
11605
  }
11218
- socket.emit('leave-room', room);
11606
+ emit({ event: 'leave-room', data: room, room });
11219
11607
  rooms.delete(room);
11220
11608
  syncDevtoolsRooms();
11221
11609
  };
@@ -11223,7 +11611,7 @@ const createWebSocketClient = (options) => {
11223
11611
  socket.on('connect', () => {
11224
11612
  isConnected.set(true);
11225
11613
  for (const room of rooms.keys()) {
11226
- socket.emit('join-room', room);
11614
+ emit({ event: 'join-room', data: room, room });
11227
11615
  }
11228
11616
  });
11229
11617
  socket.on('disconnect', () => isConnected.set(false));
@@ -11232,16 +11620,7 @@ const createWebSocketClient = (options) => {
11232
11620
  socket.onAny((data) => {
11233
11621
  try {
11234
11622
  const json = JSON.parse(data);
11235
- if (devtoolsEnabled) {
11236
- const message = {
11237
- id: devtoolsMessageId++,
11238
- timestamp: Date.now(),
11239
- room: json.room,
11240
- event: json.event,
11241
- data: json.data,
11242
- };
11243
- devtoolsMessages.update((log) => [message, ...log].slice(0, MAX_DEVTOOLS_MESSAGES));
11244
- }
11623
+ recordDevtoolsMessage({ room: json.room, event: json.event, data: json.data, direction: 'in' });
11245
11624
  const room = rooms.get(json.room);
11246
11625
  if (room)
11247
11626
  room.latestMessage.set(json);
@@ -11269,6 +11648,7 @@ const createWebSocketClient = (options) => {
11269
11648
  connected: isConnected.asReadonly(),
11270
11649
  rooms: devtoolsRooms.asReadonly(),
11271
11650
  messages: devtoolsMessages.asReadonly(),
11651
+ emit,
11272
11652
  };
11273
11653
  const unregister = registerQueryDevtoolsEntry({
11274
11654
  kind: 'ws-client',
@@ -11287,5 +11667,5 @@ const createWebSocketClient = (options) => {
11287
11667
  * Generated bundle index. Do not edit.
11288
11668
  */
11289
11669
 
11290
- export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DEFAULT_KEEP_UNUSED_FOR, DEFAULT_QUERY_PERSISTENCE_MAX_AGE, DEFAULT_QUERY_PERSISTENCE_MAX_ENTRIES, DEFAULT_QUERY_PERSISTENCE_VERSION, DEFAULT_QUERY_PERSISTENCE_WRITE_DELAY, DateArrayQueryField, DateQueryField, EMPTY_QUERY_DEVTOOLS_FAULT, EntityStore, IGNORED_FILTER_COUNT_FIELDS, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, MAX_UNUSED_ENTRIES, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QUERY_DEVTOOLS_FAULT_STATUSES, QUERY_PERSISTENCE_STORE_VERSION, QUERY_SYNC_PROTOCOL_VERSION, QueryClientFeatureType, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryFormSignals, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, booleanArrayQueryField, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, clearQueryDevtoolsFaults, collectQueryFormLinks, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createIndexedDbQueryPersistenceAdapter, createInfinityQueryConfig, createLegacyQueryCreator, createNoopQueryPersistenceAdapter, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryDevtoolsFormLinks, createQueryDevtoolsFormLinksRecorder, createQueryDevtoolsStats, createQueryDevtoolsStatsRecorder, createQueryErrorResponse, createQueryFeature, createQueryForm, createQueryInvalidationFilter, createQueryKeyLockManager, createQueryObject, createQueryPersistenceEngine, createQueryRepository, createQuerySnapshotFn, createQueryStack, createQuerySyncEngine, createQuerySyncTransport, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, dateArrayQueryField, dateQueryField, decryptBearer, deepFreeze, def, describeQueryDevtoolsFeatures, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, emptyQueryArgs, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractHtmlErrorMessage, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, formatQueryDevtoolsDuration, getBearerAuthProviderName, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, htmlErrorPayload, htmlQueryErrorParser, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isHtmlErrorPayload, isLegacyQuery, isNaN$1 as isNaN, isPageOutOfRangeError, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryDevtoolsFaultArmed, isQueryDevtoolsFaultInjectionEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, isUnderInvalidatedUrl, legacyPrepareFallbackInjector, legacyPrepareWithoutInjectionContext, mapToPaginated, mapViolationsToFormErrors, maybeExecute, measureQueryDevtoolsPayload, mergeHeaders, nestedEffect, noteQueryFormRead, numberArrayQueryField, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, parseQueryRoute, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideLegacyPrepareFallback, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryClientFeatureUsedMultipleTimes, queryComputed, queryComputedTillTruthy, queryDevtoolsEntries, queryDevtoolsFaults, queryDevtoolsFnDetail, queryErrorMessage, queryErrorMessages, queryExecute, queryFeatureUsedMultipleTimes, queryField, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, registerQueryDevtoolsEntry, registerQueryErrorParser, removeFrom, request, resetExecuteState, resetPageOnError, resolveInvalidationUrl, resolveQueryDevtoolsFault, resolveQueryDevtoolsFaultForAttempt, runDefaultQueryRetry, runQueryErrorParsers, searchQueryField, serializeBody, setDefaultQueryRetryFn, setQueryDevtoolsFault, setQueryDevtoolsFaultResolver, setQueryDevtoolsFormLinksFactory, setQueryDevtoolsRegistrar, setQueryDevtoolsStatsFactory, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, sortQueryField, splitQueryConfig, stringArrayQueryField, stringifyQueryRouteParts, sumQueryDevtoolsStats, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryState, symfonyQueryErrorParser, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, unwrapQuerySyncMessage, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withBearerAuthMultiTabSync, withDefaultRetry, withErrorHandling, withEthleteApiErrors, withHtmlErrorParsing, withInactivityLogout, withLogging, withMultiTabSync, withPageResetOnError, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withQueryPersistence, withRefreshQuery, withResponseUpdate, withSuccessHandling, withSymfonyErrors, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal, wrapQuerySyncMessage };
11670
+ export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DEFAULT_KEEP_UNUSED_FOR, DEFAULT_QUERY_PERSISTENCE_MAX_AGE, DEFAULT_QUERY_PERSISTENCE_MAX_ENTRIES, DEFAULT_QUERY_PERSISTENCE_VERSION, DEFAULT_QUERY_PERSISTENCE_WRITE_DELAY, DateArrayQueryField, DateQueryField, EMPTY_QUERY_DEVTOOLS_FAULT, EntityStore, IGNORED_FILTER_COUNT_FIELDS, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, MAX_UNUSED_ENTRIES, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QUERY_DEVTOOLS_FAULT_STATUSES, QUERY_PERSISTENCE_STORE_VERSION, QUERY_SYNC_PROTOCOL_VERSION, QueryClientFeatureType, QueryDevtoolsComponent, QueryDirective, QueryFeatureType, QueryField, QueryForm, QueryFormSignals, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryDevtoolsOverrides, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, booleanArrayQueryField, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, clearQueryDevtoolsFaults, collectLeafPaths, collectQueryFormLinks, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createIndexedDbQueryPersistenceAdapter, createInfinityQueryConfig, createLegacyQueryCreator, createNoopQueryPersistenceAdapter, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryDevtoolsFormLinks, createQueryDevtoolsFormLinksRecorder, createQueryDevtoolsOverrides, createQueryDevtoolsOverridesRecorder, createQueryDevtoolsStats, createQueryDevtoolsStatsRecorder, createQueryErrorResponse, createQueryFeature, createQueryForm, createQueryInvalidationFilter, createQueryKeyLockManager, createQueryObject, createQueryPersistenceEngine, createQueryRepository, createQuerySnapshotFn, createQueryStack, createQuerySyncEngine, createQuerySyncTransport, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, dateArrayQueryField, dateQueryField, decryptBearer, deepFreeze, def, describeQueryDevtoolsFeatures, detectContentTypeHeader, detectPaginationShape, dynLikePaginationAdapter, effectComputed, emptyQueryArgs, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractHtmlErrorMessage, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, formatQueryDevtoolsDuration, getBearerAuthProviderName, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, htmlErrorPayload, htmlQueryErrorParser, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isDateShapedLeaf, isEmptyString, isGqlQueryConfig, isHtmlErrorPayload, isLegacyQuery, isNaN$1 as isNaN, isPageOutOfRangeError, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryDevtoolsFaultArmed, isQueryDevtoolsFaultInjectionEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, isUnderInvalidatedUrl, legacyPrepareFallbackInjector, legacyPrepareWithoutInjectionContext, mapToPaginated, mapViolationsToFormErrors, maybeExecute, measureQueryDevtoolsPayload, mergeHeaders, nestedEffect, noteQueryFormRead, numberArrayQueryField, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, parseQueryRoute, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideLegacyPrepareFallback, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryClientFeatureUsedMultipleTimes, queryComputed, queryComputedTillTruthy, queryDevtoolsEntries, queryDevtoolsFaults, queryDevtoolsFnDetail, queryErrorMessage, queryErrorMessages, queryExecute, queryFeatureUsedMultipleTimes, queryField, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, registerQueryDevtoolsEntry, registerQueryErrorParser, removeFrom, request, resetExecuteState, resetPageOnError, resolveInvalidationUrl, resolveQueryDevtoolsFault, resolveQueryDevtoolsFaultForAttempt, runDefaultQueryRetry, runQueryErrorParsers, searchQueryField, serializeBody, setDefaultQueryRetryFn, setQueryDevtoolsFault, setQueryDevtoolsFaultResolver, setQueryDevtoolsFormLinksFactory, setQueryDevtoolsOverridesFactory, setQueryDevtoolsRegistrar, setQueryDevtoolsStatsFactory, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, smartDuplicateArrayItem, sortQueryField, splitQueryConfig, stringArrayQueryField, stringifyQueryRouteParts, sumQueryDevtoolsStats, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryState, symfonyQueryErrorParser, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, unwrapQuerySyncMessage, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withBearerAuthMultiTabSync, withDefaultRetry, withErrorHandling, withEthleteApiErrors, withHtmlErrorParsing, withInactivityLogout, withLogging, withMultiTabSync, withPageResetOnError, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withQueryPersistence, withRefreshQuery, withResponseUpdate, withSuccessHandling, withSymfonyErrors, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal, wrapQuerySyncMessage };
11291
11671
  //# sourceMappingURL=ethlete-query.mjs.map