shelving 1.45.0 → 1.47.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/db/Database.d.ts +20 -9
- package/db/Database.js +19 -8
- package/db/Operation.js +2 -2
- package/firestore/client/FirestoreClientProvider.js +1 -0
- package/firestore/lite/FirestoreLiteProvider.js +1 -0
- package/firestore/server/FirestoreServerProvider.js +1 -0
- package/markup/render.js +2 -2
- package/markup/rules.js +2 -2
- package/package.json +1 -1
- package/query/Filter.d.ts +11 -49
- package/query/Filter.js +36 -84
- package/query/Filters.d.ts +9 -10
- package/query/Filters.js +10 -27
- package/query/Query.d.ts +12 -13
- package/query/Query.js +16 -37
- package/query/Rules.d.ts +6 -2
- package/query/Rules.js +11 -1
- package/query/Sort.d.ts +9 -17
- package/query/Sort.js +11 -23
- package/query/Sorts.d.ts +4 -4
- package/query/Sorts.js +7 -9
- package/query/helpers.d.ts +2 -3
- package/query/types.d.ts +37 -21
- package/react/useDocument.d.ts +3 -3
- package/react/useQuery.d.ts +9 -9
- package/react/useQuery.js +2 -2
- package/schema/PhoneSchema.js +1 -1
- package/test/util.js +1 -1
- package/util/date.js +2 -2
- package/util/debug.js +1 -1
- package/util/filter.d.ts +6 -3
- package/util/filter.js +11 -8
- package/util/null.d.ts +2 -2
- package/util/null.js +2 -2
- package/util/sort.d.ts +1 -1
- package/util/sort.js +7 -7
- package/util/template.js +1 -1
- package/util/units.js +14 -14
package/query/Query.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Filters } from "./Filters.js";
|
|
|
3
3
|
import { Sorts } from "./Sorts.js";
|
|
4
4
|
import { Rule } from "./Rule.js";
|
|
5
5
|
import { getQueryProp } from "./helpers.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Filter } from "./Filter.js";
|
|
7
7
|
// Instances to save resources for the default case (empty query).
|
|
8
8
|
const EMPTY_FILTERS = new Filters(); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
9
9
|
const EMPTY_SORTS = new Sorts(); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -15,46 +15,25 @@ export class Query extends Rule {
|
|
|
15
15
|
this.sorts = sorts;
|
|
16
16
|
this.limit = limit;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return
|
|
18
|
+
/** Create a new `Query` object from a set of `QueryProps` */
|
|
19
|
+
static on(filters, sorts, limit) {
|
|
20
|
+
return new Query(filters && Filters.on(filters), sorts && Sorts.on(sorts), limit);
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.
|
|
22
|
+
filter(input, value) {
|
|
23
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.filter(input, value) };
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters:
|
|
27
|
-
}
|
|
28
|
-
contains(key, value) {
|
|
29
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.contains(key, value) };
|
|
30
|
-
}
|
|
31
|
-
lt(key, value) {
|
|
32
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.lt(key, value) };
|
|
33
|
-
}
|
|
34
|
-
lte(key, value) {
|
|
35
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.lte(key, value) };
|
|
36
|
-
}
|
|
37
|
-
gt(key, value) {
|
|
38
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.gt(key, value) };
|
|
39
|
-
}
|
|
40
|
-
gte(key, value) {
|
|
41
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.gte(key, value) };
|
|
42
|
-
}
|
|
43
|
-
get unfiltered() {
|
|
44
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.unfiltered };
|
|
25
|
+
get unfilter() {
|
|
26
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, filters: EMPTY_FILTERS };
|
|
45
27
|
}
|
|
46
28
|
match(entry) {
|
|
47
29
|
return this.filters.match(entry);
|
|
48
30
|
}
|
|
49
31
|
// Implement `Sortable`
|
|
50
|
-
|
|
51
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: this.sorts.
|
|
52
|
-
}
|
|
53
|
-
desc(key) {
|
|
54
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: this.sorts.desc(key) };
|
|
32
|
+
sort(...keys) {
|
|
33
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: this.sorts.sort(...keys) };
|
|
55
34
|
}
|
|
56
|
-
get
|
|
57
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, sorts:
|
|
35
|
+
get unsort() {
|
|
36
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: EMPTY_SORTS };
|
|
58
37
|
}
|
|
59
38
|
rank(left, right) {
|
|
60
39
|
return this.sorts.rank(left, right);
|
|
@@ -69,8 +48,8 @@ export class Query extends Rule {
|
|
|
69
48
|
const lastSort = this.sorts.last;
|
|
70
49
|
assert(lastSort);
|
|
71
50
|
for (const sort of this.sorts) {
|
|
72
|
-
const
|
|
73
|
-
filters.push(new
|
|
51
|
+
const { key, direction } = sort;
|
|
52
|
+
filters.push(new Filter(key, direction === "ASC" ? (sort === lastSort ? "GT" : "GTE") : sort === lastSort ? "LT" : "LTE", getQueryProp(id, data, key)));
|
|
74
53
|
}
|
|
75
54
|
return { __proto__: Object.getPrototypeOf(this), ...this, filters: new Filters(...filters) };
|
|
76
55
|
}
|
|
@@ -79,8 +58,8 @@ export class Query extends Rule {
|
|
|
79
58
|
const lastSort = this.sorts.last;
|
|
80
59
|
assert(lastSort);
|
|
81
60
|
for (const sort of this.sorts) {
|
|
82
|
-
const
|
|
83
|
-
filters.push(new
|
|
61
|
+
const { key, direction } = sort;
|
|
62
|
+
filters.push(new Filter(key, direction === "ASC" ? (sort === lastSort ? "LT" : "LTE") : sort === lastSort ? "GT" : "GTE", getQueryProp(id, data, key)));
|
|
84
63
|
}
|
|
85
64
|
return { __proto__: Object.getPrototypeOf(this), ...this, filters: new Filters(...filters) };
|
|
86
65
|
}
|
package/query/Rules.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Data,
|
|
1
|
+
import { Data, ImmutableArray } from "../util/index.js";
|
|
2
2
|
import { Rule } from "./Rule.js";
|
|
3
3
|
/** Type of Rule that is powered by several sub-rules (e.g. `Filters` and `Sorts` and `Query` itself extend this). */
|
|
4
4
|
export declare abstract class Rules<T extends Data, R extends Rule<T>> extends Rule<T> implements Iterable<R> {
|
|
5
|
-
protected readonly _rules:
|
|
5
|
+
protected readonly _rules: ImmutableArray<R>;
|
|
6
6
|
/** Get the first rule. */
|
|
7
7
|
get first(): R | undefined;
|
|
8
8
|
/** Get the last rule. */
|
|
@@ -11,6 +11,10 @@ export declare abstract class Rules<T extends Data, R extends Rule<T>> extends R
|
|
|
11
11
|
get size(): number;
|
|
12
12
|
constructor(...rules: R[]);
|
|
13
13
|
toString(): string;
|
|
14
|
+
/** Clone this set of rules but add additional rules. */
|
|
15
|
+
with(...rules: R[]): this;
|
|
16
|
+
/** Clone this set of rules but remove specific rules. */
|
|
17
|
+
without(...rules: R[]): this;
|
|
14
18
|
/** Iterate over the rules. */
|
|
15
19
|
[Symbol.iterator](): Iterator<R, void>;
|
|
16
20
|
}
|
package/query/Rules.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toString } from "../util/index.js";
|
|
1
|
+
import { toString, withItems, withoutItems } from "../util/index.js";
|
|
2
2
|
import { Rule } from "./Rule.js";
|
|
3
3
|
/** Type of Rule that is powered by several sub-rules (e.g. `Filters` and `Sorts` and `Query` itself extend this). */
|
|
4
4
|
export class Rules extends Rule {
|
|
@@ -21,6 +21,16 @@ export class Rules extends Rule {
|
|
|
21
21
|
toString() {
|
|
22
22
|
return this._rules.map(toString).join("&");
|
|
23
23
|
}
|
|
24
|
+
/** Clone this set of rules but add additional rules. */
|
|
25
|
+
with(...rules) {
|
|
26
|
+
const _rules = withItems(this._rules, rules);
|
|
27
|
+
return _rules !== this._rules ? { __proto__: Object.getPrototypeOf(this), ...this, _rules } : this;
|
|
28
|
+
}
|
|
29
|
+
/** Clone this set of rules but remove specific rules. */
|
|
30
|
+
without(...rules) {
|
|
31
|
+
const _rules = withoutItems(this._rules, rules);
|
|
32
|
+
return _rules !== this._rules ? { __proto__: Object.getPrototypeOf(this), ...this, _rules } : this;
|
|
33
|
+
}
|
|
24
34
|
/** Iterate over the rules. */
|
|
25
35
|
[Symbol.iterator]() {
|
|
26
36
|
return this._rules.values();
|
package/query/Sort.d.ts
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
import { Data, Entry, Rankable, Entries } from "../util/index.js";
|
|
1
|
+
import { Data, Entry, Rankable, Entries, Key } from "../util/index.js";
|
|
2
2
|
import { Rule } from "./Rule.js";
|
|
3
|
-
import {
|
|
3
|
+
import { SortDirection, SortKey } from "./types.js";
|
|
4
4
|
/** Sort a list of values. */
|
|
5
|
-
export declare
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
export declare class Sort<T extends Data> extends Rule<T> implements Rankable<Entry<T>> {
|
|
6
|
+
/** Create a sort on a specified field. */
|
|
7
|
+
static on<X extends Data>(sort: SortKey<X> | Sort<X>): Sort<X>;
|
|
8
|
+
readonly key: "id" | Key<T>;
|
|
9
|
+
readonly direction: SortDirection;
|
|
10
|
+
constructor(key: "id" | Key<T>, direction: SortDirection);
|
|
11
|
+
rank([leftId, leftData]: Entry<T>, [rightId, rightData]: Entry<T>): number;
|
|
10
12
|
transform(iterable: Entries<T>): Entries<T>;
|
|
11
13
|
toString(): string;
|
|
12
14
|
}
|
|
13
|
-
/** Sort a list of values in ascending order. */
|
|
14
|
-
export declare class AscendingSort<T extends Data> extends Sort<T> {
|
|
15
|
-
readonly direction = "ASC";
|
|
16
|
-
rank([leftId, leftData]: Entry<T>, [rightId, rightData]: Entry<T>): number;
|
|
17
|
-
}
|
|
18
|
-
/** Sort a list of values in descending order. */
|
|
19
|
-
export declare class DescendingSort<T extends Data> extends Sort<T> {
|
|
20
|
-
readonly direction = "DESC";
|
|
21
|
-
rank([leftId, leftData]: Entry<T>, [rightId, rightData]: Entry<T>): number;
|
|
22
|
-
}
|
package/query/Sort.js
CHANGED
|
@@ -1,36 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { rankAsc, rank, sortItems, rankDesc } from "../util/index.js";
|
|
2
2
|
import { getQueryProp } from "./helpers.js";
|
|
3
3
|
import { Rule } from "./Rule.js";
|
|
4
4
|
/** Sort a list of values. */
|
|
5
5
|
export class Sort extends Rule {
|
|
6
|
-
constructor(key) {
|
|
6
|
+
constructor(key, direction) {
|
|
7
7
|
super();
|
|
8
8
|
this.key = key;
|
|
9
|
+
this.direction = direction;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
toString() {
|
|
14
|
-
return `${this.key}:${this.direction}`;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
/** Sort a list of values in ascending order. */
|
|
18
|
-
export class AscendingSort extends Sort {
|
|
19
|
-
constructor() {
|
|
20
|
-
super(...arguments);
|
|
21
|
-
this.direction = "ASC";
|
|
11
|
+
/** Create a sort on a specified field. */
|
|
12
|
+
static on(sort) {
|
|
13
|
+
return sort instanceof Sort ? sort : sort.startsWith("!") ? new Sort(sort.slice(1), "DESC") : new Sort(sort, "ASC");
|
|
22
14
|
}
|
|
23
15
|
rank([leftId, leftData], [rightId, rightData]) {
|
|
24
|
-
return rank(getQueryProp(leftId, leftData, this.key),
|
|
16
|
+
return rank(getQueryProp(leftId, leftData, this.key), this.direction === "ASC" ? rankAsc : rankDesc, getQueryProp(rightId, rightData, this.key));
|
|
25
17
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export class DescendingSort extends Sort {
|
|
29
|
-
constructor() {
|
|
30
|
-
super(...arguments);
|
|
31
|
-
this.direction = "DESC";
|
|
18
|
+
transform(iterable) {
|
|
19
|
+
return sortItems(iterable, this);
|
|
32
20
|
}
|
|
33
|
-
|
|
34
|
-
return
|
|
21
|
+
toString() {
|
|
22
|
+
return `${this.direction === "DESC" ? "!" : ""}${this.key}`;
|
|
35
23
|
}
|
|
36
24
|
}
|
package/query/Sorts.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Entry, Data, Entries } from "../util/index.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Sortable, SortKeys } from "./types.js";
|
|
3
3
|
import { Sort } from "./Sort.js";
|
|
4
4
|
import { Rules } from "./Rules.js";
|
|
5
5
|
/** A set of sorts. */
|
|
6
6
|
export declare class Sorts<T extends Data> extends Rules<T, Sort<T>> implements Sortable<T> {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
/** Create a new `Sorts` object from an array of `SortKey` strings. */
|
|
8
|
+
static on<X extends Data>(...keys: SortKeys<X>[]): Sorts<X>;
|
|
9
|
+
sort(...keys: SortKeys<T>[]): this;
|
|
10
10
|
rank(left: Entry<T>, right: Entry<T>): number;
|
|
11
11
|
transform(iterable: Entries<T>): Entries<T>;
|
|
12
12
|
}
|
package/query/Sorts.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { sortItems } from "../util/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Sort } from "./Sort.js";
|
|
3
3
|
import { Rules } from "./Rules.js";
|
|
4
4
|
/** A set of sorts. */
|
|
5
5
|
export class Sorts extends Rules {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return
|
|
9
|
-
}
|
|
10
|
-
desc(key) {
|
|
11
|
-
return { __proto__: Object.getPrototypeOf(this), ...this, _rules: [...this._rules, new DescendingSort(key)] };
|
|
6
|
+
/** Create a new `Sorts` object from an array of `SortKey` strings. */
|
|
7
|
+
static on(...keys) {
|
|
8
|
+
return new Sorts(...keys.flat().map(Sort.on));
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
// Implement `Sortable`
|
|
11
|
+
sort(...keys) {
|
|
12
|
+
return this.with(...keys.flat().map(Sort.on));
|
|
15
13
|
}
|
|
16
14
|
rank(left, right) {
|
|
17
15
|
for (const rule of this._rules) {
|
package/query/helpers.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { Data } from "../util/index.js";
|
|
2
|
-
import type { QueryKey } from "./types.js";
|
|
1
|
+
import { Data, Key } from "../util/index.js";
|
|
3
2
|
/**
|
|
4
3
|
* Get a named property value from some data.
|
|
5
4
|
* - For using in `Query` and `Filter` and `Sort` etc.
|
|
6
5
|
* - `"id"` is a special case and always returns the ID.
|
|
7
6
|
* - Anything else assumes the entry value is an object and looks up that named prop in the data.
|
|
8
7
|
*/
|
|
9
|
-
export declare const getQueryProp: <T extends Data, K extends
|
|
8
|
+
export declare const getQueryProp: <T extends Data, K extends "id" | Key<T>>(id: string, data: T, key: K) => K extends "id" ? string : T[K];
|
package/query/types.d.ts
CHANGED
|
@@ -1,40 +1,52 @@
|
|
|
1
1
|
import type { Data, Key, Matchable, Entry, Rankable, ImmutableArray, ArrayType } from "../util/index.js";
|
|
2
|
-
/** Type for a key in a query, either `id` for the unique ID of the document or any other string key that exists in data. */
|
|
3
|
-
export declare type QueryKey<T extends Data> = "id" | Key<T>;
|
|
4
2
|
/** Possible operator references. */
|
|
5
|
-
export declare type FilterOperator = "IS" | "NOT" | "IN" | "CONTAINS" | "LT" | "LTE" | "GT" | "GTE";
|
|
3
|
+
export declare type FilterOperator = "IS" | "NOT" | "IN" | "OUT" | "CONTAINS" | "LT" | "LTE" | "GT" | "GTE";
|
|
4
|
+
/** 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` */
|
|
5
|
+
export declare type FilterKey<T extends Data> = "id" | "!id" | "id>" | "id>=" | "id<" | "id<=" | Key<T> | `!${Key<T>}` | `${Key<T>}[]` | `${Key<T>}<` | `${Key<T>}<=` | `${Key<T>}>` | `${Key<T>}>=`;
|
|
6
|
+
/** Format that allows multiple filters to be specified as a plain object. */
|
|
7
|
+
export declare type FilterProps<T extends Data> = {
|
|
8
|
+
"id"?: string | ImmutableArray<string>;
|
|
9
|
+
"!id"?: string | ImmutableArray<string>;
|
|
10
|
+
"id>"?: string;
|
|
11
|
+
"id>="?: string;
|
|
12
|
+
"id<"?: string;
|
|
13
|
+
"id<="?: string;
|
|
14
|
+
} & {
|
|
15
|
+
[K in Key<T> as K | `!${K}`]?: T[K] | ImmutableArray<T[K]>;
|
|
16
|
+
} & {
|
|
17
|
+
[K in Key<T> as `${K}[]`]?: T[K] extends ImmutableArray ? ArrayType<T[K]> : never;
|
|
18
|
+
} & {
|
|
19
|
+
[K in Key<T> as `${K}<` | `${K}<=` | `${K}>` | `${K}>=`]?: T[K];
|
|
20
|
+
};
|
|
6
21
|
/**
|
|
7
22
|
* Interface to make sure an object implements all matchers.
|
|
8
23
|
* - Extends `Matchable` so this object itself can be directly be used in `filterItems()` and `filterEntries()`
|
|
9
24
|
*/
|
|
10
25
|
export interface Filterable<T extends Data> extends Matchable<Entry<T>, void> {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
gte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
19
|
-
/** Return a new instance of this class with no sorts specified. */
|
|
20
|
-
unfiltered: this;
|
|
26
|
+
/** Add a filter to this filterable. */
|
|
27
|
+
filter(props: FilterProps<T>): this;
|
|
28
|
+
filter(key: "id" | "!id" | "id>" | "id>=" | "id<" | "id<=", value: string): this;
|
|
29
|
+
filter(key: "id" | "!id", value: ImmutableArray<string>): this;
|
|
30
|
+
filter<K extends Key<T>>(key: K | `!${K}` | `${K}>` | `${K}>=` | `${K}<` | `${K}<=`, value: T[K]): this;
|
|
31
|
+
filter<K extends Key<T>>(key: K | `!${K}`, value: ImmutableArray<string>): this;
|
|
32
|
+
filter<K extends Key<T>>(key: `${K}[]`, value: T[K] extends ImmutableArray ? ArrayType<T[K]> : never): this;
|
|
21
33
|
/** Match an entry against the filters specified for this object. */
|
|
22
34
|
match(entry: Entry<T>): boolean;
|
|
23
35
|
}
|
|
36
|
+
/** 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. */
|
|
37
|
+
export declare type SortKey<T extends Data> = "id" | "!id" | Key<T> | `!${Key<T>}`;
|
|
38
|
+
/** One or more sort keys. */
|
|
39
|
+
export declare type SortKeys<T extends Data> = SortKey<T> | ImmutableArray<SortKey<T>>;
|
|
40
|
+
/** Possible operator references. */
|
|
41
|
+
export declare type SortDirection = "ASC" | "DESC";
|
|
24
42
|
/**
|
|
25
43
|
* Interface to make sure an object implements all directions.
|
|
26
44
|
* - Extends `Matchable` so this object itself can be directly be used in `filterItems()` and `filterEntries()`
|
|
27
45
|
*/
|
|
28
46
|
export interface Sortable<T extends Data> extends Rankable<Entry<T>> {
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
/** Return a new instance of this class with a descending order sort defined. */
|
|
32
|
-
desc(key: QueryKey<T>): this;
|
|
33
|
-
/** Return a new instance of this class with no sorts specified. */
|
|
34
|
-
unsorted: this;
|
|
47
|
+
/** Add one or more sorts to this sortable. */
|
|
48
|
+
sort(...keys: SortKeys<T>[]): this;
|
|
35
49
|
}
|
|
36
|
-
/** Possible operator references. */
|
|
37
|
-
export declare type SortDirection = "ASC" | "DESC";
|
|
38
50
|
/** Interface for an object that can have a limit set. */
|
|
39
51
|
export interface Limitable {
|
|
40
52
|
/** The maximum number of items allowed by the limit. */
|
|
@@ -55,4 +67,8 @@ export interface Queryable<T extends Data> extends Filterable<T>, Sortable<T>, L
|
|
|
55
67
|
after(id: string, data: T): this;
|
|
56
68
|
/** Return a new instance of this class with a before offset defined. */
|
|
57
69
|
before(id: string, data: T): this;
|
|
70
|
+
/** Return a new instance of this class with no filters specified. */
|
|
71
|
+
unfilter: this;
|
|
72
|
+
/** Return a new instance of this class with no sorts specified. */
|
|
73
|
+
unsort: this;
|
|
58
74
|
}
|
package/react/useDocument.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DatabaseDocument, Result, Data } from "../index.js";
|
|
1
|
+
import { DatabaseDocument, Result, Data, DocumentData } from "../index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Use the cached result of a document in a React component (or a `Promise` to indicate the result is still loading).
|
|
4
4
|
* - Requires database to use `CacheProvider` and will error if this does not exist.
|
|
@@ -33,8 +33,8 @@ export declare function useAsyncDocument<T extends Data>(ref: DatabaseDocument<T
|
|
|
33
33
|
export declare function useDocument<T extends Data>(ref: DatabaseDocument<T>, maxAge?: number | true): Result<T>;
|
|
34
34
|
export declare function useDocument<T extends Data>(ref: DatabaseDocument<T> | undefined, maxAge?: number | true): Result<T> | undefined;
|
|
35
35
|
/** Use the data of a document or `undefined` if the query has no matching results (or a promise indicating the result is loading). */
|
|
36
|
-
export declare function useAsyncDocumentData<T extends Data>(ref: DatabaseDocument<T>, maxAge?: number | true): T | PromiseLike<T
|
|
37
|
-
export declare function useAsyncDocumentData<T extends Data>(ref: DatabaseDocument<T> | undefined, maxAge?: number | true): T | PromiseLike<T
|
|
36
|
+
export declare function useAsyncDocumentData<T extends Data>(ref: DatabaseDocument<T>, maxAge?: number | true): DocumentData<T> | PromiseLike<DocumentData<T>>;
|
|
37
|
+
export declare function useAsyncDocumentData<T extends Data>(ref: DatabaseDocument<T> | undefined, maxAge?: number | true): DocumentData<T> | PromiseLike<DocumentData<T>> | undefined;
|
|
38
38
|
/** Use the data of a document or `undefined` if the query has no matching results. */
|
|
39
39
|
export declare function useDocumentData<T extends Data>(ref: DatabaseDocument<T>, maxAge?: number | true): T;
|
|
40
40
|
export declare function useDocumentData<T extends Data>(ref: DatabaseDocument<T> | undefined, maxAge?: number | true): T | undefined;
|
package/react/useQuery.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Results, DatabaseQuery, Data,
|
|
1
|
+
import { Results, DatabaseQuery, Data, DocumentResult, DocumentData } from "../index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Use the cached result of a document in a React component (or a `Promise` to indicate the result is still loading).
|
|
4
4
|
* - Requires database to use `CacheProvider` and will error if this does not exist.
|
|
@@ -34,14 +34,14 @@ export declare function useAsyncQuery<T extends Data>(ref: DatabaseQuery<T> | un
|
|
|
34
34
|
export declare function useQuery<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true): Results<T>;
|
|
35
35
|
export declare function useQuery<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true): Results<T> | undefined;
|
|
36
36
|
/** Use the first result of a query or `undefined` if the query has no matching results (or a promise indicating the result is loading). */
|
|
37
|
-
export declare function useAsyncQueryResult<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true):
|
|
38
|
-
export declare function useAsyncQueryResult<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true):
|
|
37
|
+
export declare function useAsyncQueryResult<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true): DocumentResult<T> | undefined | PromiseLike<DocumentResult<T> | undefined>;
|
|
38
|
+
export declare function useAsyncQueryResult<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true): DocumentResult<T> | undefined | PromiseLike<DocumentResult<T> | undefined>;
|
|
39
39
|
/** Use the first result of a query or `undefined` if the query has no matching results */
|
|
40
|
-
export declare function useQueryResult<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true):
|
|
41
|
-
export declare function useQueryResult<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true):
|
|
40
|
+
export declare function useQueryResult<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true): DocumentResult<T>;
|
|
41
|
+
export declare function useQueryResult<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true): DocumentResult<T> | undefined;
|
|
42
42
|
/** Use the first result of a query (or a promise indicating the result is loading). */
|
|
43
|
-
export declare function useAsyncQueryData<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true):
|
|
44
|
-
export declare function useAsyncQueryData<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true):
|
|
43
|
+
export declare function useAsyncQueryData<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true): DocumentData<T> | PromiseLike<DocumentData<T>>;
|
|
44
|
+
export declare function useAsyncQueryData<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true): DocumentData<T> | PromiseLike<DocumentData<T>> | undefined;
|
|
45
45
|
/** Use the first result of a query. */
|
|
46
|
-
export declare function useQueryData<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true):
|
|
47
|
-
export declare function useQueryData<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true):
|
|
46
|
+
export declare function useQueryData<T extends Data>(ref: DatabaseQuery<T>, maxAge?: number | true): DocumentData<T>;
|
|
47
|
+
export declare function useQueryData<T extends Data>(ref: DatabaseQuery<T> | undefined, maxAge?: number | true): DocumentData<T> | undefined;
|
package/react/useQuery.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { CacheProvider, NOERROR, findSourceProvider, NOVALUE, getMap, callAsync, getQueryData, throwAsync,
|
|
2
|
+
import { CacheProvider, NOERROR, findSourceProvider, NOVALUE, getMap, callAsync, getQueryData, throwAsync, ResultsObserver, getQueryResult, } from "../index.js";
|
|
3
3
|
import { usePureEffect } from "./usePureEffect.js";
|
|
4
4
|
import { usePureMemo } from "./usePureMemo.js";
|
|
5
5
|
import { usePureState } from "./usePureState.js";
|
|
@@ -60,7 +60,7 @@ export function useQuery(ref, maxAge) {
|
|
|
60
60
|
}
|
|
61
61
|
export function useAsyncQueryResult(ref, maxAge) {
|
|
62
62
|
const results = useAsyncQuery(ref ? ref.max(1) : undefined, maxAge);
|
|
63
|
-
return ref && results ? callAsync(
|
|
63
|
+
return ref && results ? callAsync(getQueryResult, results, ref) : undefined;
|
|
64
64
|
}
|
|
65
65
|
export function useQueryResult(ref, maxAge) {
|
|
66
66
|
return throwAsync(useAsyncQueryResult(ref, maxAge));
|
package/schema/PhoneSchema.js
CHANGED
|
@@ -21,7 +21,7 @@ export class PhoneSchema extends StringSchema {
|
|
|
21
21
|
// Strip characters that aren't 0-9 or `+` plus (including whitespace).
|
|
22
22
|
const digits = str.replace(/[^0-9+]/g, "");
|
|
23
23
|
// Allow `+` plus only if it's first character.
|
|
24
|
-
return digits.
|
|
24
|
+
return digits.slice(0, 1) + digits.slice(1).replace(/[^0-9]/g, "");
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
/** Valid phone number, e.g. `+441234567890` */
|
package/test/util.js
CHANGED
|
@@ -34,7 +34,7 @@ function popErrorStack(error, count = 1) {
|
|
|
34
34
|
const prefix = message ? `${name}: ${message}\n` : `${name}\n`;
|
|
35
35
|
if (stack.startsWith(prefix)) {
|
|
36
36
|
// In Chrome and Node the name and message of the error is the first line of the stack (so we need to skip over the first line).
|
|
37
|
-
const lines = stack.
|
|
37
|
+
const lines = stack.slice(prefix.length).split("\n");
|
|
38
38
|
lines.splice(0, count);
|
|
39
39
|
error.stack = prefix + lines.join("\n");
|
|
40
40
|
}
|
package/util/date.js
CHANGED
|
@@ -64,11 +64,11 @@ export function getDate(target = "now") {
|
|
|
64
64
|
/** Convert an unknown value to a YMD date string like "2015-09-12", or `null` if it couldn't be converted. */
|
|
65
65
|
export function toYmd(target) {
|
|
66
66
|
const date = toDate(target);
|
|
67
|
-
return date ? date.toISOString().
|
|
67
|
+
return date ? date.toISOString().slice(0, 10) : null;
|
|
68
68
|
}
|
|
69
69
|
/** Convert a `Date` instance to a YMD string like "2015-09-12", or throw `AssertionError` if it couldn't be converted. */
|
|
70
70
|
export function getYmd(target = "now") {
|
|
71
|
-
return getDate(target).toISOString().
|
|
71
|
+
return getDate(target).toISOString().slice(0, 10);
|
|
72
72
|
}
|
|
73
73
|
/** List of day-of-week strings. */
|
|
74
74
|
export const days = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
|
package/util/debug.js
CHANGED
|
@@ -16,7 +16,7 @@ export const debug = (value) => typeof value === "function"
|
|
|
16
16
|
: typeof value === "string"
|
|
17
17
|
? debugString(value)
|
|
18
18
|
: typeof value;
|
|
19
|
-
const debugString = (value) => (value.length > DEBUG_STRING_MAX ? `"${value.
|
|
19
|
+
const debugString = (value) => (value.length > DEBUG_STRING_MAX ? `"${value.slice(0, DEBUG_STRING_MAX)}…"` : `"${value}"`);
|
|
20
20
|
const DEBUG_STRING_MAX = 23;
|
|
21
21
|
const debugObject = (value) => {
|
|
22
22
|
const prototype = Object.getPrototypeOf(value);
|
package/util/filter.d.ts
CHANGED
|
@@ -13,23 +13,26 @@ export declare type Matcher<L, R> = Matchable<L, R> | ((item: L, target: R) => b
|
|
|
13
13
|
export declare function match<L>(item: L, matcher: Matcher<L, void>): boolean;
|
|
14
14
|
export declare function match<L, R>(item: L, matcher: Matcher<L, R>, target: R): boolean;
|
|
15
15
|
export declare const isEqual: <T>(item: unknown, target: T) => item is T;
|
|
16
|
-
export declare const
|
|
16
|
+
export declare const notEqual: <T, N>(item: T | N, target: T) => item is N;
|
|
17
17
|
export declare const isInArray: <T>(item: unknown, targets: ImmutableArray<T>) => item is T;
|
|
18
|
+
export declare const notInArray: <T, N>(item: T | N, targets: ImmutableArray<T>) => item is N;
|
|
18
19
|
export declare const isArrayWith: (items: unknown, target: unknown) => boolean;
|
|
19
20
|
export declare const isLess: (item: unknown, target: unknown) => boolean;
|
|
20
21
|
export declare const isEqualLess: (item: unknown, target: unknown) => boolean;
|
|
21
22
|
export declare const isGreater: (item: unknown, target: unknown) => boolean;
|
|
22
23
|
export declare const isEqualGreater: (item: unknown, target: unknown) => boolean;
|
|
23
24
|
export declare const isKeyEqual: ([key]: Entry<unknown>, target: string) => boolean;
|
|
24
|
-
export declare const
|
|
25
|
+
export declare const notKeyEqual: ([key]: Entry<unknown>, targets: string) => boolean;
|
|
25
26
|
export declare const isKeyInArray: ([key]: Entry<unknown>, targets: ImmutableArray<string>) => boolean;
|
|
27
|
+
export declare const notKeyInArray: ([key]: Entry<unknown>, targets: ImmutableArray<string>) => boolean;
|
|
26
28
|
export declare const isKeyLess: ([key]: Entry<unknown>, target: unknown) => boolean;
|
|
27
29
|
export declare const isKeyEqualLess: ([key]: Entry<unknown>, target: unknown) => boolean;
|
|
28
30
|
export declare const isKeyGreater: ([key]: Entry<unknown>, target: unknown) => boolean;
|
|
29
31
|
export declare const isKeyEqualGreater: ([key]: Entry<unknown>, target: unknown) => boolean;
|
|
30
32
|
export declare const isValueEqual: ([, value]: Entry<unknown>, target: unknown) => boolean;
|
|
31
|
-
export declare const
|
|
33
|
+
export declare const notValueEqual: ([, value]: Entry<unknown>, target: unknown) => boolean;
|
|
32
34
|
export declare const isValueInArray: ([, value]: Entry<unknown>, targets: ImmutableArray<unknown>) => boolean;
|
|
35
|
+
export declare const notValueInArray: ([, value]: Entry<unknown>, targets: ImmutableArray<unknown>) => boolean;
|
|
33
36
|
export declare const isValueLess: ([, value]: Entry<unknown>, target: unknown) => boolean;
|
|
34
37
|
export declare const isValueEqualLess: ([, value]: Entry<unknown>, target: unknown) => boolean;
|
|
35
38
|
export declare const isValueGreater: ([, value]: Entry<unknown>, target: unknown) => boolean;
|
package/util/filter.js
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { rankAsc } from "./sort.js";
|
|
2
2
|
import { transform } from "./transform.js";
|
|
3
3
|
export function match(item, matcher, target) {
|
|
4
4
|
return typeof matcher === "function" ? matcher(item, target) : matcher.match(item, target);
|
|
5
5
|
}
|
|
6
6
|
// Regular matchers.
|
|
7
7
|
export const isEqual = (item, target) => item === target;
|
|
8
|
-
export const
|
|
8
|
+
export const notEqual = (item, target) => item !== target;
|
|
9
9
|
export const isInArray = (item, targets) => targets.includes(item);
|
|
10
|
+
export const notInArray = (item, targets) => !targets.includes(item);
|
|
10
11
|
export const isArrayWith = (items, target) => items instanceof Array && items.includes(target);
|
|
11
|
-
export const isLess = (item, target) =>
|
|
12
|
-
export const isEqualLess = (item, target) =>
|
|
13
|
-
export const isGreater = (item, target) =>
|
|
14
|
-
export const isEqualGreater = (item, target) =>
|
|
12
|
+
export const isLess = (item, target) => rankAsc(item, target) < 0;
|
|
13
|
+
export const isEqualLess = (item, target) => rankAsc(item, target) <= 0;
|
|
14
|
+
export const isGreater = (item, target) => rankAsc(item, target) > 0;
|
|
15
|
+
export const isEqualGreater = (item, target) => rankAsc(item, target) >= 0;
|
|
15
16
|
// Entry key matchers.
|
|
16
17
|
export const isKeyEqual = ([key], target) => isEqual(key, target);
|
|
17
|
-
export const
|
|
18
|
+
export const notKeyEqual = ([key], targets) => notEqual(key, targets);
|
|
18
19
|
export const isKeyInArray = ([key], targets) => isInArray(key, targets);
|
|
20
|
+
export const notKeyInArray = ([key], targets) => notInArray(key, targets);
|
|
19
21
|
export const isKeyLess = ([key], target) => isLess(key, target);
|
|
20
22
|
export const isKeyEqualLess = ([key], target) => isEqualLess(key, target);
|
|
21
23
|
export const isKeyGreater = ([key], target) => isGreater(key, target);
|
|
22
24
|
export const isKeyEqualGreater = ([key], target) => isEqualGreater(key, target);
|
|
23
25
|
// Entry value matchers.
|
|
24
26
|
export const isValueEqual = ([, value], target) => isEqual(value, target);
|
|
25
|
-
export const
|
|
27
|
+
export const notValueEqual = ([, value], target) => notEqual(value, target);
|
|
26
28
|
export const isValueInArray = ([, value], targets) => isInArray(value, targets);
|
|
29
|
+
export const notValueInArray = ([, value], targets) => notInArray(value, targets);
|
|
27
30
|
export const isValueLess = ([, value], target) => isLess(value, target);
|
|
28
31
|
export const isValueEqualLess = ([, value], target) => isEqualLess(value, target);
|
|
29
32
|
export const isValueGreater = ([, value], target) => isGreater(value, target);
|
package/util/null.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Is a value null? */
|
|
2
2
|
export declare const isNull: (v: unknown) => v is null;
|
|
3
3
|
/** Is a value not null? */
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const notNull: <T>(v: T | null) => v is T;
|
|
5
5
|
/** Function that always returns null. */
|
|
6
6
|
export declare const NULL: () => null;
|
|
7
7
|
/** Nullish is `null` or `undefined` */
|
|
@@ -11,7 +11,7 @@ export declare type NotNullish<T> = Exclude<T, null | undefined>;
|
|
|
11
11
|
/** Is a value nullish? */
|
|
12
12
|
export declare const isNullish: <T>(v: Nullish<T>) => v is null | undefined;
|
|
13
13
|
/** Is a value not nullish? */
|
|
14
|
-
export declare const
|
|
14
|
+
export declare const notNullish: <T>(v: Nullish<T>) => v is T;
|
|
15
15
|
/** Get a required value (returns value or throws `RequiredError` if value is `null` or `undefined`). */
|
|
16
16
|
export declare function getRequired<T>(v: T): NotNullish<T>;
|
|
17
17
|
export declare function getRequired<T>(v: Nullish<T>): T;
|
package/util/null.js
CHANGED
|
@@ -2,13 +2,13 @@ import { RequiredError } from "../error/index.js";
|
|
|
2
2
|
/** Is a value null? */
|
|
3
3
|
export const isNull = (v) => v === null;
|
|
4
4
|
/** Is a value not null? */
|
|
5
|
-
export const
|
|
5
|
+
export const notNull = (v) => v !== null;
|
|
6
6
|
/** Function that always returns null. */
|
|
7
7
|
export const NULL = () => null;
|
|
8
8
|
/** Is a value nullish? */
|
|
9
9
|
export const isNullish = (v) => v === null || v === undefined;
|
|
10
10
|
/** Is a value not nullish? */
|
|
11
|
-
export const
|
|
11
|
+
export const notNullish = (v) => v !== null && v !== undefined;
|
|
12
12
|
export function getRequired(v) {
|
|
13
13
|
if (v === undefined || v === null)
|
|
14
14
|
throw new RequiredError("Required value is missing");
|
package/util/sort.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare function rank<T>(left: T, ranker: Ranker<T>, right: T): number;
|
|
|
28
28
|
*
|
|
29
29
|
* @returns Number below zero if `a` is higher, number above zero if `b` is higher, or `0` if they're equally sorted.
|
|
30
30
|
*/
|
|
31
|
-
export declare function
|
|
31
|
+
export declare function rankAsc(left: unknown, right: unknown): number;
|
|
32
32
|
/** Rank two values in descending order. */
|
|
33
33
|
export declare const rankDesc: (left: unknown, right: unknown) => number;
|
|
34
34
|
/** Rank the keys of two entries in ascending order. */
|