@ngutil/data 0.0.38 → 0.0.40

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.
@@ -3,7 +3,7 @@ import { Directive, Input, inject, input, NgModule } from '@angular/core';
3
3
  import { DataSource as DataSource$1 } from '@angular/cdk/collections';
4
4
  import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
5
5
  import { BehaviorSubject, Observable, combineLatest, map, shareReplay, take, of, ReplaySubject, switchMap, distinctUntilChanged, tap, debounceTime, finalize, Subject, takeUntil, throwError } from 'rxjs';
6
- import { deepClone, deepFreeze, isPlainObject, toSorted, Busy } from '@ngutil/common';
6
+ import { deepClone, deepFreeze, isPlainObject, isTruthy, isFalsy, toSorted, Busy } from '@ngutil/common';
7
7
  import { flattenDepth, isEqual, intersection, flattenDeep } from 'lodash';
8
8
 
9
9
  function pathGetterCompile(path) {
@@ -165,6 +165,14 @@ function filterNormalize(filters) {
165
165
  return _normalizeFilter(filters);
166
166
  }
167
167
  function _normalizeFilter(filters, parent) {
168
+ if ("op" in filters && "value" in filters) {
169
+ if (filters["op"] === "|" /* FilterOp.Or */ || filters["op"] === "&" /* FilterOp.And */) {
170
+ return { op: filters["op"], value: filters["value"].map((v) => _normalizeFilter(v, parent)) };
171
+ }
172
+ if ("path" in filters) {
173
+ return filters;
174
+ }
175
+ }
168
176
  const norm = flattenDeep(Object.entries(filters).map(([path, value]) => {
169
177
  switch (path) {
170
178
  case "&" /* FilterOp.And */:
@@ -328,25 +336,10 @@ function or_(fns) {
328
336
  };
329
337
  }
330
338
  function filterMerge(...filters) {
331
- let result = undefined;
332
- for (const filter of filters) {
333
- if (filter == null) {
334
- continue;
335
- }
336
- if (result == null) {
337
- result = deepClone(filter);
338
- }
339
- else {
340
- for (const [k, v] of Object.entries(filter)) {
341
- if (v === undefined) {
342
- delete result[k];
343
- continue;
344
- }
345
- result[k] = deepClone(v);
346
- }
347
- }
348
- }
349
- return result;
339
+ const value = filters
340
+ .filter(v => v && ((Array.isArray(v) && v.length > 0) || (isPlainObject(v) && Object.keys(v).length > 0)))
341
+ .map(filter => deepClone(filter));
342
+ return compact({ op: "&" /* FilterOp.And */, value });
350
343
  }
351
344
  class FilterProperty extends QueryProperty {
352
345
  merge(a, b) {
@@ -364,6 +357,65 @@ class FilterPropertySet extends QueryPropertySet {
364
357
  return filterMerge(...args);
365
358
  }
366
359
  }
360
+ function filterSimplify(filters) {
361
+ if (isTruthy(filters)) {
362
+ filters = compact(filterNormalize(filters));
363
+ const result = {};
364
+ if (filters["op"] === "&" /* FilterOp.And */) {
365
+ filters = filters["value"];
366
+ if (filters == null) {
367
+ return result;
368
+ }
369
+ }
370
+ if (!Array.isArray(filters)) {
371
+ filters = [filters];
372
+ }
373
+ for (const f of filters) {
374
+ if (f["value"] != null &&
375
+ (f["op"] === "==" /* FilterOp.Eq */ || f["op"] === "===" /* FilterOp.EqStrict */ || f["op"] === "==*" /* FilterOp.EqInsesitive */)) {
376
+ result[f["path"]] = f["value"];
377
+ }
378
+ }
379
+ return result;
380
+ }
381
+ else {
382
+ return null;
383
+ }
384
+ }
385
+ function compact(filters) {
386
+ if (filters.op === "&" /* FilterOp.And */ || filters.op === "|" /* FilterOp.Or */) {
387
+ if (isFalsy(filters.value)) {
388
+ return null;
389
+ }
390
+ let value = filters.value.map(compact).filter(isTruthy);
391
+ if (value.length === 0) {
392
+ return null;
393
+ }
394
+ // remove subfilters with the same operator
395
+ value = value.reduce((acc, value) => {
396
+ if (value.op === filters.op) {
397
+ return acc.concat(value.value);
398
+ }
399
+ else {
400
+ acc.push(value);
401
+ return acc;
402
+ }
403
+ }, []);
404
+ // deduplicate, and latest filter is the most priority
405
+ value = value
406
+ .reverse()
407
+ .filter((v, i, a) => a.findIndex(v2 => v.path === v2.path && v.op === v2.op) === i)
408
+ .reverse();
409
+ if (value.length === 1) {
410
+ return value[0];
411
+ }
412
+ return { op: filters.op, value };
413
+ }
414
+ else if (filters.value == null) {
415
+ return null;
416
+ }
417
+ return filters;
418
+ }
367
419
 
368
420
  function groupBy(grouper) {
369
421
  return grouperCompile(grouper);
@@ -920,7 +972,7 @@ class DataSource extends DataSource$1 {
920
972
  this.provider = provider;
921
973
  this.store = store;
922
974
  this.query$ = query$;
923
- this.busy$ = new BehaviorSubject(false);
975
+ this.isBusy$ = new BehaviorSubject(false);
924
976
  this.total$ = new BehaviorSubject(undefined);
925
977
  this.#slice = new ReplaySubject(1);
926
978
  this.slice$ = this.#slice.pipe(switchMap(slice => this.provider.clampSlice(slice)), distinctUntilChanged(isEqual), map(slice => deepFreeze(deepClone(slice))), shareReplay(1));
@@ -949,6 +1001,7 @@ class DataSource extends DataSource$1 {
949
1001
  }), take(1));
950
1002
  }
951
1003
  }))), finalize(() => this.#setBusy(false)), shareReplay(1));
1004
+ this.isEmpty$ = combineLatest({ busy: this.isBusy$, items: this.items$ }).pipe(map(({ busy, items }) => !busy && items?.some(isTruthy)), shareReplay(1));
952
1005
  this.#cvSubs = new Map();
953
1006
  }
954
1007
  setSlice(slice) {
@@ -984,8 +1037,8 @@ class DataSource extends DataSource$1 {
984
1037
  }
985
1038
  #setBusy(busy) {
986
1039
  if (this.provider.isAsync) {
987
- if (this.busy$.value !== busy) {
988
- this.busy$.next(busy);
1040
+ if (this.isBusy$.value !== busy) {
1041
+ this.isBusy$.next(busy);
989
1042
  }
990
1043
  }
991
1044
  }
@@ -1064,6 +1117,8 @@ class DataSourceProxy extends DataSource$1 {
1064
1117
  this.value$ = this.#value.pipe(takeUntilDestroyed());
1065
1118
  this.query$ = this.value$.pipe(map(value => value.query$), shareReplay(1));
1066
1119
  this.items$ = this.value$.pipe(switchMap(value => value.items$), shareReplay(1));
1120
+ this.isBusy$ = this.value$.pipe(switchMap(value => value.isBusy$), shareReplay(1));
1121
+ this.isEmpty$ = this.value$.pipe(switchMap(value => value.isEmpty$), shareReplay(1));
1067
1122
  this.#cvSubs = new Map();
1068
1123
  }
1069
1124
  set value(value) {
@@ -1187,8 +1242,8 @@ class DataSourceProxyBusy {
1187
1242
  constructor() {
1188
1243
  this.#proxy = inject(DataSourceProxy);
1189
1244
  this.#busy = inject(Busy);
1190
- this.busy$ = this.#proxy.value$.pipe(switchMap(value => value.busy$), shareReplay(1));
1191
- this.#busy.connect(this.busy$).pipe(takeUntilDestroyed()).subscribe();
1245
+ this.isBusy$ = this.#proxy.value$.pipe(switchMap(value => value.isBusy$), shareReplay(1));
1246
+ this.#busy.connect(this.isBusy$).pipe(takeUntilDestroyed()).subscribe();
1192
1247
  }
1193
1248
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: DataSourceProxyBusy, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1194
1249
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.6", type: DataSourceProxyBusy, isStandalone: true, selector: "[nuDataSource][nuBusy]", ngImport: i0 }); }
@@ -1418,5 +1473,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.6", ngImpor
1418
1473
  * Generated bundle index. Do not edit.
1419
1474
  */
1420
1475
 
1421
- export { ArrayProvider, CollectionStore, DataProvider, DataSource, DataSourceModule, DataSourceProxy, DataSourceProxyBusy, DataSourceProxyFilter, DataSourceProxyGrouper, DataSourceProxySlimer, DataSourceProxySorter, LocalProvider, MemoryStore, ModelMeta, ModelRefByIndex, ModelRefByKey, ModelRefNorm, ObservableProvider, UnknownMeta, filterBy, filterMerge, filterNormalize, groupBy, grouperMerge, pathGetterCompile, queryExecutor, querySubject, sliceApply, sliceClamp, sliceEq, sliceInsert, sliceMerge, sliceToPages, slimBy, slimerMerge, sortBy, sorterMerge, sorterNormalize };
1476
+ export { ArrayProvider, CollectionStore, DataProvider, DataSource, DataSourceModule, DataSourceProxy, DataSourceProxyBusy, DataSourceProxyFilter, DataSourceProxyGrouper, DataSourceProxySlimer, DataSourceProxySorter, LocalProvider, MemoryStore, ModelMeta, ModelRefByIndex, ModelRefByKey, ModelRefNorm, ObservableProvider, UnknownMeta, filterBy, filterMerge, filterNormalize, filterSimplify, groupBy, grouperMerge, pathGetterCompile, queryExecutor, querySubject, sliceApply, sliceClamp, sliceEq, sliceInsert, sliceMerge, sliceToPages, slimBy, slimerMerge, sortBy, sorterMerge, sorterNormalize };
1422
1477
  //# sourceMappingURL=ngutil-data.mjs.map