@ethlete/query 6.0.0-next.27 → 6.0.0-next.28

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.
@@ -3690,6 +3690,9 @@ const createSecureExecuteFactory = (options) => {
3690
3690
  let authQuerySubscription = Subscription.EMPTY;
3691
3691
  let tokenRefreshSubscription = Subscription.EMPTY;
3692
3692
  let tokenWaitSubscription = Subscription.EMPTY;
3693
+ let sessionRestartSubscription = Subscription.EMPTY;
3694
+ let hasExecuted = false;
3695
+ let lastExecuteArgs;
3693
3696
  const reset = () => {
3694
3697
  authQuerySubscription.unsubscribe();
3695
3698
  authQuerySubscription = Subscription.EMPTY;
@@ -3697,6 +3700,8 @@ const createSecureExecuteFactory = (options) => {
3697
3700
  tokenRefreshSubscription = Subscription.EMPTY;
3698
3701
  tokenWaitSubscription.unsubscribe();
3699
3702
  tokenWaitSubscription = Subscription.EMPTY;
3703
+ sessionRestartSubscription.unsubscribe();
3704
+ sessionRestartSubscription = Subscription.EMPTY;
3700
3705
  resetExecuteState({
3701
3706
  executeState,
3702
3707
  executeOptions: { deps: options.deps, state: options.state },
@@ -3705,9 +3710,26 @@ const createSecureExecuteFactory = (options) => {
3705
3710
  // A logout tears down the secure entries in the repository, but the query object holding one keeps
3706
3711
  // its own `response`/`error` signals - so without this a component still mounted after logout goes
3707
3712
  // on rendering the previous user's data until something calls `reset()` by hand.
3713
+ //
3714
+ // Resetting alone leaves it idle for good though: a self-executing query runs once, at creation,
3715
+ // and nothing runs it again - so anything still mounted across a logout has to be re-armed for
3716
+ // the next session. That re-arm waits on the token instead of re-running here: `logout()` clears
3717
+ // `latestExecutedQuery` and `executionState` only *after* emitting this event, so everything read
3718
+ // synchronously still describes the session that just ended.
3708
3719
  options.deps.client.repository.events$
3709
3720
  .pipe(filter((event) => event.type === 'unbind-all-secure'), takeUntilDestroyed(options.deps.destroyRef))
3710
- .subscribe(() => reset());
3721
+ .subscribe(() => {
3722
+ const shouldRestart = hasExecuted && options.autoExecutes;
3723
+ const restartArgs = lastExecuteArgs;
3724
+ reset();
3725
+ if (!shouldRestart)
3726
+ return;
3727
+ sessionRestartSubscription = toObservable(options.authProvider.accessToken, {
3728
+ injector: options.deps.injector,
3729
+ })
3730
+ .pipe(filter(Boolean), take(1), tap(() => exec(restartArgs)))
3731
+ .subscribe();
3732
+ });
3711
3733
  const error = (query) => {
3712
3734
  const state = options.state;
3713
3735
  state.error.set(query.error());
@@ -3768,12 +3790,16 @@ const createSecureExecuteFactory = (options) => {
3768
3790
  args: executeArgs?.args ?? options.state.args(),
3769
3791
  options: executeArgs?.options,
3770
3792
  };
3793
+ hasExecuted = true;
3794
+ lastExecuteArgs = execArgsWithDefaults;
3771
3795
  authQuerySubscription.unsubscribe();
3772
3796
  authQuerySubscription = Subscription.EMPTY;
3773
3797
  tokenRefreshSubscription.unsubscribe();
3774
3798
  tokenRefreshSubscription = Subscription.EMPTY;
3775
3799
  tokenWaitSubscription.unsubscribe();
3776
3800
  tokenWaitSubscription = Subscription.EMPTY;
3801
+ sessionRestartSubscription.unsubscribe();
3802
+ sessionRestartSubscription = Subscription.EMPTY;
3777
3803
  tokenRefreshSubscription = options.authProvider.afterTokenRefresh$
3778
3804
  .pipe(filter(() => {
3779
3805
  const currentError = options.state.error();
@@ -3840,6 +3866,7 @@ const createSecureExecuteFn = (executeOptions) => {
3840
3866
  authProvider,
3841
3867
  deps: executeOptions.deps,
3842
3868
  state: executeOptions.state,
3869
+ autoExecutes: shouldAutoExecuteQuery(executeOptions.creatorInternals.method) && !executeOptions.queryConfig.onlyManualExecution,
3843
3870
  transformAuthAndExec: (executeArgs, _tokens, headers, executeState) => {
3844
3871
  const { options: runOptions } = executeArgs ?? {};
3845
3872
  const updatedArgs = { ...(executeArgs?.args ?? {}), headers };
@@ -6272,6 +6299,8 @@ const createSecureGqlExecuteFn = (executeOptions) => {
6272
6299
  authProvider,
6273
6300
  deps: executeOptions.deps,
6274
6301
  state: executeOptions.state,
6302
+ autoExecutes: shouldAutoExecuteGqlQuery(executeOptions.creatorInternals.method) &&
6303
+ !executeOptions.queryConfig.onlyManualExecution,
6275
6304
  transformAuthAndExec: (executeArgs, _tokens, headers, executeState) => {
6276
6305
  const { args, options: runOptions } = executeArgs ?? {};
6277
6306
  const query = transformGql(executeOptions.creatorInternals.query);
@@ -11098,12 +11127,11 @@ const nextQueryFormDevtoolsId = (name) => {
11098
11127
  return `query-form|${name}#${seq}`;
11099
11128
  };
11100
11129
  /**
11101
- * A signals-first query form: binds on-screen controls to typed fields, keeps a
11102
- * debounced committed value, syncs to the URL query params, and resets dependent
11103
- * fields via the `isResetBy` graph - all as signals.
11130
+ * Define a {@link QueryFormSignals}. Call `.observe()` to start syncing with the
11131
+ * URL. Must be called in an injection context.
11104
11132
  *
11105
11133
  * @example
11106
- * const qf = createQueryForm({
11134
+ * const qf = defineQueryForm({
11107
11135
  * fields: {
11108
11136
  * search: searchQueryField(),
11109
11137
  * sort: sortQueryField(),
@@ -11112,191 +11140,131 @@ const nextQueryFormDevtoolsId = (name) => {
11112
11140
  * }).observe();
11113
11141
  * // template: <input etInput [formField]="qf.fields.search" />
11114
11142
  */
11115
- class QueryFormSignals {
11116
- constructor(config) {
11117
- this.router = inject(Router);
11118
- this.route = inject(ActivatedRoute);
11119
- this.injector = inject(Injector);
11120
- this.queryParamChanges = injectQueryParamChanges();
11121
- this.previous = signal(null, /* @ts-ignore */
11122
- ...(ngDevMode ? [{ debugName: "previous" }] : /* istanbul ignore next */ []));
11123
- this.observing = signal(false, /* @ts-ignore */
11124
- ...(ngDevMode ? [{ debugName: "observing" }] : /* istanbul ignore next */ []));
11125
- this.pendingTimer = null;
11126
- this.commitPending = signal(false, /* @ts-ignore */
11127
- ...(ngDevMode ? [{ debugName: "commitPending" }] : /* istanbul ignore next */ []));
11128
- this.skipNextResets = false;
11129
- assertInInjectionContext(QueryFormSignals);
11130
- this._fields = config.fields;
11131
- this.prefix = config.queryParamPrefix;
11132
- this.defaults = buildDefaults(config.fields);
11133
- this.defaultValue = clone(this.defaults);
11134
- const initial = clone(this.defaults);
11135
- this.model = signal(initial, /* @ts-ignore */
11136
- ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
11137
- this.committed = signal(clone(initial), /* @ts-ignore */
11138
- ...(ngDevMode ? [{ debugName: "committed" }] : /* istanbul ignore next */ []));
11139
- this.fields = form(this.model);
11140
- const devtoolsName = config.name ?? (typeof this.prefix === 'string' ? this.prefix : 'form');
11141
- const devtoolsId = isQueryDevtoolsEnabled() ? nextQueryFormDevtoolsId(devtoolsName) : null;
11142
- // Reading `value` is how a query's args pick the form up, so the devtools learn which query a form
11143
- // drives by noting the read - see `QueryDevtoolsFormLinksHandle`.
11144
- this.value = devtoolsId
11145
- ? computed(() => {
11146
- noteQueryFormRead(devtoolsId);
11147
- return this.committed();
11148
- })
11149
- : this.committed.asReadonly();
11150
- this.previousValue = this.previous.asReadonly();
11151
- this.changes = computed(() => ({ previousValue: this.previous(), currentValue: this.committed() }), /* @ts-ignore */
11152
- ...(ngDevMode ? [{ debugName: "changes" }] : /* istanbul ignore next */ []));
11153
- this.activeFilterCount = computed(() => computeFilterCount(this._fields, this.committed(), this.defaults), /* @ts-ignore */
11154
- ...(ngDevMode ? [{ debugName: "activeFilterCount" }] : /* istanbul ignore next */ []));
11155
- // React to live control edits: schedule a debounced commit.
11156
- effect(() => {
11157
- const live = this.model();
11158
- untracked(() => this.onLiveChange(live));
11159
- });
11160
- // React to navigation (back/forward, external links): apply URL → form immediately.
11161
- effect(() => {
11162
- const changes = this.queryParamChanges();
11163
- untracked(() => {
11164
- if (!this.observing() || this.observeOptions?.syncOnNavigation === false)
11165
- return;
11166
- this.applyFromUrl(changes);
11167
- });
11168
- });
11169
- const destroyRef = inject(DestroyRef);
11170
- destroyRef.onDestroy(() => this.cleanup());
11171
- if (devtoolsId) {
11172
- destroyRef.onDestroy(registerQueryDevtoolsEntry({
11173
- id: devtoolsId,
11174
- kind: 'query-form',
11175
- handle: this.devtoolsHandle(),
11176
- meta: { name: devtoolsName },
11177
- }));
11178
- }
11179
- }
11180
- observe(options) {
11181
- if (this.observing()) {
11182
- if (isDevMode()) {
11183
- console.warn('QueryFormSignals.observe() was called more than once. Ignoring the extra call.');
11184
- }
11185
- return this;
11143
+ const defineQueryForm = (config) => {
11144
+ assertInInjectionContext(defineQueryForm);
11145
+ const router = inject(Router);
11146
+ const route = inject(ActivatedRoute);
11147
+ const injector = inject(Injector);
11148
+ const destroyRef = inject(DestroyRef);
11149
+ const queryParamChanges = injectQueryParamChanges();
11150
+ const fieldDefs = config.fields;
11151
+ const prefix = config.queryParamPrefix;
11152
+ const defaults = buildDefaults(fieldDefs);
11153
+ const defaultValue = clone(defaults);
11154
+ /** Live field values (updated immediately by bound controls). */
11155
+ const model = signal(clone(defaults), /* @ts-ignore */
11156
+ ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
11157
+ /** The committed (debounced) value that drives `value`, the URL and the filter count. */
11158
+ const committed = signal(clone(defaults), /* @ts-ignore */
11159
+ ...(ngDevMode ? [{ debugName: "committed" }] : /* istanbul ignore next */ []));
11160
+ const previous = signal(null, /* @ts-ignore */
11161
+ ...(ngDevMode ? [{ debugName: "previous" }] : /* istanbul ignore next */ []));
11162
+ const observing = signal(false, /* @ts-ignore */
11163
+ ...(ngDevMode ? [{ debugName: "observing" }] : /* istanbul ignore next */ []));
11164
+ const commitPending = signal(false, /* @ts-ignore */
11165
+ ...(ngDevMode ? [{ debugName: "commitPending" }] : /* istanbul ignore next */ []));
11166
+ let observeOptions;
11167
+ let pendingTimer = null;
11168
+ let skipNextResets = false;
11169
+ const fields = form(model);
11170
+ const activeFilterCount = computed(() => computeFilterCount(fieldDefs, committed(), defaults), /* @ts-ignore */
11171
+ ...(ngDevMode ? [{ debugName: "activeFilterCount" }] : /* istanbul ignore next */ []));
11172
+ const paramKey = (key) => {
11173
+ if (!prefix)
11174
+ return key;
11175
+ return `${typeof prefix === 'string' ? prefix : prefix()}-${key}`;
11176
+ };
11177
+ /** What a field puts in the URL for a given value, or `undefined` when it writes nothing. */
11178
+ const queryParamFor = (key, def, value) => {
11179
+ const isDefault = equal(value, defaults[key]);
11180
+ const writeToUrl = def.appendToUrl !== false;
11181
+ const writeDefault = def.appendDefaultValueToUrl === true;
11182
+ if (!writeToUrl || (isDefault && !writeDefault))
11183
+ return undefined;
11184
+ if (def.valueToQueryParam)
11185
+ return def.valueToQueryParam(value);
11186
+ return value === null ? ET_NULL_VALUE : value;
11187
+ };
11188
+ const deserialize = (def, raw) => {
11189
+ if (def.queryParamToValue)
11190
+ return def.queryParamToValue(raw);
11191
+ if (def.skipAutoTransform)
11192
+ return raw;
11193
+ return autoCoerce(raw, resolveDefault(def));
11194
+ };
11195
+ const clearTimer = () => {
11196
+ if (pendingTimer !== null) {
11197
+ clearTimeout(pendingTimer);
11198
+ pendingTimer = null;
11186
11199
  }
11187
- this.observeOptions = options;
11188
- this.observing.set(true);
11189
- if (options?.syncOnNavigation !== false) {
11190
- this.applyFromUrl(this.route.snapshot.queryParams);
11200
+ commitPending.set(false);
11201
+ };
11202
+ const writeToUrl = (value) => {
11203
+ const queryParams = {};
11204
+ for (const [key, def] of Object.entries(fieldDefs)) {
11205
+ queryParams[paramKey(key)] = queryParamFor(key, def, value[key]);
11191
11206
  }
11192
- // Commit whatever the model holds now (URL-restored or programmatic defaults).
11193
- this.flush();
11194
- return this;
11195
- }
11196
- unobserve() {
11197
- this.cleanup();
11198
- }
11199
- setValue(value, options) {
11200
- if (options?.skipResets)
11201
- this.skipNextResets = true;
11202
- this.model.set(clone(value));
11203
- }
11204
- patchValue(value, options) {
11205
- if (options?.skipResets)
11206
- this.skipNextResets = true;
11207
- this.model.update((cur) => ({ ...cur, ...value }));
11208
- }
11209
- resetFieldToDefault(key, options) {
11210
- if (options?.skipResets)
11211
- this.skipNextResets = true;
11212
- this.model.update((cur) => ({ ...cur, [key]: this.defaults[key] }));
11213
- }
11214
- resetFieldsToDefault(keys, options) {
11215
- if (options?.skipResets)
11216
- this.skipNextResets = true;
11217
- this.model.update((cur) => {
11218
- const next = { ...cur };
11219
- for (const key of keys) {
11220
- next[key] = this.defaults[key];
11221
- }
11222
- return next;
11207
+ queueMicrotask(() => {
11208
+ router.navigate([], {
11209
+ queryParams,
11210
+ queryParamsHandling: 'merge',
11211
+ replaceUrl: observeOptions?.replaceUrl,
11212
+ });
11223
11213
  });
11224
- }
11225
- resetAllFieldsToDefault(options) {
11226
- const skip = new Set((options?.skipFields ?? []).map((key) => key));
11227
- const keys = Object.keys(this._fields).filter((key) => !skip.has(key));
11228
- this.resetFieldsToDefault(keys, options);
11229
- }
11230
- /** Create a detached editor over the same fields, seeded from the current committed value. */
11231
- branch() {
11232
- return createBranch(this._fields, clone(this.committed()), this.injector);
11233
- }
11234
- /**
11235
- * The live view `<et-query-devtools>` renders. Only built while the devtools are installed - it walks
11236
- * every field on every change, which an app without them should not pay for.
11237
- */
11238
- devtoolsHandle() {
11239
- const fields = computed(() => {
11240
- const committed = this.committed();
11241
- const live = this.model();
11242
- return Object.entries(this._fields).map(([key, def]) => {
11243
- const value = committed[key];
11244
- return {
11245
- key,
11246
- paramKey: this.paramKey(key),
11247
- value,
11248
- liveValue: live[key],
11249
- defaultValue: this.defaults[key],
11250
- isDefault: equal(value, this.defaults[key]),
11251
- queryParam: this.queryParamFor(key, def, value),
11252
- debounceMs: def.debounce ?? null,
11253
- isResetBy: def.isResetBy ?? [],
11254
- countsAsFilter: !IGNORED_FILTER_COUNT_FIELDS.includes(key) && !def.skipInFilterCount,
11255
- };
11214
+ };
11215
+ const applyResets = (live, changedKeys) => {
11216
+ const next = { ...live };
11217
+ for (const [key, def] of Object.entries(fieldDefs)) {
11218
+ const resets = def.isResetBy;
11219
+ if (!resets?.length)
11220
+ continue;
11221
+ const triggered = resets.some((resetKey) => {
11222
+ if (!(resetKey in fieldDefs)) {
11223
+ if (isDevMode()) {
11224
+ console.warn(`defineQueryForm: isResetBy references unknown field "${resetKey}". Is it a typo?`);
11225
+ }
11226
+ return false;
11227
+ }
11228
+ return changedKeys.includes(resetKey);
11256
11229
  });
11257
- }, /* @ts-ignore */
11258
- ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
11259
- return {
11260
- fields,
11261
- // Not `this.value` - reading that from the panel would link the form to whichever query happens
11262
- // to be building its args at the time.
11263
- value: computed(() => this.committed()),
11264
- previousValue: computed(() => this.previous() ?? null),
11265
- defaultValue: this.defaults,
11266
- activeFilterCount: this.activeFilterCount,
11267
- isAtDefaults: computed(() => equal(this.committed(), this.defaults)),
11268
- isCommitPending: this.commitPending.asReadonly(),
11269
- isObserving: this.observing.asReadonly(),
11270
- resetField: (key) => this.resetFieldToDefault(key),
11271
- resetAll: () => this.resetAllFieldsToDefault(),
11272
- };
11273
- }
11274
- onLiveChange(live) {
11275
- if (!this.observing())
11276
- return;
11277
- if (equal(live, this.committed()))
11230
+ if (!triggered)
11231
+ continue;
11232
+ const fieldDefault = defaults[key];
11233
+ if (!equal(next[key], fieldDefault)) {
11234
+ next[key] = fieldDefault;
11235
+ }
11236
+ }
11237
+ return next;
11238
+ };
11239
+ const flush = () => {
11240
+ clearTimer();
11241
+ const live = model();
11242
+ const prev = committed();
11243
+ if (equal(live, prev)) {
11244
+ skipNextResets = false;
11278
11245
  return;
11279
- const changedKeys = changedKeysBetween(this.committed(), live);
11280
- const debounceMs = this.resolveDebounce(changedKeys, live);
11281
- this.clearTimer();
11282
- if (debounceMs === null) {
11283
- this.flush();
11284
11246
  }
11285
- else {
11286
- this.commitPending.set(true);
11287
- this.pendingTimer = setTimeout(() => {
11288
- this.pendingTimer = null;
11289
- this.flush();
11290
- }, debounceMs);
11247
+ const changedKeys = changedKeysBetween(prev, live);
11248
+ const next = skipNextResets ? { ...live } : applyResets(live, changedKeys);
11249
+ skipNextResets = false;
11250
+ previous.set(clone(prev));
11251
+ committed.set(clone(next));
11252
+ // Reflect any reset overrides back into the bound controls. The effect re-runs
11253
+ // but no-ops because the model now equals the committed value.
11254
+ if (!equal(next, live)) {
11255
+ model.set(clone(next));
11291
11256
  }
11292
- }
11257
+ if (observing() && observeOptions?.writeToQueryParams !== false) {
11258
+ writeToUrl(next);
11259
+ }
11260
+ };
11293
11261
  /** Shortest-debounce-wins; `null` means commit immediately. */
11294
- resolveDebounce(changedKeys, live) {
11262
+ const resolveDebounce = (changedKeys, live) => {
11295
11263
  if (!changedKeys.length)
11296
11264
  return null;
11297
11265
  const times = [];
11298
11266
  for (const key of changedKeys) {
11299
- const def = this._fields[key];
11267
+ const def = fieldDefs[key];
11300
11268
  if (!def)
11301
11269
  return null;
11302
11270
  if (def.disableDebounceIfFalsy && !live[key])
@@ -11306,61 +11274,41 @@ class QueryFormSignals {
11306
11274
  times.push(def.debounce);
11307
11275
  }
11308
11276
  return Math.min(...times);
11309
- }
11310
- flush() {
11311
- this.clearTimer();
11312
- const live = this.model();
11313
- const previous = this.committed();
11314
- if (equal(live, previous)) {
11315
- this.skipNextResets = false;
11277
+ };
11278
+ const onLiveChange = (live) => {
11279
+ if (!observing())
11316
11280
  return;
11281
+ if (equal(live, committed()))
11282
+ return;
11283
+ const changedKeys = changedKeysBetween(committed(), live);
11284
+ const debounceMs = resolveDebounce(changedKeys, live);
11285
+ clearTimer();
11286
+ if (debounceMs === null) {
11287
+ flush();
11317
11288
  }
11318
- const changedKeys = changedKeysBetween(previous, live);
11319
- const next = this.skipNextResets ? { ...live } : this.applyResets(live, changedKeys);
11320
- this.skipNextResets = false;
11321
- this.previous.set(clone(previous));
11322
- this.committed.set(clone(next));
11323
- // Reflect any reset overrides back into the bound controls. The effect re-runs
11324
- // but no-ops because the model now equals the committed value.
11325
- if (!equal(next, live)) {
11326
- this.model.set(clone(next));
11327
- }
11328
- if (this.observing() && this.observeOptions?.writeToQueryParams !== false) {
11329
- this.writeToUrl(next);
11330
- }
11331
- }
11332
- applyResets(live, changedKeys) {
11333
- const next = { ...live };
11334
- for (const [key, def] of Object.entries(this._fields)) {
11335
- const resets = def.isResetBy;
11336
- if (!resets?.length)
11337
- continue;
11338
- const triggered = resets.some((resetKey) => {
11339
- if (!(resetKey in this._fields)) {
11340
- if (isDevMode()) {
11341
- console.warn(`QueryFormSignals: isResetBy references unknown field "${resetKey}". Is it a typo?`);
11342
- }
11343
- return false;
11344
- }
11345
- return changedKeys.includes(resetKey);
11346
- });
11347
- if (!triggered)
11348
- continue;
11349
- const defaultValue = this.defaults[key];
11350
- if (!equal(next[key], defaultValue)) {
11351
- next[key] = defaultValue;
11352
- }
11289
+ else {
11290
+ commitPending.set(true);
11291
+ pendingTimer = setTimeout(() => {
11292
+ pendingTimer = null;
11293
+ flush();
11294
+ }, debounceMs);
11353
11295
  }
11354
- return next;
11355
- }
11356
- applyFromUrl(params) {
11357
- const current = { ...this.committed() };
11296
+ };
11297
+ const commitFromUrl = (next) => {
11298
+ clearTimer();
11299
+ previous.set(clone(committed()));
11300
+ committed.set(clone(next));
11301
+ // Feed the URL value into the live model & bound controls; the effect no-ops (model === committed).
11302
+ model.set(clone(next));
11303
+ };
11304
+ const applyFromUrl = (params) => {
11305
+ const current = { ...committed() };
11358
11306
  let changed = false;
11359
- for (const [key, def] of Object.entries(this._fields)) {
11360
- const raw = params[this.paramKey(key)];
11307
+ for (const [key, def] of Object.entries(fieldDefs)) {
11308
+ const raw = params[paramKey(key)];
11361
11309
  if (raw === undefined)
11362
11310
  continue;
11363
- const value = raw === ET_PROPERTY_REMOVED ? this.defaults[key] : this.deserialize(def, raw);
11311
+ const value = raw === ET_PROPERTY_REMOVED ? defaults[key] : deserialize(def, raw);
11364
11312
  if (!equal(current[key], value)) {
11365
11313
  current[key] = value;
11366
11314
  changed = true;
@@ -11368,80 +11316,149 @@ class QueryFormSignals {
11368
11316
  }
11369
11317
  if (!changed)
11370
11318
  return;
11371
- this.commitFromUrl(current);
11372
- }
11373
- commitFromUrl(next) {
11374
- this.clearTimer();
11375
- this.previous.set(clone(this.committed()));
11376
- this.committed.set(clone(next));
11377
- // Feed the URL value into the live model & bound controls; the effect no-ops (model === committed).
11378
- this.model.set(clone(next));
11379
- }
11380
- deserialize(def, raw) {
11381
- if (def.queryParamToValue)
11382
- return def.queryParamToValue(raw);
11383
- if (def.skipAutoTransform)
11384
- return raw;
11385
- return autoCoerce(raw, resolveDefault(def));
11386
- }
11387
- /** What a field puts in the URL for a given value, or `undefined` when it writes nothing. */
11388
- queryParamFor(key, def, value) {
11389
- const isDefault = equal(value, this.defaults[key]);
11390
- const writeToUrl = def.appendToUrl !== false;
11391
- const writeDefault = def.appendDefaultValueToUrl === true;
11392
- if (!writeToUrl || (isDefault && !writeDefault))
11393
- return undefined;
11394
- if (def.valueToQueryParam)
11395
- return def.valueToQueryParam(value);
11396
- return value === null ? ET_NULL_VALUE : value;
11397
- }
11398
- writeToUrl(value) {
11399
- const queryParams = {};
11400
- for (const [key, def] of Object.entries(this._fields)) {
11401
- queryParams[this.paramKey(key)] = this.queryParamFor(key, def, value[key]);
11402
- }
11403
- queueMicrotask(() => {
11404
- this.router.navigate([], {
11405
- queryParams,
11406
- queryParamsHandling: 'merge',
11407
- replaceUrl: this.observeOptions?.replaceUrl,
11408
- });
11409
- });
11410
- }
11411
- paramKey(key) {
11412
- const prefix = this.prefix;
11413
- if (!prefix)
11414
- return key;
11415
- return `${typeof prefix === 'string' ? prefix : prefix()}-${key}`;
11416
- }
11417
- clearTimer() {
11418
- if (this.pendingTimer !== null) {
11419
- clearTimeout(this.pendingTimer);
11420
- this.pendingTimer = null;
11421
- }
11422
- this.commitPending.set(false);
11423
- }
11424
- cleanup() {
11425
- if (!this.observing())
11319
+ commitFromUrl(current);
11320
+ };
11321
+ const cleanup = () => {
11322
+ if (!observing())
11426
11323
  return;
11427
- this.observing.set(false);
11428
- this.clearTimer();
11429
- if (this.observeOptions?.writeToQueryParams === false)
11324
+ observing.set(false);
11325
+ clearTimer();
11326
+ if (observeOptions?.writeToQueryParams === false)
11430
11327
  return;
11431
11328
  const queryParams = {};
11432
- for (const key of Object.keys(this._fields)) {
11433
- queryParams[this.paramKey(key)] = undefined;
11329
+ for (const key of Object.keys(fieldDefs)) {
11330
+ queryParams[paramKey(key)] = undefined;
11434
11331
  }
11435
11332
  queueMicrotask(() => {
11436
- this.router.navigate([], { queryParams, queryParamsHandling: 'merge', replaceUrl: true });
11333
+ router.navigate([], { queryParams, queryParamsHandling: 'merge', replaceUrl: true });
11334
+ });
11335
+ };
11336
+ const setValue = (value, options) => {
11337
+ if (options?.skipResets)
11338
+ skipNextResets = true;
11339
+ model.set(clone(value));
11340
+ };
11341
+ const patchValue = (value, options) => {
11342
+ if (options?.skipResets)
11343
+ skipNextResets = true;
11344
+ model.update((cur) => ({ ...cur, ...value }));
11345
+ };
11346
+ const resetFieldsToDefault = (keys, options) => {
11347
+ if (options?.skipResets)
11348
+ skipNextResets = true;
11349
+ model.update((cur) => {
11350
+ const next = { ...cur };
11351
+ for (const key of keys) {
11352
+ next[key] = defaults[key];
11353
+ }
11354
+ return next;
11437
11355
  });
11356
+ };
11357
+ const devtoolsName = config.name ?? (typeof prefix === 'string' ? prefix : 'form');
11358
+ const devtoolsId = isQueryDevtoolsEnabled() ? nextQueryFormDevtoolsId(devtoolsName) : null;
11359
+ const queryForm = {
11360
+ fields,
11361
+ // Reading `value` is how a query's args pick the form up, so the devtools learn which query a form
11362
+ // drives by noting the read - see `QueryDevtoolsFormLinksHandle`.
11363
+ value: devtoolsId
11364
+ ? computed(() => {
11365
+ noteQueryFormRead(devtoolsId);
11366
+ return committed();
11367
+ })
11368
+ : committed.asReadonly(),
11369
+ previousValue: previous.asReadonly(),
11370
+ changes: computed(() => ({ previousValue: previous(), currentValue: committed() })),
11371
+ activeFilterCount,
11372
+ defaultValue,
11373
+ observe: (options) => {
11374
+ if (observing()) {
11375
+ if (isDevMode()) {
11376
+ console.warn('defineQueryForm: observe() was called more than once. Ignoring the extra call.');
11377
+ }
11378
+ return queryForm;
11379
+ }
11380
+ observeOptions = options;
11381
+ observing.set(true);
11382
+ if (options?.syncOnNavigation !== false) {
11383
+ applyFromUrl(route.snapshot.queryParams);
11384
+ }
11385
+ // Commit whatever the model holds now (URL-restored or programmatic defaults).
11386
+ flush();
11387
+ return queryForm;
11388
+ },
11389
+ unobserve: () => cleanup(),
11390
+ setValue,
11391
+ patchValue,
11392
+ resetFieldToDefault: (key, options) => resetFieldsToDefault([key], options),
11393
+ resetFieldsToDefault,
11394
+ resetAllFieldsToDefault: (options) => {
11395
+ const skip = new Set((options?.skipFields ?? []).map((key) => key));
11396
+ const keys = Object.keys(fieldDefs).filter((key) => !skip.has(key));
11397
+ resetFieldsToDefault(keys, options);
11398
+ },
11399
+ branch: () => createBranch(fieldDefs, clone(committed()), injector),
11400
+ };
11401
+ // React to live control edits: schedule a debounced commit.
11402
+ effect(() => {
11403
+ const live = model();
11404
+ untracked(() => onLiveChange(live));
11405
+ });
11406
+ // React to navigation (back/forward, external links): apply URL → form immediately.
11407
+ effect(() => {
11408
+ const changes = queryParamChanges();
11409
+ untracked(() => {
11410
+ if (!observing() || observeOptions?.syncOnNavigation === false)
11411
+ return;
11412
+ applyFromUrl(changes);
11413
+ });
11414
+ });
11415
+ destroyRef.onDestroy(() => cleanup());
11416
+ if (devtoolsId) {
11417
+ /**
11418
+ * The live view `<et-query-devtools>` renders. Only built while the devtools are installed - it walks
11419
+ * every field on every change, which an app without them should not pay for.
11420
+ */
11421
+ const handle = {
11422
+ fields: computed(() => {
11423
+ const committedValue = committed();
11424
+ const live = model();
11425
+ return Object.entries(fieldDefs).map(([key, def]) => {
11426
+ const value = committedValue[key];
11427
+ return {
11428
+ key,
11429
+ paramKey: paramKey(key),
11430
+ value,
11431
+ liveValue: live[key],
11432
+ defaultValue: defaults[key],
11433
+ isDefault: equal(value, defaults[key]),
11434
+ queryParam: queryParamFor(key, def, value),
11435
+ debounceMs: def.debounce ?? null,
11436
+ isResetBy: def.isResetBy ?? [],
11437
+ countsAsFilter: !IGNORED_FILTER_COUNT_FIELDS.includes(key) && !def.skipInFilterCount,
11438
+ };
11439
+ });
11440
+ }),
11441
+ // Not `queryForm.value` - reading that from the panel would link the form to whichever query happens
11442
+ // to be building its args at the time.
11443
+ value: computed(() => committed()),
11444
+ previousValue: computed(() => previous() ?? null),
11445
+ defaultValue: defaults,
11446
+ activeFilterCount,
11447
+ isAtDefaults: computed(() => equal(committed(), defaults)),
11448
+ isCommitPending: commitPending.asReadonly(),
11449
+ isObserving: observing.asReadonly(),
11450
+ resetField: (key) => queryForm.resetFieldToDefault(key),
11451
+ resetAll: () => queryForm.resetAllFieldsToDefault(),
11452
+ };
11453
+ destroyRef.onDestroy(registerQueryDevtoolsEntry({
11454
+ id: devtoolsId,
11455
+ kind: 'query-form',
11456
+ handle,
11457
+ meta: { name: devtoolsName },
11458
+ }));
11438
11459
  }
11439
- }
11440
- /**
11441
- * Create a {@link QueryFormSignals}. Call `.observe()` to start syncing with the
11442
- * URL. Must be called in an injection context.
11443
- */
11444
- const createQueryForm = (config) => new QueryFormSignals(config);
11460
+ return queryForm;
11461
+ };
11445
11462
 
11446
11463
  const normalizeConfig = (config) => {
11447
11464
  if (!config)
@@ -11679,5 +11696,5 @@ const createWebSocketClient = (options) => {
11679
11696
  * Generated bundle index. Do not edit.
11680
11697
  */
11681
11698
 
11682
- 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 };
11699
+ 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, 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, 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, defineQueryForm, 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 };
11683
11700
  //# sourceMappingURL=ethlete-query.mjs.map