@ethlete/query 0.1.0-next.1 → 0.1.0-next.11

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.
Files changed (42) hide show
  1. package/esm2020/lib/auth/auth-provider.types.mjs +1 -1
  2. package/esm2020/lib/auth/basic-auth-provider.mjs +5 -5
  3. package/esm2020/lib/auth/bearer-auth-provider.mjs +12 -9
  4. package/esm2020/lib/auth/custom-header-auth-provider.mjs +4 -4
  5. package/esm2020/lib/directives/infinity-query-trigger.directive.mjs +3 -3
  6. package/esm2020/lib/directives/infinity-query.directive.mjs +36 -11
  7. package/esm2020/lib/directives/query.directive.mjs +17 -17
  8. package/esm2020/lib/infinite-query/infinity-query.mjs +11 -11
  9. package/esm2020/lib/infinite-query/infinity-query.types.mjs +1 -1
  10. package/esm2020/lib/query/query.mjs +49 -23
  11. package/esm2020/lib/query/query.types.mjs +1 -1
  12. package/esm2020/lib/query/query.utils.mjs +17 -2
  13. package/esm2020/lib/query-client/query-client.mjs +7 -7
  14. package/esm2020/lib/query-client/query-client.types.mjs +1 -1
  15. package/esm2020/lib/query-form/query-form.mjs +10 -7
  16. package/esm2020/lib/query-form/query-form.types.mjs +1 -1
  17. package/esm2020/lib/query-form/query-form.utils.mjs +21 -1
  18. package/esm2020/lib/request/request.mjs +5 -3
  19. package/esm2020/lib/request/request.types.mjs +1 -1
  20. package/esm2020/lib/request/request.util.mjs +24 -6
  21. package/esm2020/lib/utils/deep-freeze.util.mjs +5 -1
  22. package/fesm2015/ethlete-query.mjs +240 -117
  23. package/fesm2015/ethlete-query.mjs.map +1 -1
  24. package/fesm2020/ethlete-query.mjs +231 -114
  25. package/fesm2020/ethlete-query.mjs.map +1 -1
  26. package/lib/auth/auth-provider.types.d.ts +11 -1
  27. package/lib/directives/infinity-query-trigger.directive.d.ts +1 -1
  28. package/lib/directives/infinity-query.directive.d.ts +7 -2
  29. package/lib/directives/query.directive.d.ts +1 -1
  30. package/lib/infinite-query/infinity-query.types.d.ts +7 -4
  31. package/lib/query/query.d.ts +5 -3
  32. package/lib/query/query.types.d.ts +17 -14
  33. package/lib/query/query.utils.d.ts +8 -3
  34. package/lib/query-client/query-client.d.ts +9 -9
  35. package/lib/query-client/query-client.types.d.ts +9 -9
  36. package/lib/query-form/query-form.d.ts +1 -1
  37. package/lib/query-form/query-form.types.d.ts +13 -3
  38. package/lib/query-form/query-form.utils.d.ts +5 -0
  39. package/lib/request/request.types.d.ts +12 -10
  40. package/lib/request/request.util.d.ts +2 -2
  41. package/lib/utils/deep-freeze.util.d.ts +1 -1
  42. package/package.json +7 -6
@@ -1,34 +1,35 @@
1
1
  import { __awaiter } from 'tslib';
2
- import { Subject, timer, filter, takeWhile, BehaviorSubject, interval, takeUntil, tap, switchMap, of, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
2
+ import { Subject, timer, filter, takeWhile, switchMap, of, BehaviorSubject, interval, takeUntil, tap, fromEvent, startWith, concat, take, debounceTime, combineLatest, map, distinctUntilChanged } from 'rxjs';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
5
+ import { DestroyService } from '@ethlete/core';
5
6
  import { FormGroup } from '@angular/forms';
6
7
  import { Router, ActivatedRoute } from '@angular/router';
7
8
 
8
9
  class CustomHeaderAuthProvider {
10
+ get header() {
11
+ return { [this._config.name]: this._config.value };
12
+ }
9
13
  constructor(_config) {
10
14
  this._config = _config;
11
15
  this.queryClient = null;
12
16
  }
13
- get header() {
14
- return { [this._config.name]: this._config.value };
15
- }
16
17
  cleanUp() {
17
18
  // noop
18
19
  }
19
20
  }
20
21
 
21
22
  class BasicAuthProvider {
22
- constructor(_config) {
23
- this._config = _config;
24
- this.queryClient = null;
25
- }
26
23
  get header() {
27
24
  return { Authorization: `Basic ${this._basicAuthString}` };
28
25
  }
29
26
  get _basicAuthString() {
30
27
  return btoa(`${this._config.username}:${this._config.password}`);
31
28
  }
29
+ constructor(_config) {
30
+ this._config = _config;
31
+ this.queryClient = null;
32
+ }
32
33
  cleanUp() {
33
34
  // noop
34
35
  }
@@ -166,13 +167,15 @@ const buildTimestampFromSeconds = (seconds) => {
166
167
  }
167
168
  return new Date(Date.now() + seconds * 1000).getTime();
168
169
  };
169
- const buildRequestError = (error) => __awaiter(void 0, void 0, void 0, function* () {
170
+ const buildRequestError = (error, route, requestInit) => __awaiter(void 0, void 0, void 0, function* () {
170
171
  if (error instanceof DOMException && error.code === error.ABORT_ERR) {
171
172
  const err = {
172
173
  code: -1,
173
174
  message: 'Request aborted',
174
175
  detail: null,
175
176
  raw: error,
177
+ route,
178
+ requestInit,
176
179
  };
177
180
  return err;
178
181
  }
@@ -182,6 +185,8 @@ const buildRequestError = (error) => __awaiter(void 0, void 0, void 0, function*
182
185
  message: 'Syntax error',
183
186
  detail: null,
184
187
  raw: error,
188
+ route,
189
+ requestInit,
185
190
  };
186
191
  return err;
187
192
  }
@@ -191,23 +196,35 @@ const buildRequestError = (error) => __awaiter(void 0, void 0, void 0, function*
191
196
  message: `${error.name}: ${error.message}`,
192
197
  detail: null,
193
198
  raw: error,
199
+ route,
200
+ requestInit,
194
201
  };
195
202
  return err;
196
203
  }
197
204
  if (isFetchResponse(error)) {
198
205
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
- let detail;
206
+ let detail = null;
200
207
  try {
201
- detail = yield error.text();
208
+ detail = yield error.json();
202
209
  }
203
- catch (err) {
204
- detail = null;
210
+ catch (_a) {
211
+ // noop
212
+ }
213
+ if (!detail) {
214
+ try {
215
+ detail = yield error.text();
216
+ }
217
+ catch (_b) {
218
+ // noop
219
+ }
205
220
  }
206
221
  const err = {
207
222
  code: error.status,
208
223
  message: error.statusText,
209
224
  detail,
210
225
  raw: error,
226
+ route,
227
+ requestInit,
211
228
  };
212
229
  return err;
213
230
  }
@@ -216,6 +233,8 @@ const buildRequestError = (error) => __awaiter(void 0, void 0, void 0, function*
216
233
  message: 'Unknown error',
217
234
  detail: null,
218
235
  raw: error,
236
+ route,
237
+ requestInit,
219
238
  };
220
239
  return err;
221
240
  });
@@ -257,12 +276,15 @@ const guessContentType = (body) => {
257
276
  };
258
277
 
259
278
  const request = (options) => __awaiter(void 0, void 0, void 0, function* () {
279
+ var _a, _b;
260
280
  try {
261
281
  const response = yield fetch(options.route, options.init);
262
282
  if (!response.ok) {
263
283
  throw response;
264
284
  }
265
- const data = (yield response.json());
285
+ const isJsonResponse = (_a = response.headers.get('Content-Type')) === null || _a === void 0 ? void 0 : _a.includes('application/json');
286
+ const isTextResponse = (_b = response.headers.get('Content-Type')) === null || _b === void 0 ? void 0 : _b.includes('text/plain');
287
+ const data = (isJsonResponse ? yield response.json() : isTextResponse ? yield response.text() : null);
266
288
  const expiresInSeconds = options.cacheAdapter
267
289
  ? options.cacheAdapter(response.headers)
268
290
  : extractExpiresInSeconds(response.headers);
@@ -270,7 +292,7 @@ const request = (options) => __awaiter(void 0, void 0, void 0, function* () {
270
292
  return { data, expiresInTimestamp };
271
293
  }
272
294
  catch (error) {
273
- throw yield buildRequestError(error);
295
+ throw yield buildRequestError(error, options.route, options.init);
274
296
  }
275
297
  });
276
298
 
@@ -294,6 +316,9 @@ const decryptBearer = (token) => {
294
316
  };
295
317
 
296
318
  class BearerAuthProvider {
319
+ get header() {
320
+ return { Authorization: `Bearer ${this._token}` };
321
+ }
297
322
  constructor(_config) {
298
323
  var _a, _b;
299
324
  this._config = _config;
@@ -309,16 +334,13 @@ class BearerAuthProvider {
309
334
  this._setupRefresh(this._config.refreshConfig);
310
335
  }
311
336
  }
312
- get header() {
313
- return { Authorization: `Bearer ${this._token}` };
314
- }
315
337
  cleanUp() {
316
338
  var _a;
317
339
  (_a = this._refreshTimerSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
318
340
  this._refreshTimerSubscription = null;
319
341
  }
320
342
  _setupRefresh(config) {
321
- var _a;
343
+ var _a, _b;
322
344
  const bearer = decryptBearer(this._token);
323
345
  if (!bearer) {
324
346
  return;
@@ -326,11 +348,12 @@ class BearerAuthProvider {
326
348
  const expiresInPropertyName = config.expiresInPropertyName || 'exp';
327
349
  const expiresIn = bearer[expiresInPropertyName];
328
350
  const fiveMinutes = 5 * 60 * 1000;
351
+ const refreshBuffer = (_a = config.refreshBuffer) !== null && _a !== void 0 ? _a : fiveMinutes;
329
352
  if (expiresIn === undefined) {
330
353
  throw new Error(`Bearer token does not contain an '${expiresInPropertyName}' property`);
331
354
  }
332
- const remainingTime = new Date(expiresIn * 1000).getTime() - fiveMinutes - new Date().getTime();
333
- const strategy = (_a = config.strategy) !== null && _a !== void 0 ? _a : "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */;
355
+ const remainingTime = new Date(expiresIn * 1000).getTime() - refreshBuffer - new Date().getTime();
356
+ const strategy = (_b = config.strategy) !== null && _b !== void 0 ? _b : "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */;
334
357
  switch (strategy) {
335
358
  case "beforeExpiration" /* AuthBearerRefreshStrategy.BeforeExpiration */:
336
359
  this._refreshTimerSubscription = timer(remainingTime).subscribe(() => this._refresh(config));
@@ -338,6 +361,7 @@ class BearerAuthProvider {
338
361
  }
339
362
  }
340
363
  _refresh(config) {
364
+ var _a;
341
365
  return __awaiter(this, void 0, void 0, function* () {
342
366
  if (!this._refreshToken) {
343
367
  throw new Error('No refresh token found');
@@ -345,17 +369,19 @@ class BearerAuthProvider {
345
369
  if (!this.queryClient) {
346
370
  throw new Error('Query client instance is null');
347
371
  }
348
- const { method, route, bodyAdapter, responseAdapter } = config;
372
+ const { method, route, requestAdapter, responseAdapter, paramLocation } = config;
373
+ const data = (_a = requestAdapter === null || requestAdapter === void 0 ? void 0 : requestAdapter(this._refreshToken)) !== null && _a !== void 0 ? _a : { refreshToken: this._refreshToken };
349
374
  const fullRoute = buildRoute({
350
375
  base: this.queryClient.config.baseRoute,
351
376
  route,
377
+ queryParams: paramLocation === 'query' ? data : undefined,
352
378
  });
353
- const body = bodyAdapter ? bodyAdapter(this._refreshToken) : { refreshToken: this._refreshToken };
379
+ const requestInit = { body: paramLocation === 'body' ? buildBody(data) : undefined, method };
354
380
  this.onRefreshInitiation$.next();
355
381
  try {
356
382
  const result = yield request({
357
383
  route: fullRoute,
358
- init: { body: buildBody(body), method },
384
+ init: requestInit,
359
385
  });
360
386
  const tokens = responseAdapter ? responseAdapter(result.data) : result.data;
361
387
  if (!tokens.token) {
@@ -370,7 +396,7 @@ class BearerAuthProvider {
370
396
  }
371
397
  catch (error) {
372
398
  if (error instanceof Error) {
373
- this.onRefreshFailure$.next(yield buildRequestError(error));
399
+ this.onRefreshFailure$.next(yield buildRequestError(error, fullRoute, requestInit));
374
400
  }
375
401
  else {
376
402
  this.onRefreshFailure$.next(error);
@@ -403,27 +429,6 @@ const gql = (strings, ...values) => {
403
429
  return str;
404
430
  };
405
431
 
406
- const deepFreeze = (object) => {
407
- // Retrieve the property names defined on object
408
- const propNames = Object.getOwnPropertyNames(object);
409
- // Freeze properties before freezing self
410
- for (const name of propNames) {
411
- const value = object[name];
412
- if (value && typeof value === 'object') {
413
- deepFreeze(value);
414
- }
415
- }
416
- return Object.freeze(object);
417
- };
418
-
419
- /**
420
- * Dummy function for providing types while not breaking inference.
421
- * **This function always returns null.**
422
- * @see https://github.com/microsoft/TypeScript/issues/26242
423
- * @returns null
424
- */
425
- const def = () => null;
426
-
427
432
  function filterSuccess() {
428
433
  return function (source) {
429
434
  return source.pipe(filter((value) => isQueryStateSuccess(value)));
@@ -434,11 +439,26 @@ function filterFailure() {
434
439
  return source.pipe(filter((value) => isQueryStateFailure(value)));
435
440
  };
436
441
  }
442
+ function filterQueryStates(allowedStates) {
443
+ return function (source) {
444
+ return source.pipe(filter((value) => value && allowedStates.includes(value.type)));
445
+ };
446
+ }
437
447
  function takeUntilResponse() {
438
448
  return function (source) {
439
449
  return source.pipe(takeWhile((value) => isQueryStateLoading(value), true));
440
450
  };
441
451
  }
452
+ function filterNull() {
453
+ return function (source) {
454
+ return source.pipe(filter((value) => value !== null));
455
+ };
456
+ }
457
+ function switchQueryState() {
458
+ return function (source) {
459
+ return source.pipe(switchMap((value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.state$) !== null && _a !== void 0 ? _a : of(null); }));
460
+ };
461
+ }
442
462
  const isQueryStateLoading = (state) => (state === null || state === void 0 ? void 0 : state.type) === "LOADING" /* QueryStateType.Loading */;
443
463
  const isQueryStateSuccess = (state) => (state === null || state === void 0 ? void 0 : state.type) === "SUCCESS" /* QueryStateType.Success */;
444
464
  const isQueryStateFailure = (state) => (state === null || state === void 0 ? void 0 : state.type) === "FAILURE" /* QueryStateType.Failure */;
@@ -463,21 +483,8 @@ const isGqlQueryConfig = (config) => {
463
483
  };
464
484
 
465
485
  class Query {
466
- constructor(_client, _queryConfig, _route, _args) {
467
- this._client = _client;
468
- this._queryConfig = _queryConfig;
469
- this._route = _route;
470
- this._args = _args;
471
- this._currentId = 0;
472
- this._abortController = new AbortController();
473
- this._pollingSubscription = null;
474
- this._state$ = new BehaviorSubject({
475
- type: "PREPARED" /* QueryStateType.Prepared */,
476
- meta: { id: this._currentId },
477
- });
478
- }
479
486
  get _nextId() {
480
- return this._currentId++;
487
+ return ++this._currentId;
481
488
  }
482
489
  get state$() {
483
490
  return this._state$.asObservable();
@@ -495,6 +502,20 @@ class Query {
495
502
  }
496
503
  return ts < Date.now();
497
504
  }
505
+ constructor(_client, _queryConfig, _route, _args) {
506
+ this._client = _client;
507
+ this._queryConfig = _queryConfig;
508
+ this._route = _route;
509
+ this._args = _args;
510
+ this._currentId = 0;
511
+ this._abortController = new AbortController();
512
+ this._pollingSubscription = null;
513
+ this._onAbort$ = new Subject();
514
+ this._state$ = new BehaviorSubject({
515
+ type: "PREPARED" /* QueryStateType.Prepared */,
516
+ meta: { id: this._currentId },
517
+ });
518
+ }
498
519
  clone() {
499
520
  return this._client.fetch(this._queryConfig);
500
521
  }
@@ -510,11 +531,12 @@ class Query {
510
531
  if (isQueryStateLoading(this._state$.value)) {
511
532
  this.abort();
512
533
  }
513
- const meta = deepFreeze({ id });
534
+ const meta = { id };
514
535
  this._state$.next({
515
536
  type: "LOADING" /* QueryStateType.Loading */,
516
537
  meta,
517
538
  });
539
+ this._updateUseResultInDependencies();
518
540
  let body = null;
519
541
  let contentType = null;
520
542
  if (isGqlQueryConfig(this._queryConfig)) {
@@ -564,7 +586,11 @@ class Query {
564
586
  const isResponseObject = typeof response === 'object';
565
587
  const isGql = isGqlQueryConfig(this._queryConfig);
566
588
  let responseData = null;
567
- if (isGql && isResponseObject && 'data' in response.data) {
589
+ if (isGql &&
590
+ isResponseObject &&
591
+ !!response.data &&
592
+ typeof response.data === 'object' &&
593
+ 'data' in response.data) {
568
594
  responseData = response.data['data'];
569
595
  }
570
596
  else {
@@ -575,9 +601,9 @@ class Query {
575
601
  : responseData;
576
602
  this._state$.next({
577
603
  type: "SUCCESS" /* QueryStateType.Success */,
578
- response: deepFreeze(transformedResponse),
579
- rawResponse: deepFreeze(responseData),
580
- meta: deepFreeze(Object.assign(Object.assign({}, meta), { expiresAt: response.expiresInTimestamp })),
604
+ response: transformedResponse,
605
+ rawResponse: responseData,
606
+ meta: Object.assign(Object.assign({}, meta), { expiresAt: response.expiresInTimestamp }),
581
607
  });
582
608
  })
583
609
  .catch((error) => this._handleExecuteError(error, meta));
@@ -586,6 +612,7 @@ class Query {
586
612
  abort() {
587
613
  this._abortController.abort();
588
614
  this._abortController = new AbortController();
615
+ this._onAbort$.next();
589
616
  return this;
590
617
  }
591
618
  poll(config) {
@@ -603,6 +630,28 @@ class Query {
603
630
  this._pollingSubscription = null;
604
631
  return this;
605
632
  }
633
+ _updateUseResultInDependencies() {
634
+ var _a, _b;
635
+ if (!((_b = (_a = this._args) === null || _a === void 0 ? void 0 : _a.useResultIn) === null || _b === void 0 ? void 0 : _b.length)) {
636
+ return;
637
+ }
638
+ this.state$
639
+ .pipe(filterSuccess(), takeUntil(this._onAbort$), takeUntilResponse(), tap((state) => {
640
+ var _a;
641
+ if (!((_a = this._args) === null || _a === void 0 ? void 0 : _a.useResultIn)) {
642
+ return;
643
+ }
644
+ for (const query of this._args.useResultIn) {
645
+ query._state$.next({
646
+ type: "SUCCESS" /* QueryStateType.Success */,
647
+ meta: Object.assign(Object.assign({}, state.meta), { id: query._nextId }),
648
+ rawResponse: state.rawResponse,
649
+ response: state.response,
650
+ });
651
+ }
652
+ }))
653
+ .subscribe();
654
+ }
606
655
  _handleExecuteError(error, meta) {
607
656
  if (isAbortRequestError(error)) {
608
657
  this._state$.next({
@@ -624,6 +673,19 @@ class Query {
624
673
  }
625
674
 
626
675
  class QueryDirective {
676
+ get query() {
677
+ return this._query;
678
+ }
679
+ set query(v) {
680
+ this._query = v;
681
+ this._subscribeToQuery();
682
+ }
683
+ get cache() {
684
+ return this._cache;
685
+ }
686
+ set cache(v) {
687
+ this._cache = v;
688
+ }
627
689
  constructor(_mainTemplateRef, _viewContainerRef, _errorHandler, _cdr) {
628
690
  this._mainTemplateRef = _mainTemplateRef;
629
691
  this._viewContainerRef = _viewContainerRef;
@@ -640,19 +702,6 @@ class QueryDirective {
640
702
  };
641
703
  this._cache = false;
642
704
  }
643
- get query() {
644
- return this._query;
645
- }
646
- set query(v) {
647
- this._query = v;
648
- this._subscribeToQuery();
649
- }
650
- get cache() {
651
- return this._cache;
652
- }
653
- set cache(v) {
654
- this._cache = v;
655
- }
656
705
  static ngTemplateContextGuard(dir, ctx) {
657
706
  return true;
658
707
  }
@@ -706,9 +755,9 @@ class QueryDirective {
706
755
  }
707
756
  }
708
757
  }
709
- QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
710
- QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
711
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: QueryDirective, decorators: [{
758
+ QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
759
+ QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.0", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: QueryDirective, decorators: [{
712
761
  type: Directive,
713
762
  args: [{
714
763
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -724,17 +773,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
724
773
 
725
774
  /* eslint-disable @typescript-eslint/no-explicit-any */
726
775
  class InfinityQuery {
727
- constructor(_config) {
728
- var _a, _b;
729
- this._config = _config;
730
- this._currentPage$ = new BehaviorSubject(null);
731
- this._currentCalculatedPage$ = new BehaviorSubject(null);
732
- this._totalPages$ = new BehaviorSubject(null);
733
- this._itemsPerPage$ = new BehaviorSubject((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
734
- this._currentQuery$ = new BehaviorSubject(null);
735
- this._data$ = new BehaviorSubject([]);
736
- this._subscriptions = [];
737
- }
738
776
  get currentPage$() {
739
777
  return this._currentPage$.asObservable();
740
778
  }
@@ -771,6 +809,17 @@ class InfinityQuery {
771
809
  get data() {
772
810
  return this._data$.getValue();
773
811
  }
812
+ constructor(_config) {
813
+ var _a, _b;
814
+ this._config = _config;
815
+ this._currentPage$ = new BehaviorSubject(null);
816
+ this._currentCalculatedPage$ = new BehaviorSubject(null);
817
+ this._totalPages$ = new BehaviorSubject(null);
818
+ this._itemsPerPage$ = new BehaviorSubject((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
819
+ this._currentQuery$ = new BehaviorSubject(null);
820
+ this._data$ = new BehaviorSubject([]);
821
+ this._subscriptions = [];
822
+ }
774
823
  nextPage() {
775
824
  var _a, _b, _c, _d, _e;
776
825
  const newPage = ((_a = this._currentPage$.value) !== null && _a !== void 0 ? _a : 0) + 1;
@@ -873,6 +922,7 @@ const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPa
873
922
  const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
874
923
  class InfinityQueryDirective {
875
924
  constructor() {
925
+ this._queryConfigChanged$ = new Subject();
876
926
  this._viewContext = {
877
927
  $implicit: null,
878
928
  infinityQuery: null,
@@ -886,17 +936,19 @@ class InfinityQueryDirective {
886
936
  itemsPerPage: null,
887
937
  };
888
938
  this._infinityQueryInstance = null;
889
- this._destroy$ = new Subject();
939
+ this._destroy$ = inject(DestroyService).destroy$;
890
940
  this._cdr = inject(ChangeDetectorRef);
891
941
  this._viewContainerRef = inject(ViewContainerRef);
892
942
  this._mainTemplateRef = inject((TemplateRef));
893
943
  this._errorHandler = inject(ErrorHandler);
944
+ this._data$ = new BehaviorSubject([]);
894
945
  this._isMainViewCreated = false;
895
946
  }
896
947
  get infinityQuery() {
897
948
  return this._infinityQuery;
898
949
  }
899
950
  set infinityQuery(v) {
951
+ this._cleanup();
900
952
  this._infinityQuery = v;
901
953
  this._infinityQueryInstance = this._setupInfinityQuery(v);
902
954
  this._loadNextPage();
@@ -907,6 +959,12 @@ class InfinityQueryDirective {
907
959
  get instance() {
908
960
  return this._infinityQueryInstance;
909
961
  }
962
+ get data$() {
963
+ return this._data$.asObservable();
964
+ }
965
+ get data() {
966
+ return this._data$.getValue();
967
+ }
910
968
  static ngTemplateContextGuard(dir, ctx) {
911
969
  return true;
912
970
  }
@@ -915,8 +973,6 @@ class InfinityQueryDirective {
915
973
  }
916
974
  ngOnDestroy() {
917
975
  var _a;
918
- this._destroy$.next(true);
919
- this._destroy$.unsubscribe();
920
976
  (_a = this.instance) === null || _a === void 0 ? void 0 : _a._destroy();
921
977
  }
922
978
  _setupInfinityQuery(config) {
@@ -955,15 +1011,17 @@ class InfinityQueryDirective {
955
1011
  this._viewContext.currentPage = null;
956
1012
  this._viewContext.itemsPerPage = null;
957
1013
  this._viewContext.totalPages = null;
1014
+ this._data$.next([]);
958
1015
  }
959
1016
  this._cdr.markForCheck();
960
- }), takeUntil(this._destroy$))
1017
+ }), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
961
1018
  .subscribe();
962
1019
  instance.data$
963
1020
  .pipe(tap((data) => {
964
1021
  this._viewContext.infinityQuery = this._viewContext.$implicit = data;
1022
+ this._data$.next(data);
965
1023
  this._cdr.markForCheck();
966
- }), takeUntil(this._destroy$))
1024
+ }), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
967
1025
  .subscribe();
968
1026
  return instance;
969
1027
  }
@@ -979,16 +1037,32 @@ class InfinityQueryDirective {
979
1037
  this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
980
1038
  }
981
1039
  }
1040
+ _cleanup() {
1041
+ var _a;
1042
+ this._queryConfigChanged$.next(true);
1043
+ (_a = this.instance) === null || _a === void 0 ? void 0 : _a._destroy();
1044
+ this._viewContext.loading = false;
1045
+ this._viewContext.error = null;
1046
+ this._viewContext.infinityQuery = null;
1047
+ this._viewContext.$implicit = null;
1048
+ this._viewContext.isFirstLoad = false;
1049
+ this._viewContext.canLoadMore = false;
1050
+ this._viewContext.currentPage = null;
1051
+ this._viewContext.itemsPerPage = null;
1052
+ this._viewContext.totalPages = null;
1053
+ this._data$.next([]);
1054
+ }
982
1055
  }
983
- InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
984
- InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], ngImport: i0 });
985
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: InfinityQueryDirective, decorators: [{
1056
+ InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1057
+ InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.0", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], ngImport: i0 });
1058
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryDirective, decorators: [{
986
1059
  type: Directive,
987
1060
  args: [{
988
1061
  // eslint-disable-next-line @angular-eslint/directive-selector
989
1062
  selector: '[infinityQuery]',
1063
+ exportAs: 'infinityQuery',
990
1064
  standalone: true,
991
- providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }],
1065
+ providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
992
1066
  }]
993
1067
  }], propDecorators: { infinityQuery: [{
994
1068
  type: Input
@@ -1032,9 +1106,9 @@ class InfinityQueryTriggerDirective {
1032
1106
  this._observer.observe(this._elementRef.nativeElement);
1033
1107
  }
1034
1108
  }
1035
- InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1036
- InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
1037
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
1109
+ InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1110
+ InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.0", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
1111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
1038
1112
  type: Directive,
1039
1113
  args: [{
1040
1114
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -1129,6 +1203,12 @@ config, args) => {
1129
1203
  };
1130
1204
 
1131
1205
  class QueryClient {
1206
+ get config() {
1207
+ return this._clientConfig;
1208
+ }
1209
+ get authProvider() {
1210
+ return this._authProvider;
1211
+ }
1132
1212
  constructor(_clientConfig) {
1133
1213
  var _a, _b;
1134
1214
  this._clientConfig = _clientConfig;
@@ -1184,23 +1264,17 @@ class QueryClient {
1184
1264
  enableGarbageCollectorLogging: (_b = _clientConfig.logging) === null || _b === void 0 ? void 0 : _b.queryStateGarbageCollector,
1185
1265
  });
1186
1266
  }
1187
- get config() {
1188
- return this._clientConfig;
1189
- }
1190
- get authProvider() {
1191
- return this._authProvider;
1192
- }
1193
1267
  }
1194
1268
 
1195
1269
  class QueryField {
1270
+ get control() {
1271
+ return this.data.control;
1272
+ }
1196
1273
  constructor(data) {
1197
1274
  this.data = data;
1198
1275
  this.changes$ = this._setupChangesObservable();
1199
1276
  this._currentDebounceTimeout = null;
1200
1277
  }
1201
- get control() {
1202
- return this.data.control;
1203
- }
1204
1278
  setValue(value) {
1205
1279
  if (this._currentDebounceTimeout !== null) {
1206
1280
  clearTimeout(this._currentDebounceTimeout);
@@ -1248,10 +1322,11 @@ class QueryForm {
1248
1322
  const queryParams = this._activatedRoute.snapshot.queryParams;
1249
1323
  for (const [key, field] of Object.entries(this._fields)) {
1250
1324
  const value = queryParams[key];
1251
- if (value === undefined) {
1325
+ // We only check using == because the value types can be different (e.g. "1" and 1)
1326
+ if (value === undefined || value == field.control.value) {
1252
1327
  continue;
1253
1328
  }
1254
- const deserializedValue = (_c = (_b = (_a = field.data).queryParamTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)) !== null && _c !== void 0 ? _c : value;
1329
+ const deserializedValue = (_c = (_b = (_a = field.data).queryParamToValueTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)) !== null && _c !== void 0 ? _c : value;
1255
1330
  field.setValue(deserializedValue);
1256
1331
  }
1257
1332
  }
@@ -1293,6 +1368,7 @@ class QueryForm {
1293
1368
  return defaultValues;
1294
1369
  }
1295
1370
  _syncViaUrlQueryParams(values) {
1371
+ var _a, _b;
1296
1372
  if (!this._router || !this._activatedRoute) {
1297
1373
  return;
1298
1374
  }
@@ -1302,7 +1378,9 @@ class QueryForm {
1302
1378
  delete queryParams[key];
1303
1379
  }
1304
1380
  else {
1305
- queryParams[key] = value;
1381
+ queryParams[key] = this._fields[key].data.valueToQueryParamTransformFn
1382
+ ? (_b = (_a = this._fields[key].data).valueToQueryParamTransformFn) === null || _b === void 0 ? void 0 : _b.call(_a, value)
1383
+ : value;
1306
1384
  }
1307
1385
  }
1308
1386
  this._router.navigate([], {
@@ -1384,10 +1462,55 @@ const transformToDateArray = (value) => {
1384
1462
  }
1385
1463
  return null;
1386
1464
  };
1465
+ const transformToSort = (value) => {
1466
+ if (typeof value === 'string') {
1467
+ const [active, direction] = value.split(':');
1468
+ return {
1469
+ active,
1470
+ direction: direction,
1471
+ };
1472
+ }
1473
+ return null;
1474
+ };
1475
+ const transformToSortQueryParam = (value) => {
1476
+ if (typeof value === 'string') {
1477
+ return value;
1478
+ }
1479
+ if (value && typeof value === 'object' && 'active' in value && 'direction' in value) {
1480
+ const valAsSort = value;
1481
+ return valAsSort.direction ? `${valAsSort.active}:${valAsSort.direction}` : null;
1482
+ }
1483
+ return null;
1484
+ };
1485
+
1486
+ const deepFreeze = (object) => {
1487
+ // check if object is actually an object or frozen
1488
+ if (!object || typeof object !== 'object' || Object.isFrozen(object)) {
1489
+ return object;
1490
+ }
1491
+ // Retrieve the property names defined on object
1492
+ const propNames = Object.getOwnPropertyNames(object);
1493
+ // Freeze properties before freezing self
1494
+ for (const name of propNames) {
1495
+ const value = object[name];
1496
+ if (value && typeof value === 'object') {
1497
+ deepFreeze(value);
1498
+ }
1499
+ }
1500
+ return Object.freeze(object);
1501
+ };
1502
+
1503
+ /**
1504
+ * Dummy function for providing types while not breaking inference.
1505
+ * **This function always returns null.**
1506
+ * @see https://github.com/microsoft/TypeScript/issues/26242
1507
+ * @returns null
1508
+ */
1509
+ const def = () => null;
1387
1510
 
1388
1511
  /**
1389
1512
  * Generated bundle index. Do not edit.
1390
1513
  */
1391
1514
 
1392
- 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, decryptBearer, deepFreeze, def, extractExpiresInSeconds, filterFailure, filterInvalidParams, filterSuccess, gql, guessContentType, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAbortRequestError, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isFetchResponse, isGqlQueryConfig, isParamValid, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mergeHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, shouldCacheQuery, skipPaginationPageParamCalculator, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToString, transformToStringArray };
1515
+ 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, decryptBearer, deepFreeze, def, extractExpiresInSeconds, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, gql, guessContentType, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAbortRequestError, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isFetchResponse, isGqlQueryConfig, isParamValid, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mergeHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, shouldCacheQuery, skipPaginationPageParamCalculator, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
1393
1516
  //# sourceMappingURL=ethlete-query.mjs.map