shelving 1.72.0 → 1.73.0
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/{query/Rule.d.ts → constraint/Constraint.d.ts} +2 -2
- package/constraint/Constraint.js +3 -0
- package/constraint/Constraints.d.ts +20 -0
- package/constraint/Constraints.js +35 -0
- package/{query/Filter.d.ts → constraint/FilterConstraint.d.ts} +7 -7
- package/{query/Filter.js → constraint/FilterConstraint.js} +6 -9
- package/{query/Filters.d.ts → constraint/FilterConstraints.d.ts} +3 -3
- package/{query/Filters.js → constraint/FilterConstraints.js} +6 -6
- package/{query/Query.d.ts → constraint/QueryConstraints.d.ts} +8 -8
- package/{query/Query.js → constraint/QueryConstraints.js} +17 -11
- package/{query/Sort.d.ts → constraint/SortConstraint.d.ts} +5 -5
- package/{query/Sort.js → constraint/SortConstraint.js} +3 -5
- package/{query/Sorts.d.ts → constraint/SortConstraints.d.ts} +3 -3
- package/{query/Sorts.js → constraint/SortConstraints.js} +6 -6
- package/constraint/index.d.ts +7 -0
- package/constraint/index.js +7 -0
- package/db/Changes.d.ts +8 -8
- package/db/Changes.js +12 -12
- package/db/Changes.test.d.ts +1 -0
- package/db/Changes.test.js +11 -0
- package/db/Collection.d.ts +38 -0
- package/db/Collection.js +38 -0
- package/db/Database.d.ts +22 -29
- package/db/Database.js +17 -19
- package/db/Item.d.ts +96 -0
- package/db/Item.js +79 -0
- package/db/Query.d.ts +112 -0
- package/db/Query.js +92 -0
- package/db/index.d.ts +3 -2
- package/db/index.js +3 -2
- package/feedback/ErrorFeedback.d.ts +1 -0
- package/feedback/ErrorFeedback.js +14 -1
- package/feedback/Feedback.d.ts +1 -4
- package/feedback/Feedback.js +26 -2
- package/feedback/InvalidFeedback.d.ts +1 -0
- package/feedback/InvalidFeedback.js +14 -1
- package/feedback/SuccessFeedback.d.ts +1 -0
- package/feedback/SuccessFeedback.js +14 -1
- package/feedback/WarningFeedback.d.ts +1 -0
- package/feedback/WarningFeedback.js +14 -1
- package/firestore/client/FirestoreClientProvider.d.ts +17 -16
- package/firestore/client/FirestoreClientProvider.js +29 -37
- package/firestore/lite/FirestoreLiteProvider.d.ts +15 -14
- package/firestore/lite/FirestoreLiteProvider.js +26 -34
- package/firestore/server/FirestoreServerProvider.d.ts +16 -15
- package/firestore/server/FirestoreServerProvider.js +38 -40
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +2 -2
- package/provider/BatchProvider.d.ts +6 -6
- package/provider/BatchProvider.js +19 -22
- package/provider/CacheProvider.d.ts +14 -13
- package/provider/CacheProvider.js +49 -46
- package/provider/DebugProvider.d.ts +26 -24
- package/provider/DebugProvider.js +104 -82
- package/provider/MemoryProvider.d.ts +37 -36
- package/provider/MemoryProvider.js +74 -80
- package/provider/Provider.d.ts +39 -46
- package/provider/Provider.js +1 -1
- package/provider/ThroughProvider.d.ts +28 -36
- package/provider/ThroughProvider.js +44 -67
- package/provider/ValidationProvider.d.ts +37 -35
- package/provider/ValidationProvider.js +59 -61
- package/react/index.d.ts +1 -1
- package/react/index.js +1 -1
- package/react/useItem.d.ts +32 -0
- package/react/{useDocument.js → useItem.js} +14 -14
- package/react/useQuery.d.ts +15 -10
- package/react/useQuery.js +17 -9
- package/schema/ThroughSchema.d.ts +4 -7
- package/schema/ThroughSchema.js +3 -17
- package/test/basics.d.ts +12 -12
- package/test/index.d.ts +2 -2
- package/test/index.js +1 -1
- package/test/people.d.ts +8 -8
- package/test/util.d.ts +5 -4
- package/test/util.js +1 -1
- package/util/array.d.ts +6 -4
- package/util/array.js +21 -16
- package/util/class.d.ts +11 -0
- package/util/class.js +13 -0
- package/util/data.d.ts +1 -13
- package/util/data.js +0 -7
- package/util/source.d.ts +13 -0
- package/util/source.js +23 -0
- package/db/DatabaseDocument.d.ts +0 -87
- package/db/DatabaseDocument.js +0 -91
- package/db/DatabaseQuery.d.ts +0 -120
- package/db/DatabaseQuery.js +0 -120
- package/query/Rule.js +0 -3
- package/query/Rules.d.ts +0 -20
- package/query/Rules.js +0 -35
- package/query/index.d.ts +0 -5
- package/query/index.js +0 -5
- package/react/useDocument.d.ts +0 -32
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Data } from "../util/data.js";
|
|
2
2
|
import type { Transformable } from "../util/transform.js";
|
|
3
|
-
/** Something that can be used to
|
|
4
|
-
export declare abstract class
|
|
3
|
+
/** Something that can be used to constrain a query. */
|
|
4
|
+
export declare abstract class Constraint<T extends Data> implements Transformable<Iterable<T>, Iterable<T>> {
|
|
5
5
|
abstract transform(items: Iterable<T>): Iterable<T>;
|
|
6
6
|
abstract toString(): string;
|
|
7
7
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Data } from "../util/data.js";
|
|
2
|
+
import { ImmutableArray } from "../util/array.js";
|
|
3
|
+
import { Constraint } from "./Constraint.js";
|
|
4
|
+
/** Type of Rule that is powered by several sub-constraints (e.g. `Filters` and `Sorts` and `Query` itself extend this). */
|
|
5
|
+
export declare abstract class Constraints<T extends Data, C extends Constraint<T>> extends Constraint<T> implements Iterable<C> {
|
|
6
|
+
protected readonly _constraints: ImmutableArray<C>;
|
|
7
|
+
/** Get the first constraint. */
|
|
8
|
+
get first(): C | undefined;
|
|
9
|
+
/** Get the last constraint. */
|
|
10
|
+
get last(): C | undefined;
|
|
11
|
+
/** Get the number of constraints. */
|
|
12
|
+
get size(): number;
|
|
13
|
+
constructor(...constraints: C[]);
|
|
14
|
+
/** Clone this set of constraints but add additional constraints. */
|
|
15
|
+
with(...constraints: C[]): this;
|
|
16
|
+
/** Clone this set of constraints but remove specific constraints. */
|
|
17
|
+
without(...constraints: C[]): this;
|
|
18
|
+
/** Iterate over the constraints. */
|
|
19
|
+
[Symbol.iterator](): Iterator<C, void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { withItems, withoutItems } from "../util/array.js";
|
|
2
|
+
import { Constraint } from "./Constraint.js";
|
|
3
|
+
/** Type of Rule that is powered by several sub-constraints (e.g. `Filters` and `Sorts` and `Query` itself extend this). */
|
|
4
|
+
export class Constraints extends Constraint {
|
|
5
|
+
constructor(...constraints) {
|
|
6
|
+
super();
|
|
7
|
+
this._constraints = constraints;
|
|
8
|
+
}
|
|
9
|
+
/** Get the first constraint. */
|
|
10
|
+
get first() {
|
|
11
|
+
return this._constraints[0];
|
|
12
|
+
}
|
|
13
|
+
/** Get the last constraint. */
|
|
14
|
+
get last() {
|
|
15
|
+
return this._constraints[this._constraints.length - 1];
|
|
16
|
+
}
|
|
17
|
+
/** Get the number of constraints. */
|
|
18
|
+
get size() {
|
|
19
|
+
return this._constraints.length;
|
|
20
|
+
}
|
|
21
|
+
/** Clone this set of constraints but add additional constraints. */
|
|
22
|
+
with(...constraints) {
|
|
23
|
+
const _constraints = withItems(this._constraints, constraints);
|
|
24
|
+
return _constraints !== this._constraints ? { __proto__: Object.getPrototypeOf(this), ...this, _constraints: _constraints } : this;
|
|
25
|
+
}
|
|
26
|
+
/** Clone this set of constraints but remove specific constraints. */
|
|
27
|
+
without(...constraints) {
|
|
28
|
+
const _constraints = withoutItems(this._constraints, constraints);
|
|
29
|
+
return _constraints !== this._constraints ? { __proto__: Object.getPrototypeOf(this), ...this, _constraints: _constraints } : this;
|
|
30
|
+
}
|
|
31
|
+
/** Iterate over the constraints. */
|
|
32
|
+
[Symbol.iterator]() {
|
|
33
|
+
return this._constraints.values();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -2,7 +2,7 @@ import { ArrayType, ImmutableArray } from "../util/array.js";
|
|
|
2
2
|
import { Data, Key } from "../util/data.js";
|
|
3
3
|
import { Matchable } from "../util/match.js";
|
|
4
4
|
import { NotString } from "../util/string.js";
|
|
5
|
-
import {
|
|
5
|
+
import { Constraint } from "./Constraint.js";
|
|
6
6
|
/** Possible operator references. */
|
|
7
7
|
export declare type FilterOperator = "IS" | "NOT" | "IN" | "OUT" | "CONTAINS" | "LT" | "LTE" | "GT" | "GTE";
|
|
8
8
|
/** Format that allows filters to be specified as a string, e.g. `!name` means `name is not` and `age>` means `age is more than` and `tags[]` means `tags array contains` */
|
|
@@ -16,16 +16,16 @@ export declare type FilterProps<T extends Data> = {
|
|
|
16
16
|
[K in Key<T> as `${K}<` | `${K}<=` | `${K}>` | `${K}>=`]?: T[K];
|
|
17
17
|
};
|
|
18
18
|
/** List of filters in a flexible format. */
|
|
19
|
-
export declare type FilterList<T extends Data> = FilterProps<T> |
|
|
19
|
+
export declare type FilterList<T extends Data> = FilterProps<T> | FilterConstraint<T> | Iterable<FilterList<T> & NotString>;
|
|
20
20
|
/**
|
|
21
|
-
* Filter: filters a list of
|
|
21
|
+
* Filter: filters a list of data.
|
|
22
22
|
*
|
|
23
|
-
* @param key The name of a property that might exist on
|
|
23
|
+
* @param key The name of a property that might exist on data in the collection.
|
|
24
24
|
* @param operator FilterOperator, e.g. `IS` or `CONTAINS`
|
|
25
25
|
* @param value Value the specified property should be matched against.
|
|
26
26
|
*/
|
|
27
|
-
export declare class
|
|
28
|
-
readonly key:
|
|
27
|
+
export declare class FilterConstraint<T extends Data = Data> implements Constraint<T>, Matchable<T, void> {
|
|
28
|
+
readonly key: string;
|
|
29
29
|
readonly operator: FilterOperator;
|
|
30
30
|
readonly value: unknown;
|
|
31
31
|
get filterKey(): string;
|
|
@@ -35,4 +35,4 @@ export declare class Filter<T extends Data> extends Rule<T> implements Matchable
|
|
|
35
35
|
toString(): string;
|
|
36
36
|
}
|
|
37
37
|
/** Get the separate filters generated from a list of filters. */
|
|
38
|
-
export declare function getFilters<T extends Data>(filters: FilterList<T>): Iterable<
|
|
38
|
+
export declare function getFilters<T extends Data>(filters: FilterList<T>): Iterable<FilterConstraint<T>>;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { isArray } from "../util/array.js";
|
|
2
|
-
import { getProp } from "../util/data.js";
|
|
3
2
|
import { isArrayWith, isEqual, isEqualGreater, isEqualLess, isGreater, isInArray, isLess, notEqual, notInArray } from "../util/match.js";
|
|
4
3
|
import { filterItems } from "../util/filter.js";
|
|
5
4
|
import { isIterable } from "../util/iterate.js";
|
|
6
|
-
import { Rule } from "./Rule.js";
|
|
7
5
|
/** Map `FilterOperator` to its corresponding `Match` function. */
|
|
8
6
|
const MATCHERS = {
|
|
9
7
|
IS: isEqual,
|
|
@@ -17,15 +15,14 @@ const MATCHERS = {
|
|
|
17
15
|
GTE: isEqualGreater,
|
|
18
16
|
};
|
|
19
17
|
/**
|
|
20
|
-
* Filter: filters a list of
|
|
18
|
+
* Filter: filters a list of data.
|
|
21
19
|
*
|
|
22
|
-
* @param key The name of a property that might exist on
|
|
20
|
+
* @param key The name of a property that might exist on data in the collection.
|
|
23
21
|
* @param operator FilterOperator, e.g. `IS` or `CONTAINS`
|
|
24
22
|
* @param value Value the specified property should be matched against.
|
|
25
23
|
*/
|
|
26
|
-
export class
|
|
24
|
+
export class FilterConstraint {
|
|
27
25
|
constructor(filterKey, value) {
|
|
28
|
-
super();
|
|
29
26
|
if (filterKey.startsWith("!")) {
|
|
30
27
|
this.key = filterKey.slice(1);
|
|
31
28
|
this.operator = isArray(value) ? "OUT" : "NOT";
|
|
@@ -74,7 +71,7 @@ export class Filter extends Rule {
|
|
|
74
71
|
return key;
|
|
75
72
|
}
|
|
76
73
|
match(item) {
|
|
77
|
-
return MATCHERS[this.operator](
|
|
74
|
+
return MATCHERS[this.operator](item[this.key], this.value);
|
|
78
75
|
}
|
|
79
76
|
transform(items) {
|
|
80
77
|
return filterItems(items, this);
|
|
@@ -85,7 +82,7 @@ export class Filter extends Rule {
|
|
|
85
82
|
}
|
|
86
83
|
/** Get the separate filters generated from a list of filters. */
|
|
87
84
|
export function* getFilters(filters) {
|
|
88
|
-
if (filters instanceof
|
|
85
|
+
if (filters instanceof FilterConstraint) {
|
|
89
86
|
yield filters;
|
|
90
87
|
}
|
|
91
88
|
else if (isIterable(filters)) {
|
|
@@ -94,6 +91,6 @@ export function* getFilters(filters) {
|
|
|
94
91
|
}
|
|
95
92
|
else {
|
|
96
93
|
for (const [key, value] of Object.entries(filters))
|
|
97
|
-
yield new
|
|
94
|
+
yield new FilterConstraint(key, value);
|
|
98
95
|
}
|
|
99
96
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Data } from "../util/data.js";
|
|
2
2
|
import type { Matchable } from "../util/match.js";
|
|
3
|
-
import { FilterList, FilterProps,
|
|
4
|
-
import {
|
|
3
|
+
import { FilterList, FilterProps, FilterConstraint } from "./FilterConstraint.js";
|
|
4
|
+
import { Constraints } from "./Constraints.js";
|
|
5
5
|
/**
|
|
6
6
|
* Interface to make sure an object implements all matchers.
|
|
7
7
|
* - Extends `Matchable` so this object itself can be directly be used in `filterItems()` and `filterEntries()`
|
|
@@ -13,7 +13,7 @@ export interface Filterable<T extends Data> extends Matchable<T, void> {
|
|
|
13
13
|
match(item: T): boolean;
|
|
14
14
|
}
|
|
15
15
|
/** A set of filters. */
|
|
16
|
-
export declare class
|
|
16
|
+
export declare class FilterConstraints<T extends Data = Data> extends Constraints<T, FilterConstraint<T>> implements Filterable<T> {
|
|
17
17
|
constructor(...filters: FilterList<T>[]);
|
|
18
18
|
filter(...filters: FilterList<T>[]): this;
|
|
19
19
|
match(item: T): boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { filterItems } from "../util/filter.js";
|
|
2
|
-
import { getFilters } from "./
|
|
3
|
-
import {
|
|
2
|
+
import { getFilters } from "./FilterConstraint.js";
|
|
3
|
+
import { Constraints } from "./Constraints.js";
|
|
4
4
|
/** A set of filters. */
|
|
5
|
-
export class
|
|
5
|
+
export class FilterConstraints extends Constraints {
|
|
6
6
|
constructor(...filters) {
|
|
7
7
|
super(...getFilters(filters));
|
|
8
8
|
}
|
|
@@ -11,17 +11,17 @@ export class Filters extends Rules {
|
|
|
11
11
|
return this.with(...getFilters(filters));
|
|
12
12
|
}
|
|
13
13
|
match(item) {
|
|
14
|
-
for (const rule of this.
|
|
14
|
+
for (const rule of this._constraints)
|
|
15
15
|
if (!rule.match(item))
|
|
16
16
|
return false;
|
|
17
17
|
return true;
|
|
18
18
|
}
|
|
19
19
|
// Implement `Rule`
|
|
20
20
|
transform(items) {
|
|
21
|
-
return this.
|
|
21
|
+
return this._constraints.length ? filterItems(items, this) : items;
|
|
22
22
|
}
|
|
23
23
|
// Stringify as object syntax.
|
|
24
24
|
toString() {
|
|
25
|
-
return `{${this.
|
|
25
|
+
return `{${this._constraints.map(String).join(",")}`;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Data } from "../util/data.js";
|
|
2
|
-
import { Filterable,
|
|
3
|
-
import { Sortable,
|
|
4
|
-
import {
|
|
5
|
-
import { FilterList } from "./
|
|
6
|
-
import { SortKeys, SortList } from "./
|
|
2
|
+
import { Filterable, FilterConstraints } from "./FilterConstraints.js";
|
|
3
|
+
import { Sortable, SortConstraints } from "./SortConstraints.js";
|
|
4
|
+
import { Constraint } from "./Constraint.js";
|
|
5
|
+
import { FilterList } from "./FilterConstraint.js";
|
|
6
|
+
import { SortKeys, SortList } from "./SortConstraint.js";
|
|
7
7
|
/** Set of props for a query defined as an object. */
|
|
8
8
|
export declare type QueryProps<T extends Data> = {
|
|
9
9
|
readonly filter?: FilterList<T>;
|
|
@@ -35,9 +35,9 @@ export interface Queryable<T extends Data> extends Filterable<T>, Sortable<T> {
|
|
|
35
35
|
query(query: QueryProps<T>): this;
|
|
36
36
|
}
|
|
37
37
|
/** Allows filtering, sorting, and limiting on a set of results. */
|
|
38
|
-
export declare class
|
|
39
|
-
readonly filters:
|
|
40
|
-
readonly sorts:
|
|
38
|
+
export declare class QueryConstraints<T extends Data = Data> extends Constraint<T> implements Queryable<T> {
|
|
39
|
+
readonly filters: FilterConstraints<T>;
|
|
40
|
+
readonly sorts: SortConstraints<T>;
|
|
41
41
|
readonly limit: number | null;
|
|
42
42
|
constructor({ filter, sort, limit }?: QueryProps<T>);
|
|
43
43
|
filter(...filters: FilterList<T>[]): this;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { getProp } from "../util/data.js";
|
|
2
2
|
import { assert } from "../util/assert.js";
|
|
3
3
|
import { limitItems } from "../util/iterate.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { FilterConstraints } from "./FilterConstraints.js";
|
|
5
|
+
import { SortConstraints } from "./SortConstraints.js";
|
|
6
|
+
import { Constraint } from "./Constraint.js";
|
|
7
|
+
import { FilterConstraint } from "./FilterConstraint.js";
|
|
8
8
|
// Instances to save resources for the default case (empty query).
|
|
9
|
-
const EMPTY_FILTERS = new
|
|
10
|
-
const EMPTY_SORTS = new
|
|
9
|
+
const EMPTY_FILTERS = new FilterConstraints(); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
10
|
+
const EMPTY_SORTS = new SortConstraints(); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
11
11
|
const EMPTY_PROPS = { filter: EMPTY_FILTERS, sort: EMPTY_SORTS, limit: null }; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
12
12
|
/** Allows filtering, sorting, and limiting on a set of results. */
|
|
13
|
-
export class
|
|
13
|
+
export class QueryConstraints extends Constraint {
|
|
14
14
|
constructor({ filter = EMPTY_FILTERS, sort = EMPTY_SORTS, limit = null } = EMPTY_PROPS) {
|
|
15
15
|
super();
|
|
16
|
-
this.filters = filter instanceof
|
|
17
|
-
this.sorts = sort instanceof
|
|
16
|
+
this.filters = filter instanceof FilterConstraints ? filter : new FilterConstraints(filter);
|
|
17
|
+
this.sorts = sort instanceof SortConstraints ? sort : new SortConstraints(sort);
|
|
18
18
|
this.limit = limit;
|
|
19
19
|
}
|
|
20
20
|
// Implement `Filterable`
|
|
@@ -26,6 +26,8 @@ export class Query extends Rule {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
get unfilter() {
|
|
29
|
+
if (!this.filters.size)
|
|
30
|
+
return this;
|
|
29
31
|
return {
|
|
30
32
|
__proto__: Object.getPrototypeOf(this),
|
|
31
33
|
...this,
|
|
@@ -44,6 +46,8 @@ export class Query extends Rule {
|
|
|
44
46
|
};
|
|
45
47
|
}
|
|
46
48
|
get unsort() {
|
|
49
|
+
if (!this.sorts.size)
|
|
50
|
+
return this;
|
|
47
51
|
return {
|
|
48
52
|
__proto__: Object.getPrototypeOf(this),
|
|
49
53
|
...this,
|
|
@@ -69,6 +73,8 @@ export class Query extends Rule {
|
|
|
69
73
|
};
|
|
70
74
|
}
|
|
71
75
|
max(limit) {
|
|
76
|
+
if (this.limit === limit)
|
|
77
|
+
return this;
|
|
72
78
|
return {
|
|
73
79
|
__proto__: Object.getPrototypeOf(this),
|
|
74
80
|
...this,
|
|
@@ -100,7 +106,7 @@ function* _getAfterFilters(sorts, item) {
|
|
|
100
106
|
for (const sort of sorts) {
|
|
101
107
|
const { key, direction } = sort;
|
|
102
108
|
const filterKey = direction === "ASC" ? (sort === lastSort ? `${key}>` : `${key}>=`) : sort === lastSort ? `${key}<` : `${key}<=`;
|
|
103
|
-
yield new
|
|
109
|
+
yield new FilterConstraint(filterKey, getProp(item, key));
|
|
104
110
|
}
|
|
105
111
|
}
|
|
106
112
|
function* _getBeforeFilters(sorts, item) {
|
|
@@ -109,6 +115,6 @@ function* _getBeforeFilters(sorts, item) {
|
|
|
109
115
|
for (const sort of sorts) {
|
|
110
116
|
const { key, direction } = sort;
|
|
111
117
|
const filterKey = direction === "ASC" ? (sort === lastSort ? `${key}<` : `${key}<=`) : sort === lastSort ? `${key}>` : `${key}>=`;
|
|
112
|
-
yield new
|
|
118
|
+
yield new FilterConstraint(filterKey, getProp(item, key));
|
|
113
119
|
}
|
|
114
120
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ImmutableArray } from "../util/array.js";
|
|
2
2
|
import { Data, Key } from "../util/data.js";
|
|
3
3
|
import { Rankable } from "../util/sort.js";
|
|
4
|
-
import {
|
|
4
|
+
import { Constraint } from "./Constraint.js";
|
|
5
5
|
/** Format that allows sorts to be set as a plain string, e.g. `name` sorts by name in ascending order and `!date` sorts by date in descending order. */
|
|
6
6
|
export declare type SortKey<T extends Data> = Key<T> | `${Key<T>}` | `!${Key<T>}`;
|
|
7
7
|
/** One or more sort keys. */
|
|
@@ -9,10 +9,10 @@ export declare type SortKeys<T extends Data> = SortKey<T> | ImmutableArray<SortK
|
|
|
9
9
|
/** Possible operator references. */
|
|
10
10
|
export declare type SortDirection = "ASC" | "DESC";
|
|
11
11
|
/** List of sorts in a flexible format. */
|
|
12
|
-
export declare type SortList<T extends Data> = SortKeys<T> |
|
|
12
|
+
export declare type SortList<T extends Data> = SortKeys<T> | SortConstraint<T> | Iterable<SortList<T>>;
|
|
13
13
|
/** Sort a list of values. */
|
|
14
|
-
export declare class
|
|
15
|
-
readonly key:
|
|
14
|
+
export declare class SortConstraint<T extends Data = Data> implements Constraint<T>, Rankable<T> {
|
|
15
|
+
readonly key: string;
|
|
16
16
|
readonly direction: SortDirection;
|
|
17
17
|
get sortKey(): string;
|
|
18
18
|
constructor(sortKey: SortKey<T>);
|
|
@@ -21,4 +21,4 @@ export declare class Sort<T extends Data> extends Rule<T> implements Rankable<T>
|
|
|
21
21
|
toString(): string;
|
|
22
22
|
}
|
|
23
23
|
/** Get the separate sorts generated from a list of sorts. */
|
|
24
|
-
export declare function getSorts<T extends Data>(sorts: SortList<T>): Iterable<
|
|
24
|
+
export declare function getSorts<T extends Data>(sorts: SortList<T>): Iterable<SortConstraint<T>>;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { getProp } from "../util/data.js";
|
|
2
2
|
import { rank, rankAsc, rankDesc, sortItems } from "../util/sort.js";
|
|
3
|
-
import { Rule } from "./Rule.js";
|
|
4
3
|
/** Sort a list of values. */
|
|
5
|
-
export class
|
|
4
|
+
export class SortConstraint {
|
|
6
5
|
constructor(sortKey) {
|
|
7
|
-
super();
|
|
8
6
|
if (sortKey.startsWith("!")) {
|
|
9
7
|
this.key = sortKey.slice(1);
|
|
10
8
|
this.direction = "DESC";
|
|
@@ -30,9 +28,9 @@ export class Sort extends Rule {
|
|
|
30
28
|
/** Get the separate sorts generated from a list of sorts. */
|
|
31
29
|
export function* getSorts(sorts) {
|
|
32
30
|
if (typeof sorts === "string") {
|
|
33
|
-
yield new
|
|
31
|
+
yield new SortConstraint(sorts);
|
|
34
32
|
}
|
|
35
|
-
else if (sorts instanceof
|
|
33
|
+
else if (sorts instanceof SortConstraint) {
|
|
36
34
|
yield sorts;
|
|
37
35
|
}
|
|
38
36
|
else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Data } from "../util/data.js";
|
|
2
2
|
import { Rankable } from "../util/sort.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { Constraints } from "./Constraints.js";
|
|
4
|
+
import { SortConstraint, SortKeys, SortList } from "./SortConstraint.js";
|
|
5
5
|
/**
|
|
6
6
|
* Interface to make sure an object implements all directions.
|
|
7
7
|
* - Extends `Rankable` so this object itself can be directly be used with `filterItems()` and `filterEntries()`
|
|
@@ -11,7 +11,7 @@ export interface Sortable<T extends Data> extends Rankable<T> {
|
|
|
11
11
|
sort(...keys: SortKeys<T>[]): this;
|
|
12
12
|
}
|
|
13
13
|
/** A set of sorts. */
|
|
14
|
-
export declare class
|
|
14
|
+
export declare class SortConstraints<T extends Data = Data> extends Constraints<T, SortConstraint<T>> implements Sortable<T> {
|
|
15
15
|
constructor(...sorts: SortList<T>[]);
|
|
16
16
|
sort(...sorts: SortList<T>[]): this;
|
|
17
17
|
rank(left: T, right: T): number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { sortItems } from "../util/sort.js";
|
|
2
|
-
import {
|
|
3
|
-
import { getSorts } from "./
|
|
2
|
+
import { Constraints } from "./Constraints.js";
|
|
3
|
+
import { getSorts } from "./SortConstraint.js";
|
|
4
4
|
/** A set of sorts. */
|
|
5
|
-
export class
|
|
5
|
+
export class SortConstraints extends Constraints {
|
|
6
6
|
constructor(...sorts) {
|
|
7
7
|
super(...getSorts(sorts));
|
|
8
8
|
}
|
|
@@ -11,7 +11,7 @@ export class Sorts extends Rules {
|
|
|
11
11
|
return this.with(...getSorts(sorts));
|
|
12
12
|
}
|
|
13
13
|
rank(left, right) {
|
|
14
|
-
for (const rule of this.
|
|
14
|
+
for (const rule of this._constraints) {
|
|
15
15
|
const l = rule.rank(left, right);
|
|
16
16
|
if (l !== 0)
|
|
17
17
|
return l;
|
|
@@ -20,10 +20,10 @@ export class Sorts extends Rules {
|
|
|
20
20
|
}
|
|
21
21
|
// Implement `Rule`
|
|
22
22
|
transform(items) {
|
|
23
|
-
return this.
|
|
23
|
+
return this._constraints.length ? sortItems(items, this) : items;
|
|
24
24
|
}
|
|
25
25
|
// Stringify as array syntax.
|
|
26
26
|
toString() {
|
|
27
|
-
return `[${this.
|
|
27
|
+
return `[${this._constraints.map(String).join(",")}]`;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./Constraint.js";
|
|
2
|
+
export * from "./Constraints.js";
|
|
3
|
+
export * from "./FilterConstraint.js";
|
|
4
|
+
export * from "./FilterConstraints.js";
|
|
5
|
+
export * from "./SortConstraint.js";
|
|
6
|
+
export * from "./SortConstraints.js";
|
|
7
|
+
export * from "./QueryConstraints.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./Constraint.js";
|
|
2
|
+
export * from "./Constraints.js";
|
|
3
|
+
export * from "./FilterConstraint.js";
|
|
4
|
+
export * from "./FilterConstraints.js";
|
|
5
|
+
export * from "./SortConstraint.js";
|
|
6
|
+
export * from "./SortConstraints.js";
|
|
7
|
+
export * from "./QueryConstraints.js";
|
package/db/Changes.d.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import type { Datas, Key } from "../util/data.js";
|
|
2
2
|
import { DataUpdate } from "../update/DataUpdate.js";
|
|
3
3
|
import type { Provider, AsyncProvider } from "../provider/Provider.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { Database, AsyncDatabase } from "./Database.js";
|
|
5
5
|
/**
|
|
6
6
|
* Change set of operations to run against a database in `{ "collection/id": data | DataUpdate | null }` format.
|
|
7
|
-
* - If data is an object, sets the
|
|
8
|
-
* - If data is a `DataUpdate` instance, updates the
|
|
9
|
-
* - If data is null, deletes the
|
|
7
|
+
* - If data is an object, sets the item.
|
|
8
|
+
* - If data is a `DataUpdate` instance, updates the item.
|
|
9
|
+
* - If data is null, deletes the item.
|
|
10
10
|
*/
|
|
11
11
|
export declare type Changes<DB extends Datas> = {
|
|
12
12
|
[K in Key<DB> as `${K}/${string}`]: DB[K] | DataUpdate<DB[K]> | null;
|
|
13
13
|
};
|
|
14
14
|
/** Apply a set of changes to a synchronous database. */
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function changeDatabase<T extends Datas>({ provider }: Database<T>, changes: Changes<T>): Changes<T>;
|
|
16
16
|
/** Apply a set of changes to an asynchronous database. */
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function changeAsyncDatabase<T extends Datas>({ provider }: AsyncDatabase<T>, changes: Changes<T>): Promise<Changes<T>>;
|
|
18
18
|
/** Apply a set of changes to a synchronous provider. */
|
|
19
|
-
export declare function
|
|
19
|
+
export declare function changeProvider<T extends Datas>(provider: Provider<T>, changes: Changes<T>): Changes<T>;
|
|
20
20
|
/** Apply a set of changes to an asynchronous provider. */
|
|
21
|
-
export declare function
|
|
21
|
+
export declare function changeAsyncProvider<T extends Datas>(provider: AsyncProvider<T>, changes: Changes<T>): Promise<Changes<T>>;
|
package/db/Changes.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import { splitString } from "../util/string.js";
|
|
2
2
|
import { DataUpdate } from "../update/DataUpdate.js";
|
|
3
3
|
/** Apply a set of changes to a synchronous database. */
|
|
4
|
-
export function
|
|
5
|
-
return
|
|
4
|
+
export function changeDatabase({ provider }, changes) {
|
|
5
|
+
return changeProvider(provider, changes);
|
|
6
6
|
}
|
|
7
7
|
/** Apply a set of changes to an asynchronous database. */
|
|
8
|
-
export function
|
|
9
|
-
return
|
|
8
|
+
export function changeAsyncDatabase({ provider }, changes) {
|
|
9
|
+
return changeAsyncProvider(provider, changes);
|
|
10
10
|
}
|
|
11
11
|
/** Apply a set of changes to a synchronous provider. */
|
|
12
|
-
export function
|
|
12
|
+
export function changeProvider(provider, changes) {
|
|
13
13
|
for (const [key, change] of Object.entries(changes)) {
|
|
14
14
|
const [collection, id] = splitString(key, "/", 2);
|
|
15
15
|
if (!change)
|
|
16
|
-
provider.
|
|
16
|
+
provider.deleteItem(collection, id);
|
|
17
17
|
else if (change instanceof DataUpdate)
|
|
18
|
-
provider.
|
|
18
|
+
provider.updateItem(collection, id, change);
|
|
19
19
|
else
|
|
20
|
-
provider.
|
|
20
|
+
provider.setItem(collection, id, change);
|
|
21
21
|
}
|
|
22
22
|
return changes;
|
|
23
23
|
}
|
|
24
24
|
/** Apply a set of changes to an asynchronous provider. */
|
|
25
|
-
export async function
|
|
25
|
+
export async function changeAsyncProvider(provider, changes) {
|
|
26
26
|
for (const [key, change] of Object.entries(changes)) {
|
|
27
27
|
const [collection, id] = splitString(key, "/", 2);
|
|
28
28
|
if (!change)
|
|
29
|
-
await provider.
|
|
29
|
+
await provider.deleteItem(collection, id);
|
|
30
30
|
else if (change instanceof DataUpdate)
|
|
31
|
-
await provider.
|
|
31
|
+
await provider.updateItem(collection, id, change);
|
|
32
32
|
else
|
|
33
|
-
await provider.
|
|
33
|
+
await provider.setItem(collection, id, change);
|
|
34
34
|
}
|
|
35
35
|
return changes;
|
|
36
36
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DataUpdate } from "../index.js";
|
|
2
|
+
test("Typescript", () => {
|
|
3
|
+
const operations = {
|
|
4
|
+
"collection1/a1": { a: 1, one: false },
|
|
5
|
+
"collection1/b2": null,
|
|
6
|
+
"collection1/b3": new DataUpdate({ one: true }),
|
|
7
|
+
"collection2/a1": { b: 1, one: false },
|
|
8
|
+
"collection2/b2": null,
|
|
9
|
+
"collection2/c3": new DataUpdate({ one: true }),
|
|
10
|
+
};
|
|
11
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { QueryProps } from "../constraint/QueryConstraints.js";
|
|
2
|
+
import type { Datas, Key } from "../util/data.js";
|
|
3
|
+
import type { ItemData, AsyncItem, Item } from "./Item.js";
|
|
4
|
+
import type { AsyncDatabase, Database } from "./Database.js";
|
|
5
|
+
import type { AsyncQuery, Query } from "./Query.js";
|
|
6
|
+
/** Reference to a collection in a synchronous or asynchronous provider. */
|
|
7
|
+
interface CollectionInterface<T extends Datas = Datas, K extends Key<T> = Key<T>> {
|
|
8
|
+
readonly db: Database<T> | AsyncDatabase<T>;
|
|
9
|
+
readonly collection: K;
|
|
10
|
+
/** Create a query on this item's collection. */
|
|
11
|
+
query(query?: QueryProps<ItemData<T[K]>>): Query<T, K> | AsyncQuery<T, K>;
|
|
12
|
+
/** Create a query on this item's collection. */
|
|
13
|
+
item(id: string): Item<T, K> | AsyncItem<T, K>;
|
|
14
|
+
/** Add an item to this collection. */
|
|
15
|
+
add(data: T[K]): string | Promise<string>;
|
|
16
|
+
toString(): K;
|
|
17
|
+
}
|
|
18
|
+
/** Reference to a collection in a synchronous provider. */
|
|
19
|
+
export declare class Collection<T extends Datas = Datas, K extends Key<T> = Key<T>> implements CollectionInterface<T, K> {
|
|
20
|
+
readonly db: Database<T>;
|
|
21
|
+
readonly collection: K;
|
|
22
|
+
constructor(db: Database<T>, collection: K);
|
|
23
|
+
query(query?: QueryProps<ItemData<T[K]>>): Query<T, K>;
|
|
24
|
+
item(id: string): Item<T, K>;
|
|
25
|
+
add(data: T[K]): string;
|
|
26
|
+
toString(): K;
|
|
27
|
+
}
|
|
28
|
+
/** Reference to a collection in an asynchronous provider. */
|
|
29
|
+
export declare class AsyncCollection<T extends Datas = Datas, K extends Key<T> = Key<T>> implements CollectionInterface<T, K> {
|
|
30
|
+
readonly db: AsyncDatabase<T>;
|
|
31
|
+
readonly collection: K;
|
|
32
|
+
constructor(db: AsyncDatabase<T>, collection: K);
|
|
33
|
+
query(query?: QueryProps<ItemData<T[K]>>): AsyncQuery<T, K>;
|
|
34
|
+
item(id: string): AsyncItem<T, K>;
|
|
35
|
+
add(data: T[K]): Promise<string>;
|
|
36
|
+
toString(): K;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
package/db/Collection.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Reference to a collection in a synchronous provider. */
|
|
2
|
+
export class Collection {
|
|
3
|
+
constructor(db, collection) {
|
|
4
|
+
this.db = db;
|
|
5
|
+
this.collection = collection;
|
|
6
|
+
}
|
|
7
|
+
query(query) {
|
|
8
|
+
return this.db.query(this.collection, query);
|
|
9
|
+
}
|
|
10
|
+
item(id) {
|
|
11
|
+
return this.db.item(this.collection, id);
|
|
12
|
+
}
|
|
13
|
+
add(data) {
|
|
14
|
+
return this.db.provider.addItem(this.collection, data);
|
|
15
|
+
}
|
|
16
|
+
toString() {
|
|
17
|
+
return this.collection;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Reference to a collection in an asynchronous provider. */
|
|
21
|
+
export class AsyncCollection {
|
|
22
|
+
constructor(db, collection) {
|
|
23
|
+
this.db = db;
|
|
24
|
+
this.collection = collection;
|
|
25
|
+
}
|
|
26
|
+
query(query) {
|
|
27
|
+
return this.db.query(this.collection, query);
|
|
28
|
+
}
|
|
29
|
+
item(id) {
|
|
30
|
+
return this.db.item(this.collection, id);
|
|
31
|
+
}
|
|
32
|
+
add(data) {
|
|
33
|
+
return this.db.provider.addItem(this.collection, data);
|
|
34
|
+
}
|
|
35
|
+
toString() {
|
|
36
|
+
return this.collection;
|
|
37
|
+
}
|
|
38
|
+
}
|