shelving 1.72.0 → 1.73.2

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 (95) hide show
  1. package/{query/Rule.d.ts → constraint/Constraint.d.ts} +2 -2
  2. package/constraint/Constraint.js +3 -0
  3. package/constraint/Constraints.d.ts +20 -0
  4. package/constraint/Constraints.js +35 -0
  5. package/{query/Filter.d.ts → constraint/FilterConstraint.d.ts} +7 -7
  6. package/{query/Filter.js → constraint/FilterConstraint.js} +6 -9
  7. package/{query/Filters.d.ts → constraint/FilterConstraints.d.ts} +3 -3
  8. package/{query/Filters.js → constraint/FilterConstraints.js} +6 -6
  9. package/{query/Query.d.ts → constraint/QueryConstraints.d.ts} +9 -18
  10. package/{query/Query.js → constraint/QueryConstraints.js} +19 -23
  11. package/{query/Sort.d.ts → constraint/SortConstraint.d.ts} +5 -5
  12. package/{query/Sort.js → constraint/SortConstraint.js} +3 -5
  13. package/{query/Sorts.d.ts → constraint/SortConstraints.d.ts} +3 -3
  14. package/{query/Sorts.js → constraint/SortConstraints.js} +6 -6
  15. package/constraint/index.d.ts +7 -0
  16. package/constraint/index.js +7 -0
  17. package/db/Changes.d.ts +10 -9
  18. package/db/Changes.js +18 -14
  19. package/db/Changes.test.d.ts +1 -0
  20. package/db/Changes.test.js +11 -0
  21. package/db/Collection.d.ts +39 -0
  22. package/db/Collection.js +38 -0
  23. package/db/Database.d.ts +23 -29
  24. package/db/Database.js +17 -19
  25. package/db/Item.d.ts +96 -0
  26. package/db/Item.js +80 -0
  27. package/db/Query.d.ts +114 -0
  28. package/db/Query.js +92 -0
  29. package/db/index.d.ts +3 -2
  30. package/db/index.js +3 -2
  31. package/feedback/ErrorFeedback.d.ts +1 -0
  32. package/feedback/ErrorFeedback.js +14 -1
  33. package/feedback/Feedback.d.ts +1 -4
  34. package/feedback/Feedback.js +26 -2
  35. package/feedback/InvalidFeedback.d.ts +1 -0
  36. package/feedback/InvalidFeedback.js +14 -1
  37. package/feedback/SuccessFeedback.d.ts +1 -0
  38. package/feedback/SuccessFeedback.js +14 -1
  39. package/feedback/WarningFeedback.d.ts +1 -0
  40. package/feedback/WarningFeedback.js +14 -1
  41. package/firestore/client/FirestoreClientProvider.d.ts +17 -16
  42. package/firestore/client/FirestoreClientProvider.js +29 -37
  43. package/firestore/lite/FirestoreLiteProvider.d.ts +15 -14
  44. package/firestore/lite/FirestoreLiteProvider.js +26 -34
  45. package/firestore/server/FirestoreServerProvider.d.ts +16 -15
  46. package/firestore/server/FirestoreServerProvider.js +38 -40
  47. package/index.d.ts +1 -1
  48. package/index.js +1 -1
  49. package/package.json +2 -2
  50. package/provider/BatchProvider.d.ts +6 -6
  51. package/provider/BatchProvider.js +19 -22
  52. package/provider/CacheProvider.d.ts +14 -13
  53. package/provider/CacheProvider.js +49 -46
  54. package/provider/DebugProvider.d.ts +26 -24
  55. package/provider/DebugProvider.js +104 -82
  56. package/provider/MemoryProvider.d.ts +37 -36
  57. package/provider/MemoryProvider.js +74 -80
  58. package/provider/Provider.d.ts +39 -46
  59. package/provider/Provider.js +1 -1
  60. package/provider/ThroughProvider.d.ts +28 -36
  61. package/provider/ThroughProvider.js +44 -67
  62. package/provider/ValidationProvider.d.ts +37 -35
  63. package/provider/ValidationProvider.js +59 -61
  64. package/react/index.d.ts +1 -1
  65. package/react/index.js +1 -1
  66. package/react/useItem.d.ts +32 -0
  67. package/react/{useDocument.js → useItem.js} +14 -14
  68. package/react/useQuery.d.ts +15 -10
  69. package/react/useQuery.js +17 -9
  70. package/schema/ThroughSchema.d.ts +4 -7
  71. package/schema/ThroughSchema.js +3 -17
  72. package/test/basics.d.ts +12 -12
  73. package/test/index.d.ts +2 -2
  74. package/test/index.js +1 -1
  75. package/test/people.d.ts +8 -8
  76. package/test/util.d.ts +5 -4
  77. package/test/util.js +1 -1
  78. package/util/array.d.ts +6 -4
  79. package/util/array.js +21 -16
  80. package/util/class.d.ts +11 -0
  81. package/util/class.js +13 -0
  82. package/util/data.d.ts +1 -13
  83. package/util/data.js +0 -7
  84. package/util/source.d.ts +13 -0
  85. package/util/source.js +23 -0
  86. package/db/DatabaseDocument.d.ts +0 -87
  87. package/db/DatabaseDocument.js +0 -91
  88. package/db/DatabaseQuery.d.ts +0 -120
  89. package/db/DatabaseQuery.js +0 -120
  90. package/query/Rule.js +0 -3
  91. package/query/Rules.d.ts +0 -20
  92. package/query/Rules.js +0 -35
  93. package/query/index.d.ts +0 -5
  94. package/query/index.js +0 -5
  95. 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 query against a result set or an array of entries. */
4
- export declare abstract class Rule<T extends Data> implements Transformable<Iterable<T>, Iterable<T>> {
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,3 @@
1
+ /** Something that can be used to constrain a query. */
2
+ export class Constraint {
3
+ }
@@ -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 { Rule } from "./Rule.js";
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> | Filter<T> | Iterable<FilterList<T> & NotString>;
19
+ export declare type FilterList<T extends Data> = FilterProps<T> | FilterConstraint<T> | Iterable<FilterList<T> & NotString>;
20
20
  /**
21
- * Filter: filters a list of documents.
21
+ * Filter: filters a list of data.
22
22
  *
23
- * @param key The name of a property that might exist on documents in the collection.
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 Filter<T extends Data> extends Rule<T> implements Matchable<T, void> {
28
- readonly key: Key<T>;
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<Filter<T>>;
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 documents.
18
+ * Filter: filters a list of data.
21
19
  *
22
- * @param key The name of a property that might exist on documents in the collection.
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 Filter extends Rule {
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](getProp(item, this.key), this.value);
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 Filter) {
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 Filter(key, value);
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, Filter } from "./Filter.js";
4
- import { Rules } from "./Rules.js";
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 Filters<T extends Data> extends Rules<T, Filter<T>> implements Filterable<T> {
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 "./Filter.js";
3
- import { Rules } from "./Rules.js";
2
+ import { getFilters } from "./FilterConstraint.js";
3
+ import { Constraints } from "./Constraints.js";
4
4
  /** A set of filters. */
5
- export class Filters extends Rules {
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._rules)
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._rules.length ? filterItems(items, this) : items;
21
+ return this._constraints.length ? filterItems(items, this) : items;
22
22
  }
23
23
  // Stringify as object syntax.
24
24
  toString() {
25
- return `{${this._rules.map(String).join(",")}`;
25
+ return `{${this._constraints.map(String).join(",")}`;
26
26
  }
27
27
  }
@@ -1,15 +1,9 @@
1
1
  import { Data } from "../util/data.js";
2
- import { Filterable, Filters } from "./Filters.js";
3
- import { Sortable, Sorts } from "./Sorts.js";
4
- import { Rule } from "./Rule.js";
5
- import { FilterList } from "./Filter.js";
6
- import { SortKeys, SortList } from "./Sort.js";
7
- /** Set of props for a query defined as an object. */
8
- export declare type QueryProps<T extends Data> = {
9
- readonly filter?: FilterList<T>;
10
- readonly sort?: SortList<T>;
11
- readonly limit?: number | null;
12
- };
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";
13
7
  /** Interface that combines Filterable, Sortable, Sliceable. */
14
8
  export interface Queryable<T extends Data> extends Filterable<T>, Sortable<T> {
15
9
  /**
@@ -31,15 +25,13 @@ export interface Queryable<T extends Data> extends Filterable<T>, Sortable<T> {
31
25
  readonly limit: number | null;
32
26
  /** Return a new instance of this class with a limit set. */
33
27
  max(max: number | null): this;
34
- /** Return a new instance of this class with new filters, sorts, limits set. */
35
- query(query: QueryProps<T>): this;
36
28
  }
37
29
  /** Allows filtering, sorting, and limiting on a set of results. */
38
- export declare class Query<T extends Data> extends Rule<T> implements Queryable<T> {
39
- readonly filters: Filters<T>;
40
- readonly sorts: Sorts<T>;
30
+ export declare class QueryConstraints<T extends Data = Data> extends Constraint<T> implements Queryable<T> {
31
+ readonly filters: FilterConstraints<T>;
32
+ readonly sorts: SortConstraints<T>;
41
33
  readonly limit: number | null;
42
- constructor({ filter, sort, limit }?: QueryProps<T>);
34
+ constructor(filters?: FilterList<T>, sorts?: SortList<T>, limit?: number | null);
43
35
  filter(...filters: FilterList<T>[]): this;
44
36
  get unfilter(): this;
45
37
  match(item: T): boolean;
@@ -49,7 +41,6 @@ export declare class Query<T extends Data> extends Rule<T> implements Queryable<
49
41
  after(item: T): this;
50
42
  before(item: T): this;
51
43
  max(limit: number | null): this;
52
- query({ sort, limit, filter }: QueryProps<T>): this;
53
44
  transform(items: Iterable<T>): Iterable<T>;
54
45
  toString(): string;
55
46
  }
@@ -1,20 +1,19 @@
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 { Filters } from "./Filters.js";
5
- import { Sorts } from "./Sorts.js";
6
- import { Rule } from "./Rule.js";
7
- import { Filter } from "./Filter.js";
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 Filters(); // eslint-disable-line @typescript-eslint/no-explicit-any
10
- const EMPTY_SORTS = new Sorts(); // eslint-disable-line @typescript-eslint/no-explicit-any
11
- const EMPTY_PROPS = { filter: EMPTY_FILTERS, sort: EMPTY_SORTS, limit: null }; // eslint-disable-line @typescript-eslint/no-explicit-any
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
12
11
  /** Allows filtering, sorting, and limiting on a set of results. */
13
- export class Query extends Rule {
14
- constructor({ filter = EMPTY_FILTERS, sort = EMPTY_SORTS, limit = null } = EMPTY_PROPS) {
12
+ export class QueryConstraints extends Constraint {
13
+ constructor(filters = EMPTY_FILTERS, sorts = EMPTY_SORTS, limit = null) {
15
14
  super();
16
- this.filters = filter instanceof Filters ? filter : new Filters(filter);
17
- this.sorts = sort instanceof Sorts ? sort : new Sorts(sort);
15
+ this.filters = filters instanceof FilterConstraints ? filters : new FilterConstraints(filters);
16
+ this.sorts = sorts instanceof SortConstraints ? sorts : new SortConstraints(sorts);
18
17
  this.limit = limit;
19
18
  }
20
19
  // Implement `Filterable`
@@ -26,6 +25,8 @@ export class Query extends Rule {
26
25
  };
27
26
  }
28
27
  get unfilter() {
28
+ if (!this.filters.size)
29
+ return this;
29
30
  return {
30
31
  __proto__: Object.getPrototypeOf(this),
31
32
  ...this,
@@ -44,6 +45,8 @@ export class Query extends Rule {
44
45
  };
45
46
  }
46
47
  get unsort() {
48
+ if (!this.sorts.size)
49
+ return this;
47
50
  return {
48
51
  __proto__: Object.getPrototypeOf(this),
49
52
  ...this,
@@ -69,21 +72,14 @@ export class Query extends Rule {
69
72
  };
70
73
  }
71
74
  max(limit) {
75
+ if (this.limit === limit)
76
+ return this;
72
77
  return {
73
78
  __proto__: Object.getPrototypeOf(this),
74
79
  ...this,
75
80
  limit,
76
81
  };
77
82
  }
78
- query({ sort, limit, filter }) {
79
- return {
80
- __proto__: Object.getPrototypeOf(this),
81
- ...this,
82
- filters: filter ? this.filters.filter(filter) : this.filters,
83
- sorts: sort ? this.sorts.sort(sort) : this.sorts,
84
- limit: limit !== undefined ? limit : this.limit,
85
- };
86
- }
87
83
  // Implement `Rule`
88
84
  transform(items) {
89
85
  const sorted = this.sorts.transform(this.filters.transform(items));
@@ -91,7 +87,7 @@ export class Query extends Rule {
91
87
  }
92
88
  // Implement toString()
93
89
  toString() {
94
- return `{"filter":${this.filters.toString()}},"sort":${this.sorts.toString()},"limit":${this.limit}}`;
90
+ return `{"filters":${this.filters.toString()}},"sorts":${this.sorts.toString()},"limit":${this.limit}}`;
95
91
  }
96
92
  }
97
93
  function* _getAfterFilters(sorts, item) {
@@ -100,7 +96,7 @@ function* _getAfterFilters(sorts, item) {
100
96
  for (const sort of sorts) {
101
97
  const { key, direction } = sort;
102
98
  const filterKey = direction === "ASC" ? (sort === lastSort ? `${key}>` : `${key}>=`) : sort === lastSort ? `${key}<` : `${key}<=`;
103
- yield new Filter(filterKey, getProp(item, key));
99
+ yield new FilterConstraint(filterKey, getProp(item, key));
104
100
  }
105
101
  }
106
102
  function* _getBeforeFilters(sorts, item) {
@@ -109,6 +105,6 @@ function* _getBeforeFilters(sorts, item) {
109
105
  for (const sort of sorts) {
110
106
  const { key, direction } = sort;
111
107
  const filterKey = direction === "ASC" ? (sort === lastSort ? `${key}<` : `${key}<=`) : sort === lastSort ? `${key}>` : `${key}>=`;
112
- yield new Filter(filterKey, getProp(item, key));
108
+ yield new FilterConstraint(filterKey, getProp(item, key));
113
109
  }
114
110
  }
@@ -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 { Rule } from "./Rule.js";
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> | Sort<T> | Iterable<SortList<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 Sort<T extends Data> extends Rule<T> implements Rankable<T> {
15
- readonly key: Key<T>;
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<Sort<T>>;
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 Sort extends Rule {
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 Sort(sorts);
31
+ yield new SortConstraint(sorts);
34
32
  }
35
- else if (sorts instanceof Sort) {
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 { Rules } from "./Rules.js";
4
- import { Sort, SortKeys, SortList } from "./Sort.js";
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 Sorts<T extends Data> extends Rules<T, Sort<T>> implements Sortable<T> {
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 { Rules } from "./Rules.js";
3
- import { getSorts } from "./Sort.js";
2
+ import { Constraints } from "./Constraints.js";
3
+ import { getSorts } from "./SortConstraint.js";
4
4
  /** A set of sorts. */
5
- export class Sorts extends Rules {
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._rules) {
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._rules.length ? sortItems(items, this) : items;
23
+ return this._constraints.length ? sortItems(items, this) : items;
24
24
  }
25
25
  // Stringify as array syntax.
26
26
  toString() {
27
- return `[${this._rules.map(String).join(",")}]`;
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,22 @@
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 { SynchronousDatabase, AsynchronousDatabase } from "./Database.js";
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 document.
8
- * - If data is a `DataUpdate` instance, updates the document.
9
- * - If data is null, deletes the document.
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
+ * - If data is undefined, skip the item.
10
11
  */
11
12
  export declare type Changes<DB extends Datas> = {
12
- [K in Key<DB> as `${K}/${string}`]: DB[K] | DataUpdate<DB[K]> | null;
13
+ [K in Key<DB> as `${K}/${string}`]: DB[K] | DataUpdate<DB[K]> | null | undefined;
13
14
  };
14
15
  /** Apply a set of changes to a synchronous database. */
15
- export declare function changeSynchronousDatabase<T extends Datas>({ provider }: SynchronousDatabase<T>, changes: Changes<T>): Changes<T>;
16
+ export declare function changeDatabase<T extends Datas>({ provider }: Database<T>, changes: Changes<T>): Changes<T>;
16
17
  /** Apply a set of changes to an asynchronous database. */
17
- export declare function changeAsynchronousDatabase<T extends Datas>({ provider }: AsynchronousDatabase<T>, changes: Changes<T>): Promise<Changes<T>>;
18
+ export declare function changeAsyncDatabase<T extends Datas>({ provider }: AsyncDatabase<T>, changes: Changes<T>): Promise<Changes<T>>;
18
19
  /** Apply a set of changes to a synchronous provider. */
19
- export declare function changeSynchronousProvider<T extends Datas>(provider: Provider<T>, changes: Changes<T>): Changes<T>;
20
+ export declare function changeProvider<T extends Datas>(provider: Provider<T>, changes: Changes<T>): Changes<T>;
20
21
  /** Apply a set of changes to an asynchronous provider. */
21
- export declare function changeAsynchronousProvider<T extends Datas>(provider: AsyncProvider<T>, changes: Changes<T>): Promise<Changes<T>>;
22
+ export declare function changeAsyncProvider<T extends Datas>(provider: AsyncProvider<T>, changes: Changes<T>): Promise<Changes<T>>;
package/db/Changes.js CHANGED
@@ -1,36 +1,40 @@
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 changeSynchronousDatabase({ provider }, changes) {
5
- return changeSynchronousProvider(provider, changes);
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 changeAsynchronousDatabase({ provider }, changes) {
9
- return changeAsynchronousProvider(provider, changes);
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 changeSynchronousProvider(provider, changes) {
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
- if (!change)
16
- provider.deleteDocument({ collection, id });
15
+ if (change === undefined)
16
+ continue;
17
+ else if (change === null)
18
+ provider.deleteItem(collection, id);
17
19
  else if (change instanceof DataUpdate)
18
- provider.updateDocument({ collection, id }, change);
20
+ provider.updateItem(collection, id, change);
19
21
  else
20
- provider.setDocument({ collection, id }, change);
22
+ provider.setItem(collection, id, change);
21
23
  }
22
24
  return changes;
23
25
  }
24
26
  /** Apply a set of changes to an asynchronous provider. */
25
- export async function changeAsynchronousProvider(provider, changes) {
27
+ export async function changeAsyncProvider(provider, changes) {
26
28
  for (const [key, change] of Object.entries(changes)) {
27
29
  const [collection, id] = splitString(key, "/", 2);
28
- if (!change)
29
- await provider.deleteDocument({ collection, id });
30
+ if (change === undefined)
31
+ continue;
32
+ else if (change === null)
33
+ await provider.deleteItem(collection, id);
30
34
  else if (change instanceof DataUpdate)
31
- await provider.updateDocument({ collection, id }, change);
35
+ await provider.updateItem(collection, id, change);
32
36
  else
33
- await provider.setDocument({ collection, id }, change);
37
+ await provider.setItem(collection, id, change);
34
38
  }
35
39
  return changes;
36
40
  }
@@ -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,39 @@
1
+ import type { Datas, Key } from "../util/data.js";
2
+ import type { FilterList } from "../constraint/FilterConstraint.js";
3
+ import type { SortList } from "../constraint/SortConstraint.js";
4
+ import type { ItemData, AsyncItem, Item } from "./Item.js";
5
+ import type { AsyncDatabase, Database } from "./Database.js";
6
+ import type { AsyncQuery, Query } from "./Query.js";
7
+ /** Reference to a collection in a synchronous or asynchronous provider. */
8
+ interface CollectionInterface<T extends Datas = Datas, K extends Key<T> = Key<T>> {
9
+ readonly db: Database<T> | AsyncDatabase<T>;
10
+ readonly collection: K;
11
+ /** Create a query on this item's collection. */
12
+ query(filters?: FilterList<ItemData<T[K]>>, sorts?: SortList<ItemData<T[K]>>, limit?: number | null): Query<T, K> | AsyncQuery<T, K>;
13
+ /** Create a query on this item's collection. */
14
+ item(id: string): Item<T, K> | AsyncItem<T, K>;
15
+ /** Add an item to this collection. */
16
+ add(data: T[K]): string | Promise<string>;
17
+ toString(): K;
18
+ }
19
+ /** Reference to a collection in a synchronous provider. */
20
+ export declare class Collection<T extends Datas = Datas, K extends Key<T> = Key<T>> implements CollectionInterface<T, K> {
21
+ readonly db: Database<T>;
22
+ readonly collection: K;
23
+ constructor(db: Database<T>, collection: K);
24
+ query(filters?: FilterList<ItemData<T[K]>>, sorts?: SortList<ItemData<T[K]>>, limit?: number | null): Query<T, K>;
25
+ item(id: string): Item<T, K>;
26
+ add(data: T[K]): string;
27
+ toString(): K;
28
+ }
29
+ /** Reference to a collection in an asynchronous provider. */
30
+ export declare class AsyncCollection<T extends Datas = Datas, K extends Key<T> = Key<T>> implements CollectionInterface<T, K> {
31
+ readonly db: AsyncDatabase<T>;
32
+ readonly collection: K;
33
+ constructor(db: AsyncDatabase<T>, collection: K);
34
+ query(filters?: FilterList<ItemData<T[K]>>, sorts?: SortList<ItemData<T[K]>>, limit?: number | null): AsyncQuery<T, K>;
35
+ item(id: string): AsyncItem<T, K>;
36
+ add(data: T[K]): Promise<string>;
37
+ toString(): K;
38
+ }
39
+ export {};