shelving 1.30.3 → 1.32.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 +10 -3
- package/db/Database.js +13 -4
- package/firestore/client/FirestoreClientProvider.js +5 -6
- package/firestore/lite/FirestoreLiteProvider.js +4 -4
- package/firestore/server/FirestoreServerProvider.js +5 -5
- package/markup/helpers.js +1 -7
- package/package.json +1 -1
- package/provider/BatchProvider.js +1 -1
- package/provider/MemoryProvider.js +8 -8
- package/provider/ValidationProvider.js +2 -2
- package/query/Filter.d.ts +24 -10
- package/query/Filter.js +64 -11
- package/query/Filters.d.ts +1 -1
- package/query/Filters.js +1 -1
- package/query/Query.d.ts +1 -1
- package/query/Sort.d.ts +7 -6
- package/query/Sort.js +15 -5
- package/query/types.d.ts +1 -1
- package/react/index.d.ts +0 -2
- package/react/index.js +0 -2
- package/react/useDocument.d.ts +6 -0
- package/react/useDocument.js +8 -1
- package/react/useQuery.d.ts +13 -1
- package/react/useQuery.js +15 -1
- package/react/useSubscribe.js +1 -1
- package/schema/NumberSchema.js +2 -2
- package/schema/ThroughSchema.d.ts +1 -1
- package/schema/ThroughSchema.js +1 -1
- package/stream/DataState.js +4 -4
- package/stream/State.js +1 -1
- package/update/ArrayUpdate.d.ts +17 -0
- package/update/ArrayUpdate.js +30 -0
- package/update/DataUpdate.d.ts +4 -7
- package/update/DataUpdate.js +7 -10
- package/update/Increment.d.ts +4 -0
- package/update/Increment.js +4 -0
- package/update/ObjectUpdate.d.ts +25 -0
- package/update/{EntriesUpdate.js → ObjectUpdate.js} +15 -15
- package/update/hydrations.d.ts +4 -4
- package/update/hydrations.js +4 -4
- package/update/index.d.ts +2 -2
- package/update/index.js +2 -2
- package/util/assert.d.ts +4 -0
- package/util/assert.js +10 -0
- package/util/async.js +1 -1
- package/util/color.d.ts +29 -0
- package/util/color.js +70 -0
- package/util/data.d.ts +2 -2
- package/util/filter.d.ts +1 -1
- package/util/filter.js +1 -1
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/util/iterate.d.ts +7 -6
- package/util/iterate.js +23 -12
- package/util/number.d.ts +18 -8
- package/util/number.js +26 -27
- package/util/random.d.ts +8 -11
- package/util/random.js +12 -12
- package/util/string.d.ts +2 -0
- package/util/string.js +11 -4
- package/util/transform.d.ts +2 -2
- package/util/transform.js +2 -2
- package/util/undefined.d.ts +5 -0
- package/util/undefined.js +6 -0
- package/util/validate.d.ts +6 -1
- package/util/validate.js +7 -0
- package/react/useDocumentData.d.ts +0 -36
- package/react/useDocumentData.js +0 -9
- package/react/useQueryFirst.d.ts +0 -36
- package/react/useQueryFirst.js +0 -9
- package/update/EntriesUpdate.d.ts +0 -29
- package/update/ItemsUpdate.d.ts +0 -21
- package/update/ItemsUpdate.js +0 -34
package/db/Database.d.ts
CHANGED
|
@@ -55,12 +55,19 @@ export declare class DataQuery<T extends Data = Data> extends Query<T> implement
|
|
|
55
55
|
*/
|
|
56
56
|
get count(): number | PromiseLike<number>;
|
|
57
57
|
/**
|
|
58
|
-
* Get an entry for the first document
|
|
58
|
+
* Get an entry for the first document matched by this query or `undefined` if this query has no results.
|
|
59
59
|
*
|
|
60
60
|
* @return Entry in `[id, data]` format for the first document.
|
|
61
61
|
* @throws RequiredError if there were no results for this query.
|
|
62
62
|
*/
|
|
63
|
-
get
|
|
63
|
+
get result(): Entry<T> | undefined | PromiseLike<Entry<T> | undefined>;
|
|
64
|
+
/**
|
|
65
|
+
* Get an entry for the first document matched by this query.
|
|
66
|
+
*
|
|
67
|
+
* @return Entry in `[id, data]` format for the first document.
|
|
68
|
+
* @throws RequiredError if there were no results for this query.
|
|
69
|
+
*/
|
|
70
|
+
get data(): Entry<T> | PromiseLike<Entry<T>>;
|
|
64
71
|
/**
|
|
65
72
|
* Subscribe to all matching documents.
|
|
66
73
|
* - `next()` is called once with the initial results, and again any time the results change.
|
|
@@ -103,7 +110,7 @@ export declare class DataQuery<T extends Data = Data> extends Query<T> implement
|
|
|
103
110
|
toString(): string;
|
|
104
111
|
}
|
|
105
112
|
/** Get the data for a document from a result for that document. */
|
|
106
|
-
export declare function
|
|
113
|
+
export declare function getQueryData<T extends Data>(results: Results<T>, ref: DataQuery<T>): Entry<T>;
|
|
107
114
|
/** A document reference within a specific database. */
|
|
108
115
|
export declare class DataDocument<T extends Data = Data> implements Observable<Result<T>>, Validatable<T> {
|
|
109
116
|
readonly provider: Provider;
|
package/db/Database.js
CHANGED
|
@@ -80,13 +80,22 @@ export class DataQuery extends Query {
|
|
|
80
80
|
return callAsync(countItems, this.results);
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
|
-
* Get an entry for the first document
|
|
83
|
+
* Get an entry for the first document matched by this query or `undefined` if this query has no results.
|
|
84
84
|
*
|
|
85
85
|
* @return Entry in `[id, data]` format for the first document.
|
|
86
86
|
* @throws RequiredError if there were no results for this query.
|
|
87
87
|
*/
|
|
88
|
-
get
|
|
89
|
-
return callAsync(
|
|
88
|
+
get result() {
|
|
89
|
+
return callAsync(getFirstItem, this.max(1).results);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get an entry for the first document matched by this query.
|
|
93
|
+
*
|
|
94
|
+
* @return Entry in `[id, data]` format for the first document.
|
|
95
|
+
* @throws RequiredError if there were no results for this query.
|
|
96
|
+
*/
|
|
97
|
+
get data() {
|
|
98
|
+
return callAsync(getQueryData, this.max(1).results, this);
|
|
90
99
|
}
|
|
91
100
|
/**
|
|
92
101
|
* Subscribe to all matching documents.
|
|
@@ -161,7 +170,7 @@ export class DataQuery extends Query {
|
|
|
161
170
|
}
|
|
162
171
|
}
|
|
163
172
|
/** Get the data for a document from a result for that document. */
|
|
164
|
-
export function
|
|
173
|
+
export function getQueryData(results, ref) {
|
|
165
174
|
const first = getFirstItem(results);
|
|
166
175
|
if (first)
|
|
167
176
|
return first;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { orderBy as firestoreOrderBy, where as firestoreWhere, limit as firestoreLimit, increment as firestoreIncrement, arrayUnion as firestoreArrayUnion, arrayRemove as firestoreArrayRemove, deleteField as firestoreDeleteField, collection as firestoreCollection, doc as firestoreDocument, query as firestoreQuery, onSnapshot, addDoc, setDoc, updateDoc, deleteDoc, getDoc, getDocs, } from "firebase/firestore";
|
|
2
|
-
import { Provider, dispatchNext, dispatchError, Update,
|
|
2
|
+
import { Provider, dispatchNext, dispatchError, Update, ObjectUpdate, Increment, DataUpdate, AssertionError, ArrayUpdate, UnsupportedError, } from "../../index.js";
|
|
3
3
|
// Constants.
|
|
4
4
|
// const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
|
|
5
5
|
const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
|
|
@@ -56,9 +56,9 @@ function* yieldFieldValues(updates, prefix = "") {
|
|
|
56
56
|
yield [`${prefix}${key}`, update !== undefined ? update : firestoreDeleteField()];
|
|
57
57
|
else if (update instanceof Increment)
|
|
58
58
|
yield [`${prefix}${key}`, firestoreIncrement(update.amount)];
|
|
59
|
-
else if (update instanceof DataUpdate || update instanceof
|
|
59
|
+
else if (update instanceof DataUpdate || update instanceof ObjectUpdate)
|
|
60
60
|
yield* yieldFieldValues(update, `${prefix}${key}.`);
|
|
61
|
-
else if (update instanceof
|
|
61
|
+
else if (update instanceof ArrayUpdate) {
|
|
62
62
|
if (update.adds.length && update.deletes.length)
|
|
63
63
|
throw new UnsupportedError("Cannot add/delete array items in one update");
|
|
64
64
|
if (update.adds.length)
|
|
@@ -82,11 +82,10 @@ export class FirestoreClientProvider extends Provider {
|
|
|
82
82
|
this.firestore = firestore;
|
|
83
83
|
}
|
|
84
84
|
async get(ref) {
|
|
85
|
-
|
|
86
|
-
return snapshot.data();
|
|
85
|
+
return (await getDoc(getDocument(this.firestore, ref))).data() || null;
|
|
87
86
|
}
|
|
88
87
|
subscribe(ref, observer) {
|
|
89
|
-
return onSnapshot(getDocument(this.firestore, ref), snapshot => dispatchNext(observer, snapshot.data()), thrown => dispatchError(observer, thrown));
|
|
88
|
+
return onSnapshot(getDocument(this.firestore, ref), snapshot => dispatchNext(observer, snapshot.data() || null), thrown => dispatchError(observer, thrown));
|
|
90
89
|
}
|
|
91
90
|
async add(ref, data) {
|
|
92
91
|
const reference = await addDoc(getCollection(this.firestore, ref), data);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { orderBy as firestoreOrderBy, where as firestoreWhere, limit as firestoreLimit, increment as firestoreIncrement, arrayUnion as firestoreArrayUnion, arrayRemove as firestoreArrayRemove, deleteField as firestoreDeleteField, collection as firestoreCollection, doc as firestoreDocument, query as firestoreQuery, setDoc, addDoc, updateDoc, deleteDoc, getDoc, getDocs, } from "firebase/firestore/lite";
|
|
2
|
-
import { Provider, Update,
|
|
2
|
+
import { Provider, Update, ObjectUpdate, Increment, AssertionError, DataUpdate, ArrayUpdate, UnsupportedError, } from "../../index.js";
|
|
3
3
|
// Constants.
|
|
4
4
|
// const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
|
|
5
5
|
const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
|
|
@@ -56,9 +56,9 @@ function* yieldFieldValues(updates, prefix = "") {
|
|
|
56
56
|
yield [`${prefix}${key}`, update !== undefined ? update : firestoreDeleteField()];
|
|
57
57
|
else if (update instanceof Increment)
|
|
58
58
|
yield [`${prefix}${key}`, firestoreIncrement(update.amount)];
|
|
59
|
-
else if (update instanceof DataUpdate || update instanceof
|
|
59
|
+
else if (update instanceof DataUpdate || update instanceof ObjectUpdate)
|
|
60
60
|
yield* yieldFieldValues(update, `${prefix}${key}.`);
|
|
61
|
-
else if (update instanceof
|
|
61
|
+
else if (update instanceof ArrayUpdate) {
|
|
62
62
|
if (update.adds.length && update.deletes.length)
|
|
63
63
|
throw new UnsupportedError("Cannot add/delete array items in one update");
|
|
64
64
|
if (update.adds.length)
|
|
@@ -83,7 +83,7 @@ export class FirestoreClientProvider extends Provider {
|
|
|
83
83
|
}
|
|
84
84
|
async get(ref) {
|
|
85
85
|
const snapshot = await getDoc(getDocument(this.firestore, ref));
|
|
86
|
-
return snapshot.data();
|
|
86
|
+
return snapshot.data() || null;
|
|
87
87
|
}
|
|
88
88
|
subscribe() {
|
|
89
89
|
throw new Error("FirestoreLiteProvider does not support realtime subscriptions");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Firestore, FieldValue } from "@google-cloud/firestore";
|
|
2
|
-
import { Provider, dispatchNext, dispatchError, Update, Increment, DataUpdate, AssertionError,
|
|
2
|
+
import { Provider, dispatchNext, dispatchError, Update, Increment, DataUpdate, AssertionError, ArrayUpdate, UnsupportedError, ObjectUpdate, } from "../../index.js";
|
|
3
3
|
// Constants.
|
|
4
4
|
// const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
|
|
5
5
|
const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
|
|
@@ -56,9 +56,9 @@ function* yieldFieldValues(updates, prefix = "") {
|
|
|
56
56
|
yield [`${prefix}${key}`, update !== undefined ? update : FieldValue.delete()];
|
|
57
57
|
if (update instanceof Increment)
|
|
58
58
|
yield [`${prefix}${key}`, FieldValue.increment(update.amount)];
|
|
59
|
-
else if (update instanceof DataUpdate || update instanceof
|
|
59
|
+
else if (update instanceof DataUpdate || update instanceof ObjectUpdate)
|
|
60
60
|
yield* yieldFieldValues(update, `${prefix}${key}.`);
|
|
61
|
-
else if (update instanceof
|
|
61
|
+
else if (update instanceof ArrayUpdate) {
|
|
62
62
|
if (update.adds.length && update.deletes.length)
|
|
63
63
|
throw new UnsupportedError("Cannot add/delete array items in one update");
|
|
64
64
|
if (update.adds.length)
|
|
@@ -80,10 +80,10 @@ export class FirestoreServerProvider extends Provider {
|
|
|
80
80
|
this.firestore = firestore;
|
|
81
81
|
}
|
|
82
82
|
async get(ref) {
|
|
83
|
-
return (await getDocument(this.firestore, ref).get()).data();
|
|
83
|
+
return (await getDocument(this.firestore, ref).get()).data() || null;
|
|
84
84
|
}
|
|
85
85
|
subscribe(ref, observer) {
|
|
86
|
-
return getDocument(this.firestore, ref).onSnapshot(snapshot => dispatchNext(observer, snapshot.data()), thrown => dispatchError(observer, thrown));
|
|
86
|
+
return getDocument(this.firestore, ref).onSnapshot(snapshot => dispatchNext(observer, snapshot.data() || null), thrown => dispatchError(observer, thrown));
|
|
87
87
|
}
|
|
88
88
|
async add(ref, data) {
|
|
89
89
|
return (await getCollection(this.firestore, ref).add(data)).id;
|
package/markup/helpers.js
CHANGED
|
@@ -37,13 +37,7 @@ export function nodeToHtml(node) {
|
|
|
37
37
|
}
|
|
38
38
|
return "";
|
|
39
39
|
}
|
|
40
|
-
const propToString = ([key, value]) => value === true
|
|
41
|
-
? key
|
|
42
|
-
: typeof value === "number" && Number.isFinite(value)
|
|
43
|
-
? `${key}="${value.toString()}"`
|
|
44
|
-
: typeof value === "string"
|
|
45
|
-
? `${key}=${serialise(value)}`
|
|
46
|
-
: "";
|
|
40
|
+
const propToString = ([key, value]) => (value === true ? key : typeof value === "number" && Number.isFinite(value) ? `${key}="${value.toString()}"` : typeof value === "string" ? `${key}=${serialise(value)}` : "");
|
|
47
41
|
/**
|
|
48
42
|
* Iterate through all elements in a node.
|
|
49
43
|
* - This is useful if you, e.g. want to apply a `className` to all `<h1>` elements, or make a list of all URLs found in a Node.
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isAsync, toMap, TransformObserver, awaitNext
|
|
1
|
+
import { isAsync, toMap, TransformObserver, awaitNext } from "../util/index.js";
|
|
2
2
|
import { LazyState } from "../stream/index.js";
|
|
3
3
|
import { ThroughProvider } from "./ThroughProvider.js";
|
|
4
4
|
/** How long to wait after all subscriptions have ended to close the source subscription. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRandomKey, dispatchNext, isMapEqual } from "../util/index.js";
|
|
2
2
|
import { DocumentRequiredError } from "../db/index.js";
|
|
3
3
|
import { Provider } from "./Provider.js";
|
|
4
4
|
/**
|
|
@@ -18,23 +18,23 @@ export class MemoryProvider extends Provider {
|
|
|
18
18
|
return ((_a = this._tables)[collection] || (_a[collection] = new Table()));
|
|
19
19
|
}
|
|
20
20
|
get(ref) {
|
|
21
|
-
return this._table(ref).data.get(ref.id);
|
|
21
|
+
return this._table(ref).data.get(ref.id) || null;
|
|
22
22
|
}
|
|
23
23
|
subscribe(ref, observer) {
|
|
24
24
|
const table = this._table(ref);
|
|
25
25
|
const id = ref.id;
|
|
26
26
|
// Call next() immediately with initial results.
|
|
27
|
-
dispatchNext(observer, table.data.get(id));
|
|
27
|
+
dispatchNext(observer, table.data.get(id) || null);
|
|
28
28
|
// Call next() every time the collection changes.
|
|
29
29
|
return table.on(changes => {
|
|
30
|
-
changes.has(id) && dispatchNext(observer, changes.get(id));
|
|
30
|
+
changes.has(id) && dispatchNext(observer, changes.get(id) || null);
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
add(ref, data) {
|
|
34
34
|
const table = this._table(ref);
|
|
35
|
-
let id =
|
|
35
|
+
let id = getRandomKey();
|
|
36
36
|
while (table.data.get(id))
|
|
37
|
-
id =
|
|
37
|
+
id = getRandomKey(); // Regenerate ID until unique.
|
|
38
38
|
table.write(id, data);
|
|
39
39
|
return id;
|
|
40
40
|
}
|
|
@@ -54,7 +54,7 @@ export class MemoryProvider extends Provider {
|
|
|
54
54
|
delete(ref) {
|
|
55
55
|
const table = this._table(ref);
|
|
56
56
|
const id = ref.id;
|
|
57
|
-
table.write(id,
|
|
57
|
+
table.write(id, null);
|
|
58
58
|
}
|
|
59
59
|
getQuery(ref) {
|
|
60
60
|
return ref.transform(this._table(ref).data);
|
|
@@ -110,7 +110,7 @@ export class MemoryProvider extends Provider {
|
|
|
110
110
|
// If there's no limit set: only need to run the filtering (more efficient because sort order doesn't matter).
|
|
111
111
|
let count = 0;
|
|
112
112
|
for (const [id] of ref.limit ? ref.transform(table.data) : ref.filters.transform(table.data)) {
|
|
113
|
-
table.write(id,
|
|
113
|
+
table.write(id, null);
|
|
114
114
|
count++;
|
|
115
115
|
}
|
|
116
116
|
return count;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { validate, ValidateObserver, callAsync } from "../util/index.js";
|
|
1
|
+
import { validate, ValidateObserver, callAsync, validateResult } from "../util/index.js";
|
|
2
2
|
import { validateUpdate } from "../update/index.js";
|
|
3
3
|
import { ThroughProvider } from "./ThroughProvider.js";
|
|
4
4
|
/** Validates any values that are read from or written to a source provider. */
|
|
5
5
|
export class ValidationProvider extends ThroughProvider {
|
|
6
6
|
get(ref) {
|
|
7
|
-
return callAsync(
|
|
7
|
+
return callAsync(validateResult, super.get(ref), ref);
|
|
8
8
|
}
|
|
9
9
|
subscribe(ref, observer) {
|
|
10
10
|
return super.subscribe(ref, new ValidateObserver(ref, observer));
|
package/query/Filter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Data, Entry, Matchable,
|
|
1
|
+
import { Data, Entry, Matchable, Results, ImmutableArray } from "../util/index.js";
|
|
2
2
|
import { Rule } from "./Rule.js";
|
|
3
3
|
import { FilterOperator, QueryKey } from "./types.js";
|
|
4
4
|
/**
|
|
@@ -8,39 +8,53 @@ import { FilterOperator, QueryKey } from "./types.js";
|
|
|
8
8
|
* @param type MatchType reference, e.g. `is` or `contains`
|
|
9
9
|
* @param value Value the specified property should be matched against.
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
12
|
-
readonly operator: FilterOperator;
|
|
13
|
-
readonly matcher: Matcher<unknown, unknown>;
|
|
14
|
-
}
|
|
15
|
-
export declare abstract class Filter<T extends Data> extends Rule<T> implements Matchable<Entry<T>, void> {
|
|
11
|
+
export declare abstract class Filter<T extends Data, V extends unknown = unknown> extends Rule<T> implements Matchable<Entry<T>, void> {
|
|
12
|
+
abstract readonly operator: FilterOperator;
|
|
16
13
|
readonly key: QueryKey<T>;
|
|
17
|
-
readonly value:
|
|
18
|
-
constructor(key: QueryKey<T>, value:
|
|
19
|
-
match([id, data]: Entry<T
|
|
14
|
+
readonly value: V;
|
|
15
|
+
constructor(key: QueryKey<T>, value: V);
|
|
16
|
+
abstract match([id, data]: Entry<T>, target: void): boolean;
|
|
20
17
|
transform(results: Results<T>): Results<T>;
|
|
21
18
|
toString(): string;
|
|
22
19
|
}
|
|
23
20
|
/** Filter a set of values with an `IS` clause. */
|
|
24
21
|
export declare class EqualFilter<T extends Data> extends Filter<T> {
|
|
22
|
+
readonly operator = "IS";
|
|
23
|
+
readonly matcher: (item: unknown, target: unknown) => boolean;
|
|
24
|
+
match([id, data]: Entry<T>): boolean;
|
|
25
25
|
}
|
|
26
26
|
/** Filter a set of values with an `NOT` clause. */
|
|
27
27
|
export declare class NotEqualFilter<T extends Data> extends Filter<T> {
|
|
28
|
+
readonly operator = "NOT";
|
|
29
|
+
match([id, data]: Entry<T>): boolean;
|
|
28
30
|
}
|
|
29
31
|
/** Filter a set of values with an `IS` clause. */
|
|
30
|
-
export declare class InArrayFilter<T extends Data> extends Filter<T> {
|
|
32
|
+
export declare class InArrayFilter<T extends Data> extends Filter<T, ImmutableArray> {
|
|
33
|
+
readonly operator = "IN";
|
|
34
|
+
match([id, data]: Entry<T>): boolean;
|
|
31
35
|
}
|
|
32
36
|
/** Filter a set of values with an `CONTAINS` clause. */
|
|
33
37
|
export declare class ArrayContainsFilter<T extends Data> extends Filter<T> {
|
|
38
|
+
readonly operator = "CONTAINS";
|
|
39
|
+
match([id, data]: Entry<T>): boolean;
|
|
34
40
|
}
|
|
35
41
|
/** Filter a set of values with an `LT` clause. */
|
|
36
42
|
export declare class LessThanFilter<T extends Data> extends Filter<T> {
|
|
43
|
+
readonly operator = "LT";
|
|
44
|
+
match([id, data]: Entry<T>): boolean;
|
|
37
45
|
}
|
|
38
46
|
/** Filter a set of values with an `LTE` clause. */
|
|
39
47
|
export declare class LessThanEqualFilter<T extends Data> extends Filter<T> {
|
|
48
|
+
readonly operator = "LTE";
|
|
49
|
+
match([id, data]: Entry<T>): boolean;
|
|
40
50
|
}
|
|
41
51
|
/** Filter a set of values with an `GT` clause. */
|
|
42
52
|
export declare class GreaterThanFilter<T extends Data> extends Filter<T> {
|
|
53
|
+
readonly operator = "GT";
|
|
54
|
+
match([id, data]: Entry<T>): boolean;
|
|
43
55
|
}
|
|
44
56
|
/** Filter a set of values with an `GTE` clause. */
|
|
45
57
|
export declare class GreaterThanEqualFilter<T extends Data> extends Filter<T> {
|
|
58
|
+
readonly operator = "GTE";
|
|
59
|
+
match([id, data]: Entry<T>): boolean;
|
|
46
60
|
}
|
package/query/Filter.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { match, CONTAINS, IS, GT, GTE, IN, LT, LTE, NOT, yieldFiltered } from "../util/index.js";
|
|
2
2
|
import { Rule } from "./Rule.js";
|
|
3
3
|
import { getQueryProp } from "./helpers.js";
|
|
4
|
+
/**
|
|
5
|
+
* Filter: filters a list of documents.
|
|
6
|
+
*
|
|
7
|
+
* @param key The name of a property that might exist on documents in the collection.
|
|
8
|
+
* @param type MatchType reference, e.g. `is` or `contains`
|
|
9
|
+
* @param value Value the specified property should be matched against.
|
|
10
|
+
*/
|
|
4
11
|
export class Filter extends Rule {
|
|
5
12
|
constructor(key, value) {
|
|
6
13
|
super();
|
|
7
14
|
this.key = key;
|
|
8
15
|
this.value = value;
|
|
9
16
|
}
|
|
10
|
-
match([id, data]) {
|
|
11
|
-
return match(getQueryProp(id, data, this.key), this.matcher, this.value);
|
|
12
|
-
}
|
|
13
17
|
transform(results) {
|
|
14
18
|
return yieldFiltered(results, this);
|
|
15
19
|
}
|
|
@@ -19,33 +23,82 @@ export class Filter extends Rule {
|
|
|
19
23
|
}
|
|
20
24
|
/** Filter a set of values with an `IS` clause. */
|
|
21
25
|
export class EqualFilter extends Filter {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
this.operator = "IS";
|
|
29
|
+
this.matcher = IS;
|
|
30
|
+
}
|
|
31
|
+
match([id, data]) {
|
|
32
|
+
return match(getQueryProp(id, data, this.key), IS, this.value);
|
|
33
|
+
}
|
|
22
34
|
}
|
|
23
|
-
Object.assign(EqualFilter.prototype, { direction: "IS", matcher: IS });
|
|
24
35
|
/** Filter a set of values with an `NOT` clause. */
|
|
25
36
|
export class NotEqualFilter extends Filter {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.operator = "NOT";
|
|
40
|
+
}
|
|
41
|
+
match([id, data]) {
|
|
42
|
+
return match(getQueryProp(id, data, this.key), NOT, this.value);
|
|
43
|
+
}
|
|
26
44
|
}
|
|
27
|
-
Object.assign(NotEqualFilter.prototype, { direction: "NOT", matcher: NOT });
|
|
28
45
|
/** Filter a set of values with an `IS` clause. */
|
|
29
46
|
export class InArrayFilter extends Filter {
|
|
47
|
+
constructor() {
|
|
48
|
+
super(...arguments);
|
|
49
|
+
this.operator = "IN";
|
|
50
|
+
}
|
|
51
|
+
match([id, data]) {
|
|
52
|
+
return match(getQueryProp(id, data, this.key), IN, this.value);
|
|
53
|
+
}
|
|
30
54
|
}
|
|
31
|
-
Object.assign(InArrayFilter.prototype, { direction: "IN", matcher: IN });
|
|
32
55
|
/** Filter a set of values with an `CONTAINS` clause. */
|
|
33
56
|
export class ArrayContainsFilter extends Filter {
|
|
57
|
+
constructor() {
|
|
58
|
+
super(...arguments);
|
|
59
|
+
this.operator = "CONTAINS";
|
|
60
|
+
}
|
|
61
|
+
match([id, data]) {
|
|
62
|
+
return match(getQueryProp(id, data, this.key), CONTAINS, this.value);
|
|
63
|
+
}
|
|
34
64
|
}
|
|
35
|
-
Object.assign(ArrayContainsFilter.prototype, { direction: "CONTAINS", matcher: CONTAINS });
|
|
36
65
|
/** Filter a set of values with an `LT` clause. */
|
|
37
66
|
export class LessThanFilter extends Filter {
|
|
67
|
+
constructor() {
|
|
68
|
+
super(...arguments);
|
|
69
|
+
this.operator = "LT";
|
|
70
|
+
}
|
|
71
|
+
match([id, data]) {
|
|
72
|
+
return match(getQueryProp(id, data, this.key), LT, this.value);
|
|
73
|
+
}
|
|
38
74
|
}
|
|
39
|
-
Object.assign(LessThanFilter.prototype, { direction: "LT", matcher: LT });
|
|
40
75
|
/** Filter a set of values with an `LTE` clause. */
|
|
41
76
|
export class LessThanEqualFilter extends Filter {
|
|
77
|
+
constructor() {
|
|
78
|
+
super(...arguments);
|
|
79
|
+
this.operator = "LTE";
|
|
80
|
+
}
|
|
81
|
+
match([id, data]) {
|
|
82
|
+
return match(getQueryProp(id, data, this.key), LTE, this.value);
|
|
83
|
+
}
|
|
42
84
|
}
|
|
43
|
-
Object.assign(LessThanEqualFilter.prototype, { direction: "LTE", matcher: LTE });
|
|
44
85
|
/** Filter a set of values with an `GT` clause. */
|
|
45
86
|
export class GreaterThanFilter extends Filter {
|
|
87
|
+
constructor() {
|
|
88
|
+
super(...arguments);
|
|
89
|
+
this.operator = "GT";
|
|
90
|
+
}
|
|
91
|
+
match([id, data]) {
|
|
92
|
+
return match(getQueryProp(id, data, this.key), GT, this.value);
|
|
93
|
+
}
|
|
46
94
|
}
|
|
47
|
-
Object.assign(GreaterThanFilter.prototype, { direction: "GT", matcher: GT });
|
|
48
95
|
/** Filter a set of values with an `GTE` clause. */
|
|
49
96
|
export class GreaterThanEqualFilter extends Filter {
|
|
97
|
+
constructor() {
|
|
98
|
+
super(...arguments);
|
|
99
|
+
this.operator = "GTE";
|
|
100
|
+
}
|
|
101
|
+
match([id, data]) {
|
|
102
|
+
return match(getQueryProp(id, data, this.key), GTE, this.value);
|
|
103
|
+
}
|
|
50
104
|
}
|
|
51
|
-
Object.assign(GreaterThanEqualFilter.prototype, { direction: "GTE", matcher: GTE });
|
package/query/Filters.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Entry,
|
|
1
|
+
import { Entry, Data, Key, Results, ImmutableArray, ArrayType } from "../util/index.js";
|
|
2
2
|
import type { Filterable, QueryKey } from "./types.js";
|
|
3
3
|
import { Filter } from "./Filter.js";
|
|
4
4
|
import { Rules } from "./Rules.js";
|
package/query/Filters.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { yieldFiltered } from "../util/index.js";
|
|
2
|
-
import { ArrayContainsFilter, EqualFilter, GreaterThanEqualFilter, GreaterThanFilter, InArrayFilter, LessThanEqualFilter, LessThanFilter, NotEqualFilter
|
|
2
|
+
import { ArrayContainsFilter, EqualFilter, GreaterThanEqualFilter, GreaterThanFilter, InArrayFilter, LessThanEqualFilter, LessThanFilter, NotEqualFilter } from "./Filter.js";
|
|
3
3
|
import { Rules } from "./Rules.js";
|
|
4
4
|
/** A set of filters. */
|
|
5
5
|
export class Filters extends Rules {
|
package/query/Query.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Data,
|
|
1
|
+
import { Data, Entry, Key, Results, ArrayType, ImmutableArray } from "../util/index.js";
|
|
2
2
|
import type { Queryable, QueryKey } from "./types.js";
|
|
3
3
|
import { Filters } from "./Filters.js";
|
|
4
4
|
import { Sorts } from "./Sorts.js";
|
package/query/Sort.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import { Data, Entry, Rankable,
|
|
1
|
+
import { Data, Entry, Rankable, Results } from "../util/index.js";
|
|
2
2
|
import { Rule } from "./Rule.js";
|
|
3
3
|
import { QueryKey, SortDirection } from "./types.js";
|
|
4
4
|
/** Sort a list of values. */
|
|
5
|
-
export interface Sort<T extends Data> {
|
|
6
|
-
readonly direction: SortDirection;
|
|
7
|
-
readonly ranker: Ranker<unknown>;
|
|
8
|
-
}
|
|
9
5
|
export declare abstract class Sort<T extends Data> extends Rule<T> implements Rankable<Entry<T>> {
|
|
6
|
+
abstract readonly direction: SortDirection;
|
|
10
7
|
readonly key: QueryKey<T>;
|
|
11
8
|
constructor(key: QueryKey<T>);
|
|
12
|
-
rank(
|
|
9
|
+
abstract rank(left: Entry<T>, right: Entry<T>): number;
|
|
13
10
|
transform(iterable: Results<T>): Results<T>;
|
|
14
11
|
toString(): string;
|
|
15
12
|
}
|
|
16
13
|
/** Sort a list of values in ascending order. */
|
|
17
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;
|
|
18
17
|
}
|
|
19
18
|
/** Sort a list of values in descending order. */
|
|
20
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;
|
|
21
22
|
}
|
package/query/Sort.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { ASC, rank, DESC, sortItems } from "../util/index.js";
|
|
2
2
|
import { getQueryProp } from "./helpers.js";
|
|
3
3
|
import { Rule } from "./Rule.js";
|
|
4
|
+
/** Sort a list of values. */
|
|
4
5
|
export class Sort extends Rule {
|
|
5
6
|
constructor(key) {
|
|
6
7
|
super();
|
|
7
8
|
this.key = key;
|
|
8
9
|
}
|
|
9
|
-
rank([leftId, leftData], [rightId, rightData]) {
|
|
10
|
-
return rank(getQueryProp(leftId, leftData, this.key), this.ranker, getQueryProp(rightId, rightData, this.key));
|
|
11
|
-
}
|
|
12
10
|
transform(iterable) {
|
|
13
11
|
return sortItems(iterable, this);
|
|
14
12
|
}
|
|
@@ -18,9 +16,21 @@ export class Sort extends Rule {
|
|
|
18
16
|
}
|
|
19
17
|
/** Sort a list of values in ascending order. */
|
|
20
18
|
export class AscendingSort extends Sort {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.direction = "ASC";
|
|
22
|
+
}
|
|
23
|
+
rank([leftId, leftData], [rightId, rightData]) {
|
|
24
|
+
return rank(getQueryProp(leftId, leftData, this.key), ASC, getQueryProp(rightId, rightData, this.key));
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
|
-
Object.assign(AscendingSort.prototype, { direction: "ASC", ranker: ASC });
|
|
23
27
|
/** Sort a list of values in descending order. */
|
|
24
28
|
export class DescendingSort extends Sort {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
this.direction = "DESC";
|
|
32
|
+
}
|
|
33
|
+
rank([leftId, leftData], [rightId, rightData]) {
|
|
34
|
+
return rank(getQueryProp(leftId, leftData, this.key), DESC, getQueryProp(rightId, rightData, this.key));
|
|
35
|
+
}
|
|
25
36
|
}
|
|
26
|
-
Object.assign(DescendingSort.prototype, { direction: "DESC", ranker: DESC });
|
package/query/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Data, Key, Matchable, Entry, Rankable, ImmutableArray, ArrayType } from "../util/index.js";
|
|
2
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
3
|
export declare type QueryKey<T extends Data> = "id" | Key<T>;
|
|
4
4
|
/** Possible operator references. */
|
package/react/index.d.ts
CHANGED
|
@@ -5,7 +5,5 @@ export * from "./useSubscribe.js";
|
|
|
5
5
|
export * from "./useState.js";
|
|
6
6
|
export * from "./useFetch.js";
|
|
7
7
|
export * from "./useDocument.js";
|
|
8
|
-
export * from "./useDocumentData.js";
|
|
9
8
|
export * from "./useQuery.js";
|
|
10
|
-
export * from "./useQueryFirst.js";
|
|
11
9
|
export * from "./usePagination.js";
|
package/react/index.js
CHANGED
|
@@ -5,7 +5,5 @@ export * from "./useSubscribe.js";
|
|
|
5
5
|
export * from "./useState.js";
|
|
6
6
|
export * from "./useFetch.js";
|
|
7
7
|
export * from "./useDocument.js";
|
|
8
|
-
export * from "./useDocumentData.js";
|
|
9
8
|
export * from "./useQuery.js";
|
|
10
|
-
export * from "./useQueryFirst.js";
|
|
11
9
|
export * from "./usePagination.js";
|
package/react/useDocument.d.ts
CHANGED
|
@@ -32,3 +32,9 @@ export declare function useAsyncDocument<T extends Data>(ref: DataDocument<T> |
|
|
|
32
32
|
*/
|
|
33
33
|
export declare function useDocument<T extends Data>(ref: DataDocument<T>, maxAge?: number | true): Result<T>;
|
|
34
34
|
export declare function useDocument<T extends Data>(ref: DataDocument<T> | undefined, maxAge?: number | true): Result<T> | undefined;
|
|
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: DataDocument<T>, maxAge?: number | true): T | PromiseLike<T>;
|
|
37
|
+
export declare function useAsyncDocumentData<T extends Data>(ref: DataDocument<T> | undefined, maxAge?: number | true): T | PromiseLike<T> | undefined;
|
|
38
|
+
/** Use the data of a document or `undefined` if the query has no matching results. */
|
|
39
|
+
export declare function useDocumentData<T extends Data>(ref: DataDocument<T>, maxAge?: number | true): T;
|
|
40
|
+
export declare function useDocumentData<T extends Data>(ref: DataDocument<T> | undefined, maxAge?: number | true): T | undefined;
|
package/react/useDocument.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { CacheProvider, throwAsync, NOERROR, findSourceProvider, NOVALUE } from "../index.js";
|
|
2
|
+
import { CacheProvider, throwAsync, NOERROR, findSourceProvider, NOVALUE, callAsync, getDocumentData } from "../index.js";
|
|
3
3
|
import { usePureEffect } from "./usePureEffect.js";
|
|
4
4
|
import { usePureMemo } from "./usePureMemo.js";
|
|
5
5
|
import { usePureState } from "./usePureState.js";
|
|
@@ -57,3 +57,10 @@ function subscribeEffect(ref, maxAge, next, error) {
|
|
|
57
57
|
export function useDocument(ref, maxAge) {
|
|
58
58
|
return throwAsync(useAsyncDocument(ref, maxAge));
|
|
59
59
|
}
|
|
60
|
+
export function useAsyncDocumentData(ref, maxAge) {
|
|
61
|
+
const result = useAsyncDocument(ref, maxAge);
|
|
62
|
+
return ref && result !== undefined ? callAsync(getDocumentData, result, ref) : undefined;
|
|
63
|
+
}
|
|
64
|
+
export function useDocumentData(ref, maxAge) {
|
|
65
|
+
return throwAsync(useAsyncDocumentData(ref, maxAge));
|
|
66
|
+
}
|
package/react/useQuery.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ResultsMap, DataQuery, Data, Entry } 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,3 +33,15 @@ export declare function useAsyncQuery<T extends Data>(ref: DataQuery<T> | undefi
|
|
|
33
33
|
*/
|
|
34
34
|
export declare function useQuery<T extends Data>(ref: DataQuery<T>, maxAge?: number | true): ResultsMap<T>;
|
|
35
35
|
export declare function useQuery<T extends Data>(ref: DataQuery<T> | undefined, maxAge?: number | true): ResultsMap<T> | undefined;
|
|
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: DataQuery<T>, maxAge?: number | true): Entry<T> | undefined | PromiseLike<Entry<T> | undefined>;
|
|
38
|
+
export declare function useAsyncQueryResult<T extends Data>(ref: DataQuery<T> | undefined, maxAge?: number | true): Entry<T> | undefined | PromiseLike<Entry<T> | undefined>;
|
|
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: DataQuery<T>, maxAge?: number | true): Entry<T> | undefined;
|
|
41
|
+
export declare function useQueryResult<T extends Data>(ref: DataQuery<T> | undefined, maxAge?: number | true): Entry<T> | undefined;
|
|
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: DataQuery<T>, maxAge?: number | true): Entry<T> | PromiseLike<Entry<T>>;
|
|
44
|
+
export declare function useAsyncQueryData<T extends Data>(ref: DataQuery<T> | undefined, maxAge?: number | true): Entry<T> | PromiseLike<Entry<T>> | undefined;
|
|
45
|
+
/** Use the first result of a query. */
|
|
46
|
+
export declare function useQueryData<T extends Data>(ref: DataQuery<T>, maxAge?: number | true): Entry<T>;
|
|
47
|
+
export declare function useQueryData<T extends Data>(ref: DataQuery<T> | undefined, maxAge?: number | true): Entry<T> | undefined;
|
package/react/useQuery.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { CacheProvider,
|
|
2
|
+
import { CacheProvider, NOERROR, findSourceProvider, NOVALUE, TransformObserver, toMap, callAsync, getQueryData, throwAsync, getFirstItem } from "../index.js";
|
|
3
3
|
import { usePureEffect } from "./usePureEffect.js";
|
|
4
4
|
import { usePureMemo } from "./usePureMemo.js";
|
|
5
5
|
import { usePureState } from "./usePureState.js";
|
|
@@ -58,3 +58,17 @@ function subscribeEffect(ref, maxAge, next, error) {
|
|
|
58
58
|
export function useQuery(ref, maxAge) {
|
|
59
59
|
return throwAsync(useAsyncQuery(ref, maxAge));
|
|
60
60
|
}
|
|
61
|
+
export function useAsyncQueryResult(ref, maxAge) {
|
|
62
|
+
const results = useAsyncQuery(ref ? ref.max(1) : undefined, maxAge);
|
|
63
|
+
return ref && results ? callAsync(getFirstItem, results) : undefined;
|
|
64
|
+
}
|
|
65
|
+
export function useQueryResult(ref, maxAge) {
|
|
66
|
+
return throwAsync(useAsyncQueryResult(ref, maxAge));
|
|
67
|
+
}
|
|
68
|
+
export function useAsyncQueryData(ref, maxAge) {
|
|
69
|
+
const results = useAsyncQuery(ref ? ref.max(1) : undefined, maxAge);
|
|
70
|
+
return ref && results ? callAsync(getQueryData, results, ref) : undefined;
|
|
71
|
+
}
|
|
72
|
+
export function useQueryData(ref, maxAge) {
|
|
73
|
+
return throwAsync(useAsyncQueryData(ref, maxAge));
|
|
74
|
+
}
|