@ngutil/data 0.0.102 → 0.0.104

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.
package/index.d.ts CHANGED
@@ -1,12 +1,589 @@
1
- import * as i0 from "@angular/core";
2
- import * as i1 from "./source/proxy.directive";
3
- export * from "./model";
4
- export * from "./provider";
5
- export * from "./query";
6
- export * from "./source";
7
- export * from "./store";
8
- export declare class DataSourceModule {
1
+ import * as i0 from '@angular/core';
2
+ import { TrackByFunction, OnDestroy } from '@angular/core';
3
+ import * as _ngutil_data from '@ngutil/data';
4
+ import { Primitive } from 'utility-types';
5
+ import { Observable, BehaviorSubject } from 'rxjs';
6
+ import { Flatten, Primitive as Primitive$1, DeepReadonly, ConnectProtocol } from '@ngutil/common';
7
+ import { DataSource as DataSource$1, CollectionViewer, ListRange } from '@angular/cdk/collections';
8
+
9
+ type Model = {
10
+ [key: string]: any;
11
+ };
12
+ type ModelRef = {
13
+ key?: Primitive | Array<Primitive>;
14
+ index?: number;
15
+ };
16
+ type ModelRefFilter<T> = (item: T, index: number) => boolean;
17
+ interface ModelMetaProps<T extends Model> {
18
+ readonly keys: readonly string[];
19
+ readonly trackBy?: TrackByFunction<T>;
20
+ }
21
+ type ModelMetaInput<T extends Model> = ModelMeta<T> | ModelMetaProps<T>;
22
+ type TrackedModel<T extends Model> = {
23
+ index: number;
24
+ model: T;
25
+ };
26
+ declare class ModelMeta<T extends Model> implements ModelMetaProps<T> {
27
+ #private;
28
+ static coerce<M extends Model>(value: ModelMetaInput<M>): ModelMeta<M>;
29
+ readonly keys: readonly string[];
30
+ readonly trackBy: TrackByFunction<T>;
31
+ constructor(props: ModelMetaProps<T>);
32
+ isEqual(a: T, b: T): boolean;
33
+ isEqualByTrack(a: TrackedModel<T>, b: TrackedModel<T>): boolean;
34
+ isEqualByKey(a: T, b: T): boolean;
35
+ normalizeRef(ref: ModelRef | ModelRefNorm): ModelRefNorm;
36
+ }
37
+ declare abstract class ModelRefNorm {
38
+ #private;
39
+ readonly key?: readonly Primitive[];
40
+ readonly index?: number;
41
+ toFilter(): ModelRefFilter<any>;
42
+ protected abstract _asFilter(): ModelRefFilter<any>;
43
+ }
44
+ declare class ModelRefByKey extends ModelRefNorm {
45
+ #private;
46
+ readonly key: readonly Primitive[];
47
+ constructor(key: readonly Primitive[], keys: readonly string[]);
48
+ protected _asFilter(): ModelRefFilter<any>;
49
+ }
50
+ declare class ModelRefByIndex extends ModelRefNorm {
51
+ readonly index: number;
52
+ constructor(index: number);
53
+ protected _asFilter(): ModelRefFilter<any>;
54
+ }
55
+ declare class UnknownMeta<T extends Model> extends ModelMeta<T> {
56
+ constructor();
57
+ }
58
+
59
+ type GrouperFn<T = any> = (item: any) => Primitive$1;
60
+ type Grouper<T extends Model, F = Flatten<T>> = any;
61
+ type GrouperNormalized = any;
62
+ declare function groupBy<T extends Model, F = Flatten<T>>(grouper: Grouper<T, F>): GrouperFn<T>;
63
+ declare function grouperMerge<T extends Model, F = Flatten<T>>(...groupers: Array<Grouper<T, F> | undefined | null>): Grouper<T, F> | undefined;
64
+ declare class GrouperProperty<T extends Model> extends QueryProperty<Grouper<T>, GrouperNormalized> {
65
+ protected norm(a: any): any;
66
+ protected merge(a?: any, b?: any): any;
67
+ }
68
+ declare class GrouperPropertySet<T extends Model> extends QueryPropertySet<Grouper<T>> {
69
+ protected newProperty(): GrouperProperty<Model>;
70
+ protected merge(...args: any[]): any;
71
+ }
72
+
73
+ /**
74
+ * @exmaple
75
+ * ```ts
76
+ * [
77
+ * "field_name",
78
+ * {"child_name": ["child_field_name"]},
79
+ * {"children": ["children_field_name", {"$type": Article, slimer: ["id", "title"]}]},
80
+ * {"$type": Employee, slimer: ["name"]}.
81
+ * {"$filter": Filter<T, F>}
82
+ * ]
83
+ * ```
84
+ */
85
+ type Slimer<T extends Model> = any;
86
+ type SlimerNormalized = any;
87
+ declare function slimBy<T extends Model>(slimer: Slimer<T>): void;
88
+ declare function slimerMerge<T extends Model>(...slimers: Slimer<T>): any;
89
+ declare class SlimerProperty<T extends Model> extends QueryProperty<Slimer<T>, SlimerNormalized> {
90
+ protected norm(a: any): any;
91
+ protected merge(a?: any, b?: any): any;
92
+ }
93
+ declare class SlimerPropertySet<T extends Model> extends QueryPropertySet<Slimer<T>> {
94
+ protected newProperty(): SlimerProperty<Model>;
95
+ protected merge(...args: any[]): any;
96
+ }
97
+
98
+ type PartialCollection<T> = readonly (T | undefined)[];
99
+ declare abstract class CollectionStore<T extends Model> {
100
+ /**
101
+ * Update the given slice, and return all items observable
102
+ */
103
+ abstract insertSlice(slice: DeepReadonly<Slice>, items: readonly T[]): Observable<PartialCollection<T>>;
104
+ /**
105
+ * @returns `true` when the given slice is available in the cache
106
+ */
107
+ abstract hasSlice(slice: DeepReadonly<Slice>): Observable<boolean>;
108
+ /**
109
+ * @returns items by the given slice
110
+ */
111
+ abstract getSlice(slice: DeepReadonly<Slice>): Observable<PartialCollection<T>>;
112
+ /**
113
+ * Get item from collection
114
+ */
115
+ abstract get(ref: ModelRefNorm): Observable<T | undefined>;
116
+ /**
117
+ * Get index of item in collection, -1 if not found
118
+ */
119
+ abstract indexOf(ref: ModelRefNorm): Observable<number>;
120
+ /**
121
+ * Update item in collection
122
+ *
123
+ * @returns the updated index, or -1 if not found
124
+ */
125
+ abstract update(ref: ModelRefNorm, item: T): Observable<number>;
126
+ /**
127
+ * Update item if exists in collection, or insert at the given position
128
+ *
129
+ * @param position If positon is negative, insert at the end of collection
130
+ * @returns the updated index or index of where to insert
131
+ */
132
+ abstract updateOrInsert(ref: ModelRefNorm, item: T, position?: number): Observable<number>;
133
+ /**
134
+ * Remove item from collection
135
+ * @returns the index of deleted item, -1 if not found
136
+ */
137
+ abstract del(ref: ModelRefNorm): Observable<number>;
138
+ /**
139
+ * Removes all items from collection
140
+ */
141
+ abstract clear(): Observable<void>;
142
+ }
143
+
144
+ declare class MemoryStore<T extends Model> extends CollectionStore<T> {
145
+ #private;
146
+ insertSlice(slice: Slice, items: readonly T[]): Observable<PartialCollection<T>>;
147
+ hasSlice(slice: Slice): Observable<boolean>;
148
+ getSlice(slice: Slice): Observable<PartialCollection<T>>;
149
+ get(ref: ModelRefNorm): Observable<T | undefined>;
150
+ indexOf(ref: ModelRefNorm): Observable<number>;
151
+ update(ref: ModelRefNorm, item: T): Observable<number>;
152
+ updateOrInsert(ref: ModelRefNorm, item: T, position?: number): Observable<number>;
153
+ del(ref: ModelRefNorm): Observable<number>;
154
+ clear(): Observable<void>;
155
+ }
156
+
157
+ declare class DataSource<T extends Model> extends DataSource$1<T | undefined> implements ConnectProtocol {
158
+ #private;
159
+ readonly provider: DataProvider<T>;
160
+ readonly store: CollectionStore<T>;
161
+ readonly query$: QuerySubject<T, ["normal", "forced"]>;
162
+ readonly isBusy$: BehaviorSubject<boolean>;
163
+ readonly total$: BehaviorSubject<number | undefined>;
164
+ readonly slice$: Observable<Slice>;
165
+ readonly reset$: Observable<void>;
166
+ readonly items$: Observable<PartialCollection<T>>;
167
+ readonly isEmpty$: Observable<boolean>;
168
+ constructor(provider: DataProvider<T>, store?: CollectionStore<T>, query$?: QuerySubject<T, ["normal", "forced"]>);
169
+ setSlice(slice: Slice): this;
170
+ setFilter(filter: Partial<Record<"normal" | "forced", Filter<T>>>): this;
171
+ updateFilter(filter: Partial<Record<"normal" | "forced", Filter<T>>>): this;
172
+ all(): this;
173
+ reload(): void;
174
+ getItem(ref: ModelRef): Observable<T | undefined>;
175
+ watchItem(ref: ModelRef): Observable<T | undefined>;
176
+ getItemPosition(ref: ModelRef): Observable<number | undefined>;
177
+ watchItemPosition(ref: ModelRef): Observable<number | undefined>;
178
+ realodItem(ref: ModelRef, insertPosition?: number): Observable<T | undefined>;
179
+ connect(collectionViewer: CollectionViewer): Observable<PartialCollection<T>>;
180
+ disconnect(collectionViewer: CollectionViewer): void;
181
+ }
182
+
183
+ declare abstract class DataProvider<T extends Model> {
184
+ /**
185
+ * `true` when the provider is making async requests
186
+ */
187
+ abstract readonly isAsync: boolean;
188
+ /**
189
+ * Metadata of model
190
+ */
191
+ abstract readonly meta: ModelMeta<T>;
192
+ /**
193
+ * Emit event when data is changed
194
+ */
195
+ get changed$(): Observable<any>;
196
+ protected _changed: Observable<any>;
197
+ /**
198
+ * Query items by the given request
199
+ */
200
+ abstract queryList(request: QueryWithSlice<T>): Observable<QueryResult<T>>;
201
+ /**
202
+ * Query exactly one item by the given request
203
+ */
204
+ abstract queryItem(ref: ModelRefNorm, request?: QueryWithSlice<T>): Observable<T | undefined>;
205
+ /**
206
+ * Query item position in the list that matching by the given request
207
+ */
208
+ abstract queryPosition(ref: ModelRefNorm, request: QueryWithSlice<T>): Observable<number | undefined>;
209
+ /**
210
+ * Froce Slice boundaries, useful in array, or obeservable providers
211
+ */
212
+ clampSlice(slice: Slice): Observable<Slice>;
213
+ filterNormalize(filter: any): FilterNormalized | undefined;
214
+ filterMerge(...filters: any[]): FilterNormalized | undefined;
215
+ sorterNormalize(sorter: any): SorterNormalized;
216
+ sorterMerge(...sorters: any[]): SorterNormalized | undefined;
217
+ grouperNormalize(grouper: any): GrouperNormalized;
218
+ grouperMerge(...groupers: any[]): GrouperNormalized | undefined;
219
+ slimerNormalize(slimer: any): SlimerNormalized;
220
+ slimerMerge(...slimers: any[]): SlimerNormalized | undefined;
221
+ /**
222
+ * @returns New data source instance
223
+ */
224
+ toDataSource(store?: CollectionStore<T>): DataSource<T>;
225
+ }
226
+
227
+ declare abstract class LocalProvider<T extends Model> extends DataProvider<T> {
228
+ #private;
229
+ readonly isAsync = false;
230
+ readonly meta: ModelMeta<T>;
231
+ abstract readonly items$: Observable<readonly T[]>;
232
+ constructor(meta: ModelMetaInput<T>);
233
+ executor(request: QueryWithSlice<T>): QueryExecutor<T>;
234
+ queryList(request: QueryWithSlice<T>): Observable<QueryResult<T>>;
235
+ queryItem(ref: ModelRefNorm, request?: QueryWithSlice<T>): Observable<T | undefined>;
236
+ queryPosition(ref: ModelRefNorm, request: QueryWithSlice<T>): Observable<number | undefined>;
237
+ clampSlice(slice: Slice): Observable<Slice>;
238
+ }
239
+
240
+ declare class ArrayProvider<T extends Model> extends LocalProvider<T> {
241
+ readonly items$: Observable<readonly T[]>;
242
+ constructor(meta: ModelMetaInput<T>, items: readonly T[]);
243
+ }
244
+
245
+ declare class ObservableProvider<T extends Model> extends LocalProvider<T> {
246
+ readonly items$: Observable<readonly T[]>;
247
+ constructor(meta: ModelMetaInput<T>, src: Observable<readonly T[]>);
248
+ }
249
+
250
+ declare abstract class QueryProperty<I, O> extends BehaviorSubject<O | undefined> {
251
+ #private;
252
+ protected readonly provider: DataProvider<any>;
253
+ constructor(provider: DataProvider<any>);
254
+ set(value?: I | O): void;
255
+ update(value?: I | O): void;
256
+ del(): void;
257
+ /**
258
+ * Merge values and emit when changed (dont change original values)
259
+ */
260
+ protected abstract merge(a?: O, b?: O): O | undefined;
261
+ protected abstract norm(a: I | O): O | undefined;
262
+ }
263
+ declare abstract class QueryPropertySet<O> extends Observable<O> {
264
+ #private;
265
+ protected readonly provider: DataProvider<any>;
266
+ constructor(provider: DataProvider<any>, ...names: string[]);
267
+ protected abstract newProperty(): QueryProperty<any, any>;
268
+ protected abstract merge(...args: any[]): any | undefined;
269
+ }
270
+ type QueryPropertySetOf<T, P, N extends string[]> = T & {
271
+ [K in N[number]]: P;
272
+ };
273
+
274
+ declare enum FilterOp {
275
+ Eq = "==",
276
+ EqStrict = "===",
277
+ EqInsesitive = "==*",
278
+ Neq = "!=",
279
+ NeqStrict = "!==",
280
+ NeqInsesitive = "!=*",
281
+ Gt = ">",
282
+ GtInsesitive = ">*",
283
+ Gte = ">=",
284
+ GteInsesitive = ">=*",
285
+ Lt = "<",
286
+ LtInsesitive = "<*",
287
+ Lte = "<=",
288
+ LteInsesitive = "<=*",
289
+ Contains = "%",
290
+ ContainsInsesitive = "%*",
291
+ StartsWith = "^",
292
+ StartsWithInsesitive = "^*",
293
+ EndsWith = "$",
294
+ EndsWithInsesitive = "$*",
295
+ Similarity = "**",
296
+ Regexp = "~",
297
+ RegexpInsesitive = "~*",
298
+ Or = "|",
299
+ And = "&",
300
+ Not = "!"
301
+ }
302
+ type FilterCustom<T = any> = {
303
+ custom: string;
304
+ matcher?: FilterCustomMatcher<T>;
305
+ };
306
+ type FilterCustomMatcher<T = any> = (item: T | null | undefined, value: any) => boolean;
307
+ type FilterOpMap = Record<string, FilterOp | FilterCustom>;
308
+ type Filter<T extends Model> = {
309
+ [key: string]: any;
310
+ };
311
+ type FilterFn<T = any> = (item: T) => boolean;
312
+ /**
313
+ * @example
314
+ * ```ts
315
+ * items.filter(filterBy({id: 42}))
316
+ * ```
317
+ */
318
+ declare function filterBy<T extends Model>(filters: Filter<T>, opmap?: FilterOpMap): FilterFn<T>;
319
+ type NormPath = {
320
+ path: string;
321
+ op: Exclude<FilterOp, FilterOp.Or | FilterOp.And | FilterOp.Not>;
322
+ value: any;
323
+ };
324
+ type NormOr = {
325
+ op: FilterOp.Or;
326
+ value: Array<NormEntry>;
327
+ };
328
+ type NormAnd = {
329
+ op: FilterOp.And;
330
+ value: Array<NormEntry>;
331
+ };
332
+ type NormNot = {
333
+ op: FilterOp.Not;
334
+ value: Array<NormEntry>;
335
+ };
336
+ type NormCustom = {
337
+ path: string;
338
+ op: FilterCustom;
339
+ value: any;
340
+ };
341
+ type NormEmpty = Record<string, never>;
342
+ type NormEntry = NormPath | NormOr | NormAnd | NormNot | NormCustom | NormEmpty;
343
+ type FilterNormalized = NormEntry;
344
+ /**
345
+ * @example
346
+ * ```ts
347
+ * filterNormalize({id: {">": 0, "<": 10}})
348
+ * {op: "&", value: [{path: "id", op: ">", value: 0}, {path: "id", op: "<", value: 10}]}
349
+ * ```
350
+ */
351
+ declare function filterNormalize<T extends Model>(filters: Filter<T> | null | undefined, opmap?: FilterOpMap): FilterNormalized | undefined;
352
+ declare function filterIsNormnalized(filters: any): filters is FilterNormalized;
353
+ declare function filterMerge(...filters: Array<FilterNormalized | null | undefined>): any | undefined;
354
+ declare class FilterProperty<T extends Model> extends QueryProperty<Filter<T>, FilterNormalized> {
355
+ protected merge(a?: FilterNormalized | undefined, b?: FilterNormalized | undefined): FilterNormalized | undefined;
356
+ protected norm(a: FilterNormalized | Filter<T>): FilterNormalized | undefined;
357
+ }
358
+ declare class FilterPropertySet<T extends Model> extends QueryPropertySet<Filter<T>> {
359
+ protected newProperty(): FilterProperty<Model>;
360
+ protected merge(...args: any[]): NormEntry | undefined;
361
+ }
362
+ declare function filterSimplify(filters: any): object | null;
363
+
364
+ type SorterFn<T = any> = (a: T, b: T) => number;
365
+ declare const enum SortDirection {
366
+ Asc = "asc",
367
+ Desc = "desc"
368
+ }
369
+ type SortDir = SortDirection.Asc | SortDirection.Desc | "asc" | "desc";
370
+ type SortDirExtra = {
371
+ dir: SortDir;
372
+ emptyFirst: boolean;
373
+ };
374
+ type Sorter<T extends Model> = Array<{
375
+ [key: string]: SortDir | SortDirExtra | NormalizedEntry | undefined;
376
+ }>;
377
+ type NormalizedEntry = {
378
+ path: string;
379
+ isAsc: boolean;
380
+ emptyFirst: boolean;
381
+ remove?: boolean;
382
+ };
383
+ type SorterNormalized = Array<NormalizedEntry>;
384
+ /**
385
+ * @example
386
+ *```ts
387
+ * items.toSorted(sortBy([{"author.name": "asc"}]))
388
+ * ```
389
+ */
390
+ declare function sortBy<T extends Model>(sorters: Sorter<T> | SorterNormalized): SorterFn<T>;
391
+ /**
392
+ * Normalize sorter definition
393
+ *
394
+ * @example
395
+ * ```ts
396
+ * normalizeSorter([{id: "asc"}]) -> [{path: "id", isAsc: true, emptyFirst: true}]
397
+ * normalizeSorter([{id: {dir: "desc", emptyFirst: false}}]) -> [{path: "id", isAsc: false, emptyFirst: false}]
398
+ * ```
399
+ */
400
+ declare function sorterNormalize<T extends Model>(sorters: Sorter<T> | SorterNormalized): SorterNormalized;
401
+ declare function sorterMerge(...sorters: (SorterNormalized | undefined | null)[]): SorterNormalized | undefined;
402
+ declare class SorterProperty<T extends Model> extends QueryProperty<Sorter<T>, SorterNormalized> {
403
+ protected norm(a: Sorter<T>): SorterNormalized | undefined;
404
+ protected merge(a?: SorterNormalized, b?: SorterNormalized): SorterNormalized | undefined;
405
+ }
406
+ declare class SorterPropertySet extends QueryPropertySet<SorterNormalized> {
407
+ of(name: string): Observable<NormalizedEntry | undefined>;
408
+ isAsc(name: string): Observable<boolean | undefined>;
409
+ isDesc(name: string): Observable<boolean | undefined>;
410
+ protected newProperty(): SorterProperty<Model>;
411
+ protected merge(...args: any[]): SorterNormalized | undefined;
412
+ }
413
+
414
+ /**
415
+ * @example
416
+ * ```ts
417
+ * {start: 0, end: 0} // empty range
418
+ * {start: 0, end: 1} // range with one item.eg sliceApply([1, 2, 3], {start:0, end:1}) -> [1]
419
+ * ```
420
+ */
421
+ interface Slice extends ListRange {
422
+ /**
423
+ * Start of slice, exact index of item in list
424
+ */
425
+ readonly start: number;
426
+ /**
427
+ * End of slice, not include end index of item in list
428
+ */
429
+ readonly end: number;
430
+ readonly pageSize?: number;
431
+ }
432
+ declare function sliceMerge(...slices: Slice[]): Slice | undefined;
433
+ /**
434
+ * Apply slice to array, and force the result length to equal with Slice length,
435
+ * so fill array with undefined if not enought elements
436
+ */
437
+ declare function sliceApply(slice: Slice, array: readonly any[]): any[];
438
+ /**
439
+ * @returns Page numbers, eg.: `[10, 11, 12, 13, ...]`
440
+ */
441
+ declare function sliceToPages(slice: Slice): number[];
442
+ declare function sliceInsert(slice: Slice, array: readonly any[], newItems: readonly any[]): any[];
443
+ declare function sliceClamp(slice: Slice, constraint: Slice): Slice;
444
+ declare function sliceEq(a: Slice, b: Slice): boolean;
445
+
446
+ type PathGetter<T = any, R = any> = (obj: T) => R[];
447
+ declare function pathGetterCompile(path: string): PathGetter;
448
+
449
+ interface Query {
450
+ filter?: DeepReadonly<FilterNormalized>;
451
+ sorter?: DeepReadonly<SorterNormalized>;
452
+ slimer?: DeepReadonly<SlimerNormalized>;
453
+ grouper?: DeepReadonly<GrouperNormalized>;
454
+ }
455
+ interface QueryWithSlice<T extends Model> extends Query {
456
+ slice: DeepReadonly<Slice>;
457
+ }
458
+ interface QueryResult<T extends Model> {
459
+ items: readonly T[];
460
+ total?: number;
461
+ groups?: any[];
462
+ }
463
+ interface QuerySubject<T extends Model, N extends string[]> extends Observable<Query> {
464
+ readonly filter: QueryPropertySetOf<FilterPropertySet<T>, FilterProperty<T>, N>;
465
+ readonly sorter: QueryPropertySetOf<SorterPropertySet, SorterProperty<T>, N>;
466
+ readonly slimer: QueryPropertySetOf<SlimerPropertySet<T>, SlimerProperty<T>, N>;
467
+ readonly grouper: QueryPropertySetOf<GrouperPropertySet<T>, GrouperProperty<T>, N>;
468
+ }
469
+ declare function querySubject<T extends Model, N extends string[]>(provider: DataProvider<T>, ...names: N): QuerySubject<T, N>;
470
+
471
+ declare const INPUT: unique symbol;
472
+ interface PartialExecutor {
473
+ [INPUT]: any;
474
+ }
475
+ interface QueryExecutors<T extends Model> {
476
+ readonly filterFn?: FilterExecutor<T>;
477
+ readonly sorterFn?: SorterExecutor<T>;
478
+ readonly grouperFn?: GrouperExecutor<T>;
479
+ readonly slicerFn?: SliceExecutor<T>;
480
+ }
481
+ interface QueryExecutor<T extends Model> extends QueryExecutors<T> {
482
+ (items: readonly T[]): QueryResult<T>;
483
+ }
484
+ declare function queryExecutor<T extends Model>(query: QueryWithSlice<T>, previous?: QueryExecutor<T>): QueryExecutor<T>;
485
+ interface FilterExecutor<T extends Model> extends PartialExecutor {
486
+ (item: T): boolean;
487
+ }
488
+ interface SorterExecutor<T extends Model> extends PartialExecutor {
489
+ (a: T, b: T): number;
490
+ }
491
+ interface GrouperExecutor<T extends Model> extends PartialExecutor {
492
+ (item: T): Primitive;
493
+ }
494
+ interface SliceExecutor<T extends Model> extends PartialExecutor {
495
+ (items: readonly T[]): T[];
496
+ }
497
+
498
+ type DataSourceProxyInput<T extends Model> = DataSourceProxy<T> | DataSource<T> | DataProvider<T>;
499
+ /**
500
+ * @example
501
+ * ```html
502
+ * <table [nuDataSource]="..." [filter]="{isActive: true}" [sorter]="[{name: 'asc'}]"></table>
503
+ * ```
504
+ *
505
+ * ```ts
506
+ * @Component({
507
+ * template: `<table [nuDataSource]="users$"></table>`
508
+ * })
509
+ * class UserTable {
510
+ * readonly userService = inject(UserService)
511
+ * readonly users$ = UserService.all()
512
+ * }
513
+ * ```
514
+ *
515
+ * ```ts
516
+ * @Component({
517
+ * selector: "table.my-table",
518
+ * template: `
519
+ * <cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
520
+ * <div *cdkVirtualFor="let item of dataSource" class="example-item">{{item}}</div>
521
+ * </cdk-virtual-scroll-viewport>
522
+ * `
523
+ * })
524
+ * class TableComponent {
525
+ * readonly dataSource = inject(DataSourceProxy)
526
+ * }
527
+ * ```
528
+ */
529
+ declare class DataSourceProxy<T extends Model> extends DataSource$1<T | undefined> implements OnDestroy, ConnectProtocol {
530
+ #private;
531
+ set value(value: DataSourceProxyInput<T>);
532
+ readonly value$: Observable<DataSource<T>>;
533
+ readonly query$: Observable<QuerySubject<T, ["normal", "forced"]>>;
534
+ readonly items$: Observable<_ngutil_data.PartialCollection<T>>;
535
+ readonly isBusy$: Observable<boolean>;
536
+ readonly isEmpty$: Observable<boolean>;
537
+ connect(collectionViewer: CollectionViewer): Observable<readonly (T | undefined)[]>;
538
+ disconnect(collectionViewer: CollectionViewer): void;
539
+ ngOnDestroy(): void;
540
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceProxy<any>, never>;
541
+ static ɵdir: i0.ɵɵDirectiveDeclaration<DataSourceProxy<any>, "[nuDataSource]", ["nuDataSource"], { "value": { "alias": "nuDataSource"; "required": true; }; }, {}, never, never, true, never>;
542
+ }
543
+ declare class DataSourceProxyFilter<T extends Model, F extends Filter<T>> {
544
+ #private;
545
+ readonly filter: i0.InputSignal<F>;
546
+ readonly filter$: Observable<F>;
547
+ constructor();
548
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceProxyFilter<any, any>, never>;
549
+ static ɵdir: i0.ɵɵDirectiveDeclaration<DataSourceProxyFilter<any, any>, "[nuDataSource][filter]", never, { "filter": { "alias": "filter"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
550
+ }
551
+ declare class DataSourceProxySorter<T extends Model, S extends Sorter<T>> {
552
+ #private;
553
+ readonly sorter: i0.InputSignal<S>;
554
+ readonly sorter$: Observable<S>;
555
+ constructor();
556
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceProxySorter<any, any>, never>;
557
+ static ɵdir: i0.ɵɵDirectiveDeclaration<DataSourceProxySorter<any, any>, "[nuDataSource][sorter]", never, { "sorter": { "alias": "sorter"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
558
+ }
559
+ declare class DataSourceProxySlimer<T extends Model, S extends Slimer<T>> {
560
+ #private;
561
+ readonly slimer: i0.InputSignal<S>;
562
+ readonly slimer$: Observable<S>;
563
+ constructor();
564
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceProxySlimer<any, any>, never>;
565
+ static ɵdir: i0.ɵɵDirectiveDeclaration<DataSourceProxySlimer<any, any>, "[nuDataSource][slimer]", never, { "slimer": { "alias": "slimer"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
566
+ }
567
+ declare class DataSourceProxyGrouper<T extends Model, G extends Grouper<T>> {
568
+ #private;
569
+ readonly grouper: i0.InputSignal<G>;
570
+ readonly grouper$: Observable<G>;
571
+ constructor();
572
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceProxyGrouper<any, any>, never>;
573
+ static ɵdir: i0.ɵɵDirectiveDeclaration<DataSourceProxyGrouper<any, any>, "[nuDataSource][grouper]", never, { "grouper": { "alias": "grouper"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
574
+ }
575
+ declare class DataSourceProxyBusy {
576
+ #private;
577
+ constructor();
578
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceProxyBusy, never>;
579
+ static ɵdir: i0.ɵɵDirectiveDeclaration<DataSourceProxyBusy, "[nuDataSource][nuBusy]", never, {}, {}, never, never, true, never>;
580
+ }
581
+
582
+ declare class DataSourceModule {
9
583
  static ɵfac: i0.ɵɵFactoryDeclaration<DataSourceModule, never>;
10
- static ɵmod: i0.ɵɵNgModuleDeclaration<DataSourceModule, never, [typeof i1.DataSourceProxy, typeof i1.DataSourceProxyBusy, typeof i1.DataSourceProxyFilter, typeof i1.DataSourceProxyGrouper, typeof i1.DataSourceProxySlimer, typeof i1.DataSourceProxySorter], [typeof i1.DataSourceProxy, typeof i1.DataSourceProxyBusy, typeof i1.DataSourceProxyFilter, typeof i1.DataSourceProxyGrouper, typeof i1.DataSourceProxySlimer, typeof i1.DataSourceProxySorter]>;
584
+ static ɵmod: i0.ɵɵNgModuleDeclaration<DataSourceModule, never, [typeof DataSourceProxy, typeof DataSourceProxyBusy, typeof DataSourceProxyFilter, typeof DataSourceProxyGrouper, typeof DataSourceProxySlimer, typeof DataSourceProxySorter], [typeof DataSourceProxy, typeof DataSourceProxyBusy, typeof DataSourceProxyFilter, typeof DataSourceProxyGrouper, typeof DataSourceProxySlimer, typeof DataSourceProxySorter]>;
11
585
  static ɵinj: i0.ɵɵInjectorDeclaration<DataSourceModule>;
12
586
  }
587
+
588
+ export { ArrayProvider, CollectionStore, DataProvider, DataSource, DataSourceModule, DataSourceProxy, DataSourceProxyBusy, DataSourceProxyFilter, DataSourceProxyGrouper, DataSourceProxySlimer, DataSourceProxySorter, FilterOp, LocalProvider, MemoryStore, ModelMeta, ModelRefByIndex, ModelRefByKey, ModelRefNorm, ObservableProvider, SortDirection, UnknownMeta, filterBy, filterIsNormnalized, filterMerge, filterNormalize, filterSimplify, groupBy, grouperMerge, pathGetterCompile, queryExecutor, querySubject, sliceApply, sliceClamp, sliceEq, sliceInsert, sliceMerge, sliceToPages, slimBy, slimerMerge, sortBy, sorterMerge, sorterNormalize };
589
+ export type { DataSourceProxyInput, Filter, FilterCustom, FilterCustomMatcher, FilterNormalized, FilterOpMap, Grouper, Model, ModelMetaInput, ModelMetaProps, ModelRef, ModelRefFilter, PartialCollection, Query, QueryExecutor, QueryResult, QuerySubject, QueryWithSlice, Slice, Slimer, SortDir, SortDirExtra, Sorter, SorterNormalized };
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@ngutil/data",
3
- "version": "0.0.102",
3
+ "version": "0.0.104",
4
4
  "peerDependencies": {
5
- "@angular/cdk": "19.2.11",
6
- "@angular/core": "19.2.8",
5
+ "@angular/cdk": "20.2.14",
6
+ "@angular/core": "20.3.13",
7
7
  "es-toolkit": "^1.35.0",
8
8
  "rxjs": "^7.8.1",
9
9
  "utility-types": "^3.11.0",
10
- "@ngutil/common": "0.0.102",
11
- "@ngutil/aria": "0.0.102"
10
+ "@ngutil/aria": "0.0.104",
11
+ "@ngutil/common": "0.0.104"
12
12
  },
13
13
  "publishConfig": {
14
14
  "access": "public",
package/model/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export { Model, ModelRef, ModelRefNorm, ModelMeta, ModelMetaProps, ModelRefFilter, ModelMetaInput, ModelRefByIndex, ModelRefByKey, UnknownMeta } from "./meta";
package/model/meta.d.ts DELETED
@@ -1,51 +0,0 @@
1
- import { TrackByFunction } from "@angular/core";
2
- import { Primitive } from "utility-types";
3
- export type Model = {
4
- [key: string]: any;
5
- };
6
- export type ModelRef = {
7
- key?: Primitive | Array<Primitive>;
8
- index?: number;
9
- };
10
- export type ModelRefFilter<T> = (item: T, index: number) => boolean;
11
- export interface ModelMetaProps<T extends Model> {
12
- readonly keys: readonly string[];
13
- readonly trackBy?: TrackByFunction<T>;
14
- }
15
- export type ModelMetaInput<T extends Model> = ModelMeta<T> | ModelMetaProps<T>;
16
- export type TrackedModel<T extends Model> = {
17
- index: number;
18
- model: T;
19
- };
20
- export declare class ModelMeta<T extends Model> implements ModelMetaProps<T> {
21
- #private;
22
- static coerce<M extends Model>(value: ModelMetaInput<M>): ModelMeta<M>;
23
- readonly keys: readonly string[];
24
- readonly trackBy: TrackByFunction<T>;
25
- constructor(props: ModelMetaProps<T>);
26
- isEqual(a: T, b: T): boolean;
27
- isEqualByTrack(a: TrackedModel<T>, b: TrackedModel<T>): boolean;
28
- isEqualByKey(a: T, b: T): boolean;
29
- normalizeRef(ref: ModelRef | ModelRefNorm): ModelRefNorm;
30
- }
31
- export declare abstract class ModelRefNorm {
32
- #private;
33
- readonly key?: readonly Primitive[];
34
- readonly index?: number;
35
- toFilter(): ModelRefFilter<any>;
36
- protected abstract _asFilter(): ModelRefFilter<any>;
37
- }
38
- export declare class ModelRefByKey extends ModelRefNorm {
39
- #private;
40
- readonly key: readonly Primitive[];
41
- constructor(key: readonly Primitive[], keys: readonly string[]);
42
- protected _asFilter(): ModelRefFilter<any>;
43
- }
44
- export declare class ModelRefByIndex extends ModelRefNorm {
45
- readonly index: number;
46
- constructor(index: number);
47
- protected _asFilter(): ModelRefFilter<any>;
48
- }
49
- export declare class UnknownMeta<T extends Model> extends ModelMeta<T> {
50
- constructor();
51
- }
@@ -1,7 +0,0 @@
1
- import { type Observable } from "rxjs";
2
- import type { Model, ModelMetaInput } from "../model";
3
- import { LocalProvider } from "./local";
4
- export declare class ArrayProvider<T extends Model> extends LocalProvider<T> {
5
- readonly items$: Observable<readonly T[]>;
6
- constructor(meta: ModelMetaInput<T>, items: readonly T[]);
7
- }