@ethlete/query 0.1.0-next.20 → 0.1.0-next.22

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.
@@ -1,6 +1,5 @@
1
- import { getCookie, setCookie, deleteCookie, DestroyService } from '@ethlete/core';
2
- import { filter, takeWhile, switchMap, of, BehaviorSubject, Subject, interval, takeUntil, tap, timer, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
3
- import { __awaiter } from 'tslib';
1
+ import { getCookie, setCookie, deleteCookie, DestroyService, equal, clone } from '@ethlete/core';
2
+ import { Observable, filter, takeWhile, switchMap, of, BehaviorSubject, Subject, takeUntil, interval, tap, timer, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
4
3
  import * as i0 from '@angular/core';
5
4
  import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
6
5
  import { FormGroup } from '@angular/forms';
@@ -73,7 +72,6 @@ const queryStateCannotTransformError = (data) => new QueryError('006', 'The quer
73
72
  const invalidBodyError = (data) => new QueryError('007', 'The body is not valid or upsupported', data);
74
73
 
75
74
  const isRequestError = (error) => error instanceof Object && 'code' in error && 'message' in error;
76
- const isAbortRequestError = (error) => isRequestError(error) && error.code === -1;
77
75
  const buildRoute = (options) => {
78
76
  var _a;
79
77
  if (options.base.endsWith('/')) {
@@ -147,9 +145,9 @@ const isParamValid = (primitive) => {
147
145
  return true;
148
146
  };
149
147
  const extractExpiresInSeconds = (headers) => {
150
- const cacheControl = headers.get('cache-control');
151
- const age = headers.get('age');
152
- const expires = headers.get('expires');
148
+ const cacheControl = headers['cache-control'];
149
+ const age = headers['age'];
150
+ const expires = headers['expires'];
153
151
  // In seconds
154
152
  let expiresIn = null;
155
153
  let maxAge = null;
@@ -188,91 +186,21 @@ const buildTimestampFromSeconds = (seconds) => {
188
186
  }
189
187
  return new Date(Date.now() + seconds * 1000).getTime();
190
188
  };
191
- const buildRequestError = (error, route, requestInit) => __awaiter(void 0, void 0, void 0, function* () {
192
- if (error instanceof DOMException && error.code === error.ABORT_ERR) {
193
- const err = {
194
- code: -1,
195
- message: 'Request aborted',
196
- detail: null,
197
- raw: error,
198
- route,
199
- requestInit,
200
- };
201
- return err;
202
- }
203
- if (error instanceof SyntaxError) {
204
- const err = {
205
- code: -3,
206
- message: 'Syntax error',
207
- detail: null,
208
- raw: error,
209
- route,
210
- requestInit,
211
- };
212
- return err;
213
- }
214
- if (error instanceof Error) {
215
- const err = {
216
- code: -2,
217
- message: `${error.name}: ${error.message}`,
218
- detail: null,
219
- raw: error,
220
- route,
221
- requestInit,
222
- };
223
- return err;
224
- }
225
- if (isFetchResponse(error)) {
226
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
227
- let detail = null;
228
- try {
229
- detail = yield error.json();
230
- }
231
- catch (_a) {
232
- // noop
233
- }
234
- if (!detail) {
235
- try {
236
- detail = yield error.text();
237
- }
238
- catch (_b) {
239
- // noop
240
- }
241
- }
242
- const err = {
243
- code: error.status,
244
- message: error.statusText,
245
- detail,
246
- raw: error,
247
- route,
248
- requestInit,
249
- };
250
- return err;
251
- }
252
- const err = {
253
- code: 0,
254
- message: 'Unknown error',
255
- detail: null,
256
- raw: error,
257
- route,
258
- requestInit,
259
- };
260
- return err;
261
- });
262
- const buildBody = (body) => {
263
- if (body === undefined || body === null) {
189
+ const serializeBody = (body) => {
190
+ if (body === null || body === undefined) {
264
191
  return null;
265
192
  }
266
- if (typeof body === 'string') {
193
+ if (body instanceof ArrayBuffer ||
194
+ body instanceof Blob ||
195
+ body instanceof FormData ||
196
+ body instanceof URLSearchParams ||
197
+ typeof body === 'string') {
267
198
  return body;
268
199
  }
269
- if (body instanceof FormData) {
270
- return body;
271
- }
272
- if (typeof body === 'object') {
200
+ if (typeof body === 'object' || typeof body === 'boolean' || Array.isArray(body)) {
273
201
  return JSON.stringify(body);
274
202
  }
275
- throw invalidBodyError(body);
203
+ return body.toString();
276
204
  };
277
205
  const transformMethod = (method) => {
278
206
  if (method === 'GQL_QUERY' || method === 'GQL_MUTATE') {
@@ -280,42 +208,236 @@ const transformMethod = (method) => {
280
208
  }
281
209
  return method;
282
210
  };
283
- const guessContentType = (body) => {
284
- if (body === null || body === undefined) {
211
+ const detectContentTypeHeader = (body) => {
212
+ // An empty body has no content type.
213
+ if (body === null) {
285
214
  return null;
286
215
  }
216
+ // FormData bodies rely on the browser's content type assignment.
217
+ if (body instanceof FormData) {
218
+ return null;
219
+ }
220
+ // Blobs usually have their own content type. If it doesn't, then
221
+ // no type can be inferred.
222
+ if (body instanceof Blob) {
223
+ return body.type || null;
224
+ }
225
+ // Array buffers have unknown contents and thus no type can be inferred.
226
+ if (body instanceof ArrayBuffer) {
227
+ return null;
228
+ }
229
+ // Technically, strings could be a form of JSON data, but it's safe enough
230
+ // to assume they're plain strings.
287
231
  if (typeof body === 'string') {
288
232
  return 'text/plain';
289
233
  }
290
- if (body instanceof FormData) {
291
- return 'multipart/form-data';
292
- }
293
- if (typeof body === 'object') {
234
+ // Arrays, objects, boolean and numbers will be encoded as JSON.
235
+ if (typeof body === 'object' || typeof body === 'number' || typeof body === 'boolean') {
294
236
  return 'application/json';
295
237
  }
238
+ // No type could be inferred.
296
239
  return null;
297
240
  };
298
-
299
- const request = (options) => __awaiter(void 0, void 0, void 0, function* () {
300
- var _a, _b;
301
- try {
302
- const response = yield fetch(options.route, options.init);
303
- if (!response.ok) {
304
- throw response;
305
- }
306
- const isJsonResponse = (_a = response.headers.get('Content-Type')) === null || _a === void 0 ? void 0 : _a.includes('application/json');
307
- const isTextResponse = (_b = response.headers.get('Content-Type')) === null || _b === void 0 ? void 0 : _b.includes('text/plain');
308
- const data = (isJsonResponse ? yield response.json() : isTextResponse ? yield response.text() : null);
309
- const expiresInSeconds = options.cacheAdapter
310
- ? options.cacheAdapter(response.headers)
311
- : extractExpiresInSeconds(response.headers);
312
- const expiresInTimestamp = buildTimestampFromSeconds(expiresInSeconds);
313
- return { data, expiresInTimestamp };
241
+ const hasHeader = (headers, header) => {
242
+ return Object.keys(headers).some((key) => key.toLowerCase() === header.toLowerCase());
243
+ };
244
+ const forEachHeader = (headers, callback) => {
245
+ Object.entries(headers).forEach(([key, value]) => {
246
+ callback(key, value);
247
+ });
248
+ };
249
+ const parseAllXhrResponseHeaders = (xhr) => {
250
+ const headers = xhr.getAllResponseHeaders();
251
+ const parsedHeaders = {};
252
+ for (const line of headers.split('\n')) {
253
+ const index = line.indexOf(':');
254
+ if (index > 0) {
255
+ const name = line.slice(0, index);
256
+ const key = name.toLowerCase();
257
+ const value = line.slice(index + 1).trim();
258
+ parsedHeaders[key] = value;
259
+ }
260
+ }
261
+ return parsedHeaders;
262
+ };
263
+ const getResponseUrl = (xhr) => {
264
+ if ('responseURL' in xhr && xhr.responseURL) {
265
+ return xhr.responseURL;
314
266
  }
315
- catch (error) {
316
- throw yield buildRequestError(error, options.route, options.init);
267
+ if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
268
+ return xhr.getResponseHeader('X-Request-URL');
317
269
  }
318
- });
270
+ return null;
271
+ };
272
+
273
+ const XSSI_PREFIX = /^\)\]\}',?\n/;
274
+ const request = (config) => {
275
+ const headers = config.headers || {};
276
+ const responseType = config.responseType || 'json';
277
+ const body = config.body || null;
278
+ const url = config.urlWithParams.split('?')[0];
279
+ return new Observable((observer) => {
280
+ const xhr = new XMLHttpRequest();
281
+ xhr.open(config.method, config.urlWithParams);
282
+ if (config.withCredentials) {
283
+ xhr.withCredentials = true;
284
+ }
285
+ forEachHeader(headers, (name, value) => xhr.setRequestHeader(name, value));
286
+ if (!hasHeader(headers, 'Accept')) {
287
+ xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
288
+ }
289
+ if (!hasHeader(headers, 'Content-Type')) {
290
+ const detectedType = detectContentTypeHeader(body);
291
+ if (detectedType) {
292
+ xhr.setRequestHeader('Content-Type', detectedType);
293
+ }
294
+ }
295
+ xhr.responseType = responseType !== 'json' ? responseType : 'text';
296
+ const reqBody = serializeBody(body);
297
+ let headerResponse = null;
298
+ const partialFromXhr = () => {
299
+ if (headerResponse !== null) {
300
+ return headerResponse;
301
+ }
302
+ const statusText = xhr.statusText || 'OK';
303
+ const headers = parseAllXhrResponseHeaders(xhr);
304
+ const _url = getResponseUrl(xhr) || url;
305
+ headerResponse = { headers, status: xhr.status, statusText, url: _url };
306
+ return headerResponse;
307
+ };
308
+ const onLoad = () => {
309
+ var _a, _b;
310
+ const { headers, statusText, url } = partialFromXhr();
311
+ let { status } = partialFromXhr();
312
+ let body = null;
313
+ if (status !== 204 /* HttpStatusCode.NoContent */) {
314
+ body = typeof xhr.response === 'undefined' ? xhr.responseText : xhr.response;
315
+ }
316
+ if (status === 0) {
317
+ status = body ? 200 /* HttpStatusCode.Ok */ : 0;
318
+ }
319
+ let ok = status >= 200 && status < 300;
320
+ if (responseType === 'json' && typeof body === 'string') {
321
+ const originalBody = body;
322
+ body = body.replace(XSSI_PREFIX, '');
323
+ try {
324
+ body = body !== '' ? JSON.parse(body) : null;
325
+ }
326
+ catch (error) {
327
+ body = originalBody;
328
+ if (ok) {
329
+ ok = false;
330
+ body = { error, text: body };
331
+ }
332
+ }
333
+ }
334
+ if (ok) {
335
+ const successEvent = {
336
+ type: 'success',
337
+ headers,
338
+ response: body,
339
+ };
340
+ const expiresInSeconds = (_b = (_a = config.cacheAdapter) === null || _a === void 0 ? void 0 : _a.call(config, headers)) !== null && _b !== void 0 ? _b : extractExpiresInSeconds(headers);
341
+ const expiresInTimestamp = buildTimestampFromSeconds(expiresInSeconds);
342
+ if (expiresInTimestamp) {
343
+ successEvent.expiresInTimestamp = expiresInTimestamp;
344
+ }
345
+ observer.next(successEvent);
346
+ observer.complete();
347
+ }
348
+ else {
349
+ observer.next({
350
+ type: 'failure',
351
+ headers,
352
+ error: {
353
+ url,
354
+ detail: body,
355
+ status,
356
+ statusText,
357
+ },
358
+ });
359
+ observer.complete();
360
+ }
361
+ };
362
+ const onError = (error) => {
363
+ const { url, headers } = partialFromXhr();
364
+ observer.next({
365
+ type: 'failure',
366
+ headers,
367
+ error: {
368
+ url,
369
+ detail: error,
370
+ status: xhr.status || 0,
371
+ statusText: xhr.statusText || 'Unknown Error',
372
+ },
373
+ });
374
+ observer.complete();
375
+ };
376
+ const onDownProgress = (event) => {
377
+ const { headers } = partialFromXhr();
378
+ const progress = {
379
+ type: 'download-progress',
380
+ headers,
381
+ progress: {
382
+ current: event.loaded,
383
+ },
384
+ };
385
+ if (event.lengthComputable) {
386
+ const progressPercent = (event.loaded / event.total) * 100;
387
+ progress.progress.percentage = Math.round(progressPercent * 100) / 100;
388
+ progress.progress.total = event.total;
389
+ }
390
+ if (responseType === 'text' && !!xhr.responseText) {
391
+ progress.partialText = xhr.responseText;
392
+ }
393
+ observer.next(progress);
394
+ };
395
+ const onUpProgress = (event) => {
396
+ const { headers } = partialFromXhr();
397
+ const progress = {
398
+ type: 'upload-progress',
399
+ headers,
400
+ progress: {
401
+ current: event.loaded,
402
+ },
403
+ };
404
+ if (event.lengthComputable) {
405
+ const progressPercent = (event.loaded / event.total) * 100;
406
+ progress.progress.percentage = Math.round(progressPercent * 100) / 100;
407
+ progress.progress.total = event.total;
408
+ }
409
+ observer.next(progress);
410
+ };
411
+ xhr.addEventListener('load', onLoad);
412
+ xhr.addEventListener('error', onError);
413
+ xhr.addEventListener('timeout', onError);
414
+ xhr.addEventListener('abort', onError);
415
+ if (config.reportProgress) {
416
+ xhr.addEventListener('progress', onDownProgress);
417
+ if (reqBody !== null && xhr.upload) {
418
+ xhr.upload.addEventListener('progress', onUpProgress);
419
+ }
420
+ }
421
+ xhr.send(reqBody);
422
+ observer.next({ type: 'start', headers });
423
+ return () => {
424
+ xhr.removeEventListener('error', onError);
425
+ xhr.removeEventListener('abort', onError);
426
+ xhr.removeEventListener('load', onLoad);
427
+ xhr.removeEventListener('timeout', onError);
428
+ if (config.reportProgress) {
429
+ xhr.removeEventListener('progress', onDownProgress);
430
+ if (reqBody !== null && xhr.upload) {
431
+ xhr.upload.removeEventListener('progress', onUpProgress);
432
+ }
433
+ }
434
+ if (xhr.readyState !== xhr.DONE) {
435
+ xhr.abort();
436
+ }
437
+ observer.next({ type: 'cancel', headers });
438
+ };
439
+ });
440
+ };
319
441
 
320
442
  function filterSuccess() {
321
443
  return function (source) {
@@ -413,13 +535,12 @@ class Query {
413
535
  }
414
536
  return ts < Date.now();
415
537
  }
416
- constructor(_client, _queryConfig, _route, _args) {
538
+ constructor(_client, _queryConfig, _routeWithParams, _args) {
417
539
  this._client = _client;
418
540
  this._queryConfig = _queryConfig;
419
- this._route = _route;
541
+ this._routeWithParams = _routeWithParams;
420
542
  this._args = _args;
421
543
  this._currentId = 0;
422
- this._abortController = new AbortController();
423
544
  this._pollingSubscription = null;
424
545
  this._onAbort$ = new Subject();
425
546
  this._state$ = new BehaviorSubject({
@@ -431,7 +552,7 @@ class Query {
431
552
  return this._client.fetch(this._queryConfig);
432
553
  }
433
554
  execute(options) {
434
- var _a, _b, _c, _d, _e, _f, _g;
555
+ var _a, _b, _c, _d, _e, _f;
435
556
  if (!this.isExpired && !(options === null || options === void 0 ? void 0 : options.skipCache) && isQueryStateSuccess(this.state)) {
436
557
  return this;
437
558
  }
@@ -448,85 +569,103 @@ class Query {
448
569
  meta,
449
570
  });
450
571
  this._updateUseResultInDependencies();
451
- let body = null;
452
- let contentType = null;
572
+ let body;
453
573
  if (isGqlQueryConfig(this._queryConfig)) {
454
574
  const queryTemplate = this._queryConfig.query;
455
575
  const query = transformGql(queryTemplate);
456
- contentType = 'application/json';
457
576
  body = query((_a = this._args) === null || _a === void 0 ? void 0 : _a.variables);
458
577
  }
459
578
  else {
460
- body = buildBody((_b = this._args) === null || _b === void 0 ? void 0 : _b.body);
461
- contentType = guessContentType((_c = this._args) === null || _c === void 0 ? void 0 : _c.body);
579
+ body = serializeBody((_b = this._args) === null || _b === void 0 ? void 0 : _b.body);
462
580
  }
463
581
  let authHeader = null;
464
582
  if (this._queryConfig.secure) {
465
- const header = (_d = this._client.authProvider) === null || _d === void 0 ? void 0 : _d.header;
583
+ const header = (_c = this._client.authProvider) === null || _c === void 0 ? void 0 : _c.header;
466
584
  if (header) {
467
585
  authHeader = header;
468
586
  }
469
587
  }
470
- else if ((_e = this._client.authProvider) === null || _e === void 0 ? void 0 : _e.header) {
588
+ else if ((_d = this._client.authProvider) === null || _d === void 0 ? void 0 : _d.header) {
471
589
  if (this._queryConfig.secure === undefined || this._queryConfig.secure) {
472
590
  authHeader = this._client.authProvider.header;
473
591
  }
474
592
  }
475
- let headers = mergeHeaders(authHeader, (_f = this._args) === null || _f === void 0 ? void 0 : _f.headers);
476
- if (contentType && !(headers === null || headers === void 0 ? void 0 : headers['Content-Type']) && !(headers === null || headers === void 0 ? void 0 : headers['content-type'])) {
477
- if (headers) {
478
- headers['Content-Type'] = contentType;
479
- }
480
- else {
481
- headers = {
482
- 'Content-Type': contentType,
483
- };
484
- }
485
- }
486
- // For form data we need to remove content type header because browser will set it automatically including boundary
487
- if (headers && 'Content-Type' in headers && headers['Content-Type'] === 'multipart/form-data') {
488
- delete headers['Content-Type'];
489
- }
490
593
  request({
491
- route: this._route,
492
- init: {
493
- method: transformMethod(this._queryConfig.method),
494
- signal: this._abortController.signal,
495
- body,
496
- headers: headers || undefined,
497
- },
498
- cacheAdapter: (_g = this._client.config.request) === null || _g === void 0 ? void 0 : _g.cacheAdapter,
499
- })
500
- .then((response) => {
501
- const isResponseObject = typeof response === 'object';
502
- const isGql = isGqlQueryConfig(this._queryConfig);
503
- let responseData = null;
504
- if (isGql &&
505
- isResponseObject &&
506
- !!response.data &&
507
- typeof response.data === 'object' &&
508
- 'data' in response.data) {
509
- responseData = response.data['data'];
510
- }
511
- else {
512
- responseData = response.data;
513
- }
514
- const transformedResponse = this._queryConfig.responseTransformer
515
- ? this._queryConfig.responseTransformer(responseData)
516
- : responseData;
517
- this._state$.next({
518
- type: "SUCCESS" /* QueryStateType.Success */,
519
- response: transformedResponse,
520
- rawResponse: responseData,
521
- meta: Object.assign(Object.assign({}, meta), { expiresAt: response.expiresInTimestamp }),
522
- });
594
+ urlWithParams: this._routeWithParams,
595
+ method: transformMethod(this._queryConfig.method),
596
+ body,
597
+ headers: mergeHeaders(authHeader, (_e = this._args) === null || _e === void 0 ? void 0 : _e.headers) || undefined,
598
+ cacheAdapter: (_f = this._client.config.request) === null || _f === void 0 ? void 0 : _f.cacheAdapter,
599
+ reportProgress: this._queryConfig.reportProgress,
600
+ responseType: this._queryConfig.responseType,
601
+ withCredentials: this._queryConfig.withCredentials,
523
602
  })
524
- .catch((error) => this._handleExecuteError(error, meta));
603
+ .pipe(takeUntil(this._onAbort$))
604
+ .subscribe({
605
+ next: (state) => {
606
+ if (state.type === 'start') {
607
+ this._state$.next({
608
+ type: "LOADING" /* QueryStateType.Loading */,
609
+ meta,
610
+ });
611
+ }
612
+ else if (state.type === 'download-progress') {
613
+ this._state$.next({
614
+ type: "LOADING" /* QueryStateType.Loading */,
615
+ progress: state.progress,
616
+ partialText: state.partialText,
617
+ meta,
618
+ });
619
+ }
620
+ else if (state.type === 'upload-progress') {
621
+ this._state$.next({
622
+ type: "LOADING" /* QueryStateType.Loading */,
623
+ progress: state.progress,
624
+ meta,
625
+ });
626
+ }
627
+ else if (state.type === 'success') {
628
+ const isResponseObject = typeof state.response === 'object';
629
+ const isGql = isGqlQueryConfig(this._queryConfig);
630
+ let responseData = null;
631
+ if (isGql &&
632
+ isResponseObject &&
633
+ !!state.response &&
634
+ typeof state.response === 'object' &&
635
+ 'data' in state.response) {
636
+ responseData = state.response['data'];
637
+ }
638
+ else {
639
+ responseData = state.response;
640
+ }
641
+ const transformedResponse = this._queryConfig.responseTransformer
642
+ ? this._queryConfig.responseTransformer(responseData)
643
+ : responseData;
644
+ this._state$.next({
645
+ type: "SUCCESS" /* QueryStateType.Success */,
646
+ rawResponse: state.response,
647
+ response: transformedResponse,
648
+ meta: Object.assign(Object.assign({}, meta), { expiresAt: state.expiresInTimestamp }),
649
+ });
650
+ }
651
+ else if (state.type === 'failure') {
652
+ this._state$.next({
653
+ type: "FAILURE" /* QueryStateType.Failure */,
654
+ error: state.error,
655
+ meta,
656
+ });
657
+ }
658
+ else if (state.type === 'cancel') {
659
+ this._state$.next({
660
+ type: "CANCELLED" /* QueryStateType.Cancelled */,
661
+ meta,
662
+ });
663
+ }
664
+ },
665
+ });
525
666
  return this;
526
667
  }
527
668
  abort() {
528
- this._abortController.abort();
529
- this._abortController = new AbortController();
530
669
  this._onAbort$.next();
531
670
  return this;
532
671
  }
@@ -567,24 +706,6 @@ class Query {
567
706
  }))
568
707
  .subscribe();
569
708
  }
570
- _handleExecuteError(error, meta) {
571
- if (isAbortRequestError(error)) {
572
- this._state$.next({
573
- type: "CANCELLED" /* QueryStateType.Cancelled */,
574
- meta,
575
- });
576
- }
577
- else if (isRequestError(error)) {
578
- this._state$.next({
579
- type: "FAILURE" /* QueryStateType.Failure */,
580
- error,
581
- meta,
582
- });
583
- }
584
- else {
585
- throw error;
586
- }
587
- }
588
709
  }
589
710
 
590
711
  const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
@@ -779,6 +900,7 @@ class QueryDirective {
779
900
  raw: null,
780
901
  loading: false,
781
902
  error: null,
903
+ progress: null,
782
904
  };
783
905
  this._cache = false;
784
906
  }
@@ -804,11 +926,14 @@ class QueryDirective {
804
926
  this._subscription = sub;
805
927
  }
806
928
  _updateView(state) {
929
+ var _a;
807
930
  if (isQueryStateLoading(state)) {
808
931
  this._viewContext.loading = true;
932
+ this._viewContext.progress = (_a = state.progress) !== null && _a !== void 0 ? _a : null;
809
933
  }
810
934
  else {
811
935
  this._viewContext.loading = false;
936
+ this._viewContext.progress = null;
812
937
  }
813
938
  if (isQueryStateSuccess(state)) {
814
939
  this._viewContext.query = state.response;
@@ -836,9 +961,9 @@ class QueryDirective {
836
961
  }
837
962
  }
838
963
  }
839
- QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
840
- QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.2", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
841
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: QueryDirective, decorators: [{
964
+ QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
965
+ QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
966
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: QueryDirective, decorators: [{
842
967
  type: Directive,
843
968
  args: [{
844
969
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -1017,7 +1142,7 @@ class InfinityQueryDirective {
1017
1142
  itemsPerPage: null,
1018
1143
  };
1019
1144
  this._infinityQueryInstance = null;
1020
- this._destroy$ = inject(DestroyService, { self: true }).destroy$;
1145
+ this._destroy$ = inject(DestroyService, { host: true }).destroy$;
1021
1146
  this._cdr = inject(ChangeDetectorRef);
1022
1147
  this._viewContainerRef = inject(ViewContainerRef);
1023
1148
  this._mainTemplateRef = inject((TemplateRef));
@@ -1134,9 +1259,9 @@ class InfinityQueryDirective {
1134
1259
  this._data$.next([]);
1135
1260
  }
1136
1261
  }
1137
- InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1138
- InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.2", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], ngImport: i0 });
1139
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryDirective, decorators: [{
1262
+ InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1263
+ InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], ngImport: i0 });
1264
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InfinityQueryDirective, decorators: [{
1140
1265
  type: Directive,
1141
1266
  args: [{
1142
1267
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -1187,9 +1312,9 @@ class InfinityQueryTriggerDirective {
1187
1312
  this._observer.observe(this._elementRef.nativeElement);
1188
1313
  }
1189
1314
  }
1190
- InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1191
- InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.2", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
1192
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.2", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
1315
+ InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1316
+ InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
1317
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
1193
1318
  type: Directive,
1194
1319
  args: [{
1195
1320
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -1391,7 +1516,7 @@ class QueryForm {
1391
1516
  this.form = this._setupFormGroup();
1392
1517
  }
1393
1518
  observe(options) {
1394
- return combineLatest(Object.values(this._fields).map((field) => field.changes$)).pipe(map(() => this.form.getRawValue()), distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), tap((values) => {
1519
+ return combineLatest(Object.values(this._fields).map((field) => field.changes$)).pipe(map(() => this.form.getRawValue()), distinctUntilChanged((a, b) => equal(a, b)), tap((values) => {
1395
1520
  if ((options === null || options === void 0 ? void 0 : options.syncViaUrlQueryParams) !== false) {
1396
1521
  this._syncViaUrlQueryParams(values);
1397
1522
  }
@@ -1455,7 +1580,7 @@ class QueryForm {
1455
1580
  if (!this._router || !this._activatedRoute) {
1456
1581
  return;
1457
1582
  }
1458
- const queryParams = structuredClone(this._activatedRoute.snapshot.queryParams);
1583
+ const queryParams = Object.assign({}, clone(this._activatedRoute.snapshot.queryParams));
1459
1584
  for (const [key, value] of Object.entries(values)) {
1460
1585
  if (this._isDefaultValue(key, value) || this._fields[key].data.appendToUrl === false) {
1461
1586
  delete queryParams[key];
@@ -1595,5 +1720,5 @@ const def = () => null;
1595
1720
  * Generated bundle index. Do not edit.
1596
1721
  */
1597
1722
 
1598
- export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildBody, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryString, buildRequestError, buildRoute, buildTimestampFromSeconds, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, extractExpiresInSeconds, extractQuery, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, gql, guessContentType, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAbortRequestError, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isFetchResponse, isGqlQueryConfig, isParamValid, isQuery, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mergeHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, shouldCacheQuery, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
1723
+ export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryString, buildRoute, buildTimestampFromSeconds, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds, extractQuery, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, forEachHeader, getResponseUrl, gql, hasHeader, invalidBaseRouteError, invalidBodyError, invalidRouteError, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isFetchResponse, isGqlQueryConfig, isParamValid, isQuery, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mergeHeaders, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, serializeBody, shouldCacheQuery, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
1599
1724
  //# sourceMappingURL=ethlete-query.mjs.map