shelving 1.91.2 → 1.92.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/Change.d.ts +19 -20
- package/db/Change.js +22 -21
- package/db/CollectionReference.d.ts +103 -0
- package/db/CollectionReference.js +127 -0
- package/db/Database.d.ts +21 -23
- package/db/Database.js +18 -18
- package/db/{Item.d.ts → ItemReference.d.ts} +13 -14
- package/db/{Item.js → ItemReference.js} +14 -17
- package/db/ItemState.d.ts +3 -3
- package/db/{Query.d.ts → QueryReference.d.ts} +25 -33
- package/db/QueryReference.js +101 -0
- package/db/QueryState.d.ts +10 -10
- package/db/QueryState.js +20 -18
- package/db/index.d.ts +3 -3
- package/db/index.js +3 -3
- package/firestore/client/FirestoreClientProvider.d.ts +13 -13
- package/firestore/client/FirestoreClientProvider.js +55 -84
- package/firestore/lite/FirestoreLiteProvider.d.ts +11 -11
- package/firestore/lite/FirestoreLiteProvider.js +52 -83
- package/firestore/server/FirestoreServerProvider.d.ts +13 -13
- package/firestore/server/FirestoreServerProvider.js +51 -84
- package/index.d.ts +0 -2
- package/index.js +0 -2
- package/package.json +1 -3
- package/provider/CacheProvider.d.ts +7 -7
- package/provider/CacheProvider.js +14 -14
- package/provider/DebugProvider.d.ts +11 -11
- package/provider/DebugProvider.js +28 -29
- package/provider/MemoryProvider.d.ts +17 -17
- package/provider/MemoryProvider.js +41 -43
- package/provider/Provider.d.ts +15 -15
- package/provider/ThroughProvider.d.ts +12 -12
- package/provider/ThroughProvider.js +20 -20
- package/provider/ValidationProvider.d.ts +11 -11
- package/provider/ValidationProvider.js +16 -12
- package/react/useData.d.ts +5 -5
- package/react/useData.js +2 -2
- package/state/DataState.d.ts +4 -8
- package/state/DataState.js +6 -16
- package/state/DictionaryState.d.ts +4 -6
- package/state/DictionaryState.js +4 -9
- package/test/basics.d.ts +1 -1
- package/test/people.d.ts +1 -1
- package/test/util.d.ts +1 -1
- package/test/util.js +1 -1
- package/util/data.d.ts +2 -2
- package/util/equal.js +5 -5
- package/util/hydrate.d.ts +13 -26
- package/util/hydrate.js +44 -60
- package/util/index.d.ts +2 -0
- package/util/index.js +2 -0
- package/util/iterate.d.ts +2 -0
- package/util/match.d.ts +2 -10
- package/util/match.js +4 -8
- package/util/query.d.ts +83 -0
- package/util/query.js +129 -0
- package/util/sort.d.ts +8 -15
- package/util/sort.js +15 -19
- package/util/transform.d.ts +26 -45
- package/util/transform.js +24 -29
- package/util/update.d.ts +22 -0
- package/util/update.js +42 -0
- package/util/validate.js +2 -2
- package/constraint/Constraint.d.ts +0 -7
- package/constraint/Constraint.js +0 -3
- package/constraint/Constraints.d.ts +0 -20
- package/constraint/Constraints.js +0 -34
- package/constraint/Filter.d.ts +0 -34
- package/constraint/Filter.js +0 -89
- package/constraint/Filters.d.ts +0 -27
- package/constraint/Filters.js +0 -41
- package/constraint/Sort.d.ts +0 -18
- package/constraint/Sort.js +0 -33
- package/constraint/Sorts.d.ts +0 -26
- package/constraint/Sorts.js +0 -47
- package/constraint/Statement.d.ts +0 -45
- package/constraint/Statement.js +0 -79
- package/constraint/index.d.ts +0 -7
- package/constraint/index.js +0 -7
- package/db/Collection.d.ts +0 -64
- package/db/Collection.js +0 -83
- package/db/Query.js +0 -94
- package/update/ArrayUpdate.d.ts +0 -17
- package/update/ArrayUpdate.js +0 -31
- package/update/DataUpdate.d.ts +0 -37
- package/update/DataUpdate.js +0 -44
- package/update/Delete.d.ts +0 -10
- package/update/Delete.js +0 -12
- package/update/DictionaryUpdate.d.ts +0 -31
- package/update/DictionaryUpdate.js +0 -62
- package/update/Increment.d.ts +0 -18
- package/update/Increment.js +0 -22
- package/update/Update.d.ts +0 -8
- package/update/Update.js +0 -6
- package/update/hydrations.d.ts +0 -3
- package/update/hydrations.js +0 -13
- package/update/index.d.ts +0 -7
- package/update/index.js +0 -7
package/db/ItemState.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AsyncItemReference, ItemData, ItemReference, ItemValue } from "./ItemReference.js";
|
|
2
2
|
import type { Data } from "../util/data.js";
|
|
3
3
|
import type { Dispatch } from "../util/function.js";
|
|
4
4
|
import { BooleanState } from "../state/BooleanState.js";
|
|
5
5
|
import { State } from "../state/State.js";
|
|
6
6
|
/** Hold the current state of a item. */
|
|
7
7
|
export declare class ItemState<T extends Data = Data> extends State<ItemValue<T>> {
|
|
8
|
-
readonly ref:
|
|
8
|
+
readonly ref: ItemReference<T> | AsyncItemReference<T>;
|
|
9
9
|
readonly busy: BooleanState;
|
|
10
10
|
/** Get the data of the item (throws `RequiredError` if item doesn't exist). */
|
|
11
11
|
get data(): ItemData<T>;
|
|
12
12
|
/** Does the item exist (i.e. its value isn't `null`)? */
|
|
13
13
|
get exists(): boolean;
|
|
14
|
-
constructor(ref:
|
|
14
|
+
constructor(ref: ItemReference<T> | AsyncItemReference<T>);
|
|
15
15
|
/** Refresh this state from the source provider. */
|
|
16
16
|
readonly refresh: () => void;
|
|
17
17
|
private _refresh;
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import type { ItemArray, ItemData, ItemValue } from "./
|
|
2
|
-
import type { PossibleFilters } from "../constraint/Filters.js";
|
|
3
|
-
import type { PossibleSorts } from "../constraint/Sorts.js";
|
|
1
|
+
import type { ItemArray, ItemData, ItemQuery, ItemValue } from "./ItemReference.js";
|
|
4
2
|
import type { AsyncProvider, Provider } from "../provider/Provider.js";
|
|
5
|
-
import type { Updates } from "../update/DataUpdate.js";
|
|
6
3
|
import type { Data } from "../util/data.js";
|
|
7
4
|
import type { Dispatch, Handler, Stop } from "../util/function.js";
|
|
8
|
-
import {
|
|
5
|
+
import type { Updates } from "../util/update.js";
|
|
9
6
|
/** Reference to a set of items in a sync or async provider. */
|
|
10
|
-
declare abstract class
|
|
7
|
+
declare abstract class AbstractQueryReference<T extends Data = Data> implements AsyncIterable<ItemArray<T>> {
|
|
11
8
|
abstract readonly provider: Provider | AsyncProvider;
|
|
12
|
-
|
|
9
|
+
readonly collection: string;
|
|
10
|
+
readonly query: ItemQuery<T>;
|
|
11
|
+
constructor(collection: string, query?: ItemQuery<T>);
|
|
12
|
+
/** Get a copy of this query reference with additional query props. */
|
|
13
|
+
with(query: ItemQuery<T>): this;
|
|
13
14
|
/**
|
|
14
15
|
* Get array of entities for this query.
|
|
15
16
|
* @return Array of entities.
|
|
16
17
|
*/
|
|
17
|
-
abstract
|
|
18
|
+
abstract items: ItemArray<T> | PromiseLike<ItemArray<T>>;
|
|
18
19
|
/**
|
|
19
20
|
* Count the number of results of this set of items.
|
|
20
21
|
* @return Number of items matching the query (possibly promised).
|
|
@@ -29,22 +30,17 @@ declare abstract class BaseQuery<T extends Data = Data> extends Statement<ItemDa
|
|
|
29
30
|
* Get the first item matched by this query or `null` if this query has no results.
|
|
30
31
|
* @throws RequiredError if there were no results for this query.
|
|
31
32
|
*/
|
|
32
|
-
abstract
|
|
33
|
-
/**
|
|
34
|
-
* Get the first item matched by this query.
|
|
35
|
-
* @throws RequiredError if there were no results for this query.
|
|
36
|
-
*/
|
|
37
|
-
abstract firstData: ItemData<T> | PromiseLike<ItemData<T>>;
|
|
33
|
+
abstract first: ItemValue<T> | PromiseLike<ItemValue<T>>;
|
|
38
34
|
/**
|
|
39
35
|
* Get the last item matched by this query or `null` if this query has no results.
|
|
40
36
|
* @throws RequiredError if there were no results for this query.
|
|
41
37
|
*/
|
|
42
|
-
abstract
|
|
38
|
+
abstract last: ItemValue<T> | PromiseLike<ItemValue<T>>;
|
|
43
39
|
/**
|
|
44
|
-
* Get the
|
|
40
|
+
* Get the first item matched by this query.
|
|
45
41
|
* @throws RequiredError if there were no results for this query.
|
|
46
42
|
*/
|
|
47
|
-
abstract
|
|
43
|
+
abstract data: ItemData<T> | PromiseLike<ItemData<T>>;
|
|
48
44
|
/**
|
|
49
45
|
* Set all matching items to the same exact value.
|
|
50
46
|
*
|
|
@@ -70,33 +66,29 @@ declare abstract class BaseQuery<T extends Data = Data> extends Statement<ItemDa
|
|
|
70
66
|
[Symbol.asyncIterator](): AsyncIterator<ItemArray<T>>;
|
|
71
67
|
}
|
|
72
68
|
/** Reference to a set of items in a provider. */
|
|
73
|
-
export declare class
|
|
69
|
+
export declare class QueryReference<T extends Data = Data> extends AbstractQueryReference<T> {
|
|
74
70
|
readonly provider: Provider;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
get value(): ItemArray<T>;
|
|
71
|
+
constructor(provider: Provider, collection: string, query?: ItemQuery<T>);
|
|
72
|
+
get items(): ItemArray<T>;
|
|
78
73
|
get count(): number;
|
|
79
74
|
get exists(): boolean;
|
|
80
|
-
get
|
|
81
|
-
get
|
|
82
|
-
get
|
|
83
|
-
get lastData(): ItemData<T>;
|
|
75
|
+
get first(): ItemValue<T>;
|
|
76
|
+
get last(): ItemValue<T>;
|
|
77
|
+
get data(): ItemData<T>;
|
|
84
78
|
set(data: T): number;
|
|
85
79
|
update(updates: Updates<T>): number;
|
|
86
80
|
delete(): number;
|
|
87
81
|
}
|
|
88
82
|
/** Reference to a set of items in a provider. */
|
|
89
|
-
export declare class
|
|
83
|
+
export declare class AsyncQueryReference<T extends Data = Data> extends AbstractQueryReference<T> {
|
|
90
84
|
readonly provider: AsyncProvider;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
get value(): Promise<ItemArray<T>>;
|
|
85
|
+
constructor(provider: AsyncProvider, collection: string, query?: ItemQuery<T>);
|
|
86
|
+
get items(): Promise<ItemArray<T>>;
|
|
94
87
|
get count(): Promise<number>;
|
|
95
88
|
get exists(): Promise<boolean>;
|
|
96
|
-
get
|
|
97
|
-
get
|
|
98
|
-
get
|
|
99
|
-
get lastData(): Promise<ItemData<T>>;
|
|
89
|
+
get first(): Promise<ItemValue<T>>;
|
|
90
|
+
get last(): Promise<ItemValue<T>>;
|
|
91
|
+
get data(): Promise<ItemData<T>>;
|
|
100
92
|
set(data: T): Promise<number>;
|
|
101
93
|
update(updates: Updates<T>): PromiseLike<number>;
|
|
102
94
|
delete(): PromiseLike<number>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { countArray, getOptionalFirstItem, getOptionalLastItem, isArrayLength } from "../util/array.js";
|
|
2
|
+
import { getData } from "../util/data.js";
|
|
3
|
+
import { cloneObjectWith } from "../util/object.js";
|
|
4
|
+
import { runSequence } from "../util/sequence.js";
|
|
5
|
+
/** Reference to a set of items in a sync or async provider. */
|
|
6
|
+
class AbstractQueryReference {
|
|
7
|
+
constructor(collection, query = {}) {
|
|
8
|
+
this.collection = collection;
|
|
9
|
+
this.query = query;
|
|
10
|
+
}
|
|
11
|
+
/** Get a copy of this query reference with additional query props. */
|
|
12
|
+
with(query) {
|
|
13
|
+
return cloneObjectWith(this, "query", { ...this.query, query });
|
|
14
|
+
}
|
|
15
|
+
// Implement toString()
|
|
16
|
+
toString() {
|
|
17
|
+
return `${this.collection}?{${JSON.stringify(this.query)}`;
|
|
18
|
+
}
|
|
19
|
+
/** Subscribe to this item. */
|
|
20
|
+
subscribe(onNext, onError) {
|
|
21
|
+
return runSequence(this, onNext, onError);
|
|
22
|
+
}
|
|
23
|
+
// Implement AsyncIterable
|
|
24
|
+
[Symbol.asyncIterator]() {
|
|
25
|
+
return this.provider.getQuerySequence(this.collection, this.query)[Symbol.asyncIterator]();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Reference to a set of items in a provider. */
|
|
29
|
+
export class QueryReference extends AbstractQueryReference {
|
|
30
|
+
constructor(provider, collection, query) {
|
|
31
|
+
super(collection, query);
|
|
32
|
+
this.provider = provider;
|
|
33
|
+
}
|
|
34
|
+
get items() {
|
|
35
|
+
return _getItemArray(this);
|
|
36
|
+
}
|
|
37
|
+
get count() {
|
|
38
|
+
return this.items.length;
|
|
39
|
+
}
|
|
40
|
+
get exists() {
|
|
41
|
+
return !!_getSingleItemArray(this).length;
|
|
42
|
+
}
|
|
43
|
+
get first() {
|
|
44
|
+
return getOptionalFirstItem(_getSingleItemArray(this));
|
|
45
|
+
}
|
|
46
|
+
get last() {
|
|
47
|
+
return getOptionalLastItem(this.items);
|
|
48
|
+
}
|
|
49
|
+
get data() {
|
|
50
|
+
return getData(this.first);
|
|
51
|
+
}
|
|
52
|
+
set(data) {
|
|
53
|
+
return this.provider.setQuery(this.collection, this.query, data);
|
|
54
|
+
}
|
|
55
|
+
update(updates) {
|
|
56
|
+
return this.provider.updateQuery(this.collection, this.query, updates);
|
|
57
|
+
}
|
|
58
|
+
delete() {
|
|
59
|
+
return this.provider.deleteQuery(this.collection, this.query);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Reference to a set of items in a provider. */
|
|
63
|
+
export class AsyncQueryReference extends AbstractQueryReference {
|
|
64
|
+
constructor(provider, collection, query) {
|
|
65
|
+
super(collection, query);
|
|
66
|
+
this.provider = provider;
|
|
67
|
+
}
|
|
68
|
+
get items() {
|
|
69
|
+
return _getItemArray(this);
|
|
70
|
+
}
|
|
71
|
+
get count() {
|
|
72
|
+
return this.items.then(countArray);
|
|
73
|
+
}
|
|
74
|
+
get exists() {
|
|
75
|
+
return _getSingleItemArray(this).then(isArrayLength);
|
|
76
|
+
}
|
|
77
|
+
get first() {
|
|
78
|
+
return _getSingleItemArray(this).then(getOptionalFirstItem);
|
|
79
|
+
}
|
|
80
|
+
get last() {
|
|
81
|
+
return this.items.then(getOptionalLastItem);
|
|
82
|
+
}
|
|
83
|
+
get data() {
|
|
84
|
+
return this.first.then(getData);
|
|
85
|
+
}
|
|
86
|
+
set(data) {
|
|
87
|
+
return this.provider.setQuery(this.collection, this.query, data);
|
|
88
|
+
}
|
|
89
|
+
update(updates) {
|
|
90
|
+
return this.provider.updateQuery(this.collection, this.query, updates);
|
|
91
|
+
}
|
|
92
|
+
delete() {
|
|
93
|
+
return this.provider.deleteQuery(this.collection, this.query);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function _getItemArray({ provider, collection, query }) {
|
|
97
|
+
return provider.getQuery(collection, query);
|
|
98
|
+
}
|
|
99
|
+
function _getSingleItemArray({ provider, collection, query }) {
|
|
100
|
+
return provider.getQuery(collection, { ...query, $limit: 1 });
|
|
101
|
+
}
|
package/db/QueryState.d.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import type { ItemArray, ItemData, ItemValue } from "
|
|
2
|
-
import type {
|
|
1
|
+
import type { ItemArray, ItemData, ItemValue } from "./ItemReference.js";
|
|
2
|
+
import type { AsyncQueryReference, QueryReference } from "./QueryReference.js";
|
|
3
3
|
import type { Data } from "../util/data.js";
|
|
4
4
|
import type { Stop } from "../util/function.js";
|
|
5
5
|
import { BooleanState } from "../state/BooleanState.js";
|
|
6
6
|
import { State } from "../state/State.js";
|
|
7
7
|
/** Hold the current state of a query. */
|
|
8
8
|
export declare class QueryState<T extends Data = Data> extends State<ItemArray<T>> implements Iterable<ItemData<T>> {
|
|
9
|
-
readonly ref:
|
|
9
|
+
readonly ref: QueryReference<T> | AsyncQueryReference<T>;
|
|
10
10
|
readonly busy: BooleanState;
|
|
11
11
|
readonly limit: number;
|
|
12
12
|
/** Can more items be loaded after the current result. */
|
|
13
13
|
get hasMore(): boolean;
|
|
14
14
|
private _hasMore;
|
|
15
|
+
/** Get the items currently stored in this query. */
|
|
16
|
+
get items(): ItemArray<T>;
|
|
15
17
|
/** Get the first document matched by this query or `null` if this query has no items. */
|
|
16
|
-
get
|
|
17
|
-
/** Get the first document matched by this query. */
|
|
18
|
-
get firstData(): ItemData<T>;
|
|
18
|
+
get first(): ItemValue<T>;
|
|
19
19
|
/** Get the last document matched by this query or `null` if this query has no items. */
|
|
20
|
-
get
|
|
21
|
-
/** Get the
|
|
22
|
-
get
|
|
20
|
+
get last(): ItemValue<T>;
|
|
21
|
+
/** Get the first document matched by this query. */
|
|
22
|
+
get data(): ItemData<T>;
|
|
23
23
|
/** Does the document have at least one result. */
|
|
24
24
|
get exists(): boolean;
|
|
25
25
|
/** Get the number of items matching this query. */
|
|
26
26
|
get count(): number;
|
|
27
|
-
constructor(ref:
|
|
27
|
+
constructor(ref: QueryReference<T> | AsyncQueryReference<T>);
|
|
28
28
|
/** Refresh this state from the source provider. */
|
|
29
29
|
readonly refresh: () => void;
|
|
30
30
|
private _refresh;
|
package/db/QueryState.js
CHANGED
|
@@ -2,7 +2,9 @@ import { CacheProvider } from "../provider/CacheProvider.js";
|
|
|
2
2
|
import { LazyDeferredSequence } from "../sequence/LazyDeferredSequence.js";
|
|
3
3
|
import { BooleanState } from "../state/BooleanState.js";
|
|
4
4
|
import { State } from "../state/State.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getOptionalFirstItem, getOptionalLastItem } from "../util/array.js";
|
|
6
|
+
import { getData } from "../util/data.js";
|
|
7
|
+
import { getAfterQuery, getLimit } from "../util/query.js";
|
|
6
8
|
import { getOptionalSource } from "../util/source.js";
|
|
7
9
|
/** Hold the current state of a query. */
|
|
8
10
|
export class QueryState extends State {
|
|
@@ -10,21 +12,21 @@ export class QueryState extends State {
|
|
|
10
12
|
get hasMore() {
|
|
11
13
|
return this._hasMore;
|
|
12
14
|
}
|
|
15
|
+
/** Get the items currently stored in this query. */
|
|
16
|
+
get items() {
|
|
17
|
+
return this.value;
|
|
18
|
+
}
|
|
13
19
|
/** Get the first document matched by this query or `null` if this query has no items. */
|
|
14
|
-
get
|
|
20
|
+
get first() {
|
|
15
21
|
return getOptionalFirstItem(this.value);
|
|
16
22
|
}
|
|
17
|
-
/** Get the first document matched by this query. */
|
|
18
|
-
get firstData() {
|
|
19
|
-
return getFirstItem(this.value);
|
|
20
|
-
}
|
|
21
23
|
/** Get the last document matched by this query or `null` if this query has no items. */
|
|
22
|
-
get
|
|
24
|
+
get last() {
|
|
23
25
|
return getOptionalLastItem(this.value);
|
|
24
26
|
}
|
|
25
|
-
/** Get the
|
|
26
|
-
get
|
|
27
|
-
return
|
|
27
|
+
/** Get the first document matched by this query. */
|
|
28
|
+
get data() {
|
|
29
|
+
return getData(this.first);
|
|
28
30
|
}
|
|
29
31
|
/** Does the document have at least one result. */
|
|
30
32
|
get exists() {
|
|
@@ -35,8 +37,8 @@ export class QueryState extends State {
|
|
|
35
37
|
return this.value.length;
|
|
36
38
|
}
|
|
37
39
|
constructor(ref) {
|
|
38
|
-
var _a;
|
|
39
|
-
const { provider, collection,
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const { provider, collection, query } = ref;
|
|
40
42
|
const table = (_a = getOptionalSource(CacheProvider, provider)) === null || _a === void 0 ? void 0 : _a.memory.getTable(collection);
|
|
41
43
|
const time = table ? table.getQueryTime(ref) : null;
|
|
42
44
|
const isCached = typeof time === "number";
|
|
@@ -58,7 +60,7 @@ export class QueryState extends State {
|
|
|
58
60
|
};
|
|
59
61
|
this._time = time;
|
|
60
62
|
this.ref = ref;
|
|
61
|
-
this.limit =
|
|
63
|
+
this.limit = (_b = getLimit(query)) !== null && _b !== void 0 ? _b : Infinity;
|
|
62
64
|
// Queue a request to refresh the value if it doesn't exist.
|
|
63
65
|
if (this.loading)
|
|
64
66
|
this.refresh();
|
|
@@ -66,7 +68,7 @@ export class QueryState extends State {
|
|
|
66
68
|
async _refresh() {
|
|
67
69
|
this.busy.set(true);
|
|
68
70
|
try {
|
|
69
|
-
const items = await this.ref.
|
|
71
|
+
const items = await this.ref.items;
|
|
70
72
|
this._hasMore = items.length >= this.limit; // If the query returned {limit} or more items, we can assume there are more items waiting to be queried.
|
|
71
73
|
this.set(items);
|
|
72
74
|
}
|
|
@@ -89,10 +91,10 @@ export class QueryState extends State {
|
|
|
89
91
|
async _loadMore() {
|
|
90
92
|
this.busy.set(true);
|
|
91
93
|
try {
|
|
92
|
-
const last = this.
|
|
93
|
-
const
|
|
94
|
-
const items = await
|
|
95
|
-
this.set([...this.
|
|
94
|
+
const last = this.last;
|
|
95
|
+
const ref = last ? this.ref.with(getAfterQuery(this.ref.query, last)) : this.ref;
|
|
96
|
+
const items = await ref.items;
|
|
97
|
+
this.set([...this.items, ...items]);
|
|
96
98
|
this._hasMore = items.length >= this.limit; // If the query returned {limit} or more items, we can assume there are more items waiting to be queried.
|
|
97
99
|
}
|
|
98
100
|
catch (thrown) {
|
package/db/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./Database.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
2
|
+
export * from "./CollectionReference.js";
|
|
3
|
+
export * from "./ItemReference.js";
|
|
4
4
|
export * from "./ItemState.js";
|
|
5
|
-
export * from "./
|
|
5
|
+
export * from "./QueryReference.js";
|
|
6
6
|
export * from "./QueryState.js";
|
|
7
7
|
export * from "./Change.js";
|
package/db/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./Database.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
2
|
+
export * from "./CollectionReference.js";
|
|
3
|
+
export * from "./ItemReference.js";
|
|
4
4
|
export * from "./ItemState.js";
|
|
5
|
-
export * from "./
|
|
5
|
+
export * from "./QueryReference.js";
|
|
6
6
|
export * from "./QueryState.js";
|
|
7
7
|
export * from "./Change.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ItemArray,
|
|
1
|
+
import type { ItemArray, ItemQuery, ItemValue } from "../../db/ItemReference.js";
|
|
2
2
|
import type { AsyncProvider } from "../../provider/Provider.js";
|
|
3
|
-
import type { Updates } from "../../update/DataUpdate.js";
|
|
4
3
|
import type { Data } from "../../util/data.js";
|
|
4
|
+
import type { Updates } from "../../util/update.js";
|
|
5
5
|
import type { Firestore } from "firebase/firestore";
|
|
6
6
|
/**
|
|
7
7
|
* Firestore client database provider.
|
|
@@ -12,15 +12,15 @@ import type { Firestore } from "firebase/firestore";
|
|
|
12
12
|
export declare class FirestoreClientProvider implements AsyncProvider {
|
|
13
13
|
private readonly _firestore;
|
|
14
14
|
constructor(firestore: Firestore);
|
|
15
|
-
getItem(
|
|
16
|
-
getItemSequence(
|
|
17
|
-
addItem(
|
|
18
|
-
setItem(
|
|
19
|
-
updateItem(
|
|
20
|
-
deleteItem(
|
|
21
|
-
getQuery(
|
|
22
|
-
getQuerySequence(
|
|
23
|
-
setQuery(
|
|
24
|
-
updateQuery(
|
|
25
|
-
deleteQuery(
|
|
15
|
+
getItem(c: string, id: string): Promise<ItemValue>;
|
|
16
|
+
getItemSequence(c: string, id: string): AsyncIterable<ItemValue>;
|
|
17
|
+
addItem(c: string, data: Data): Promise<string>;
|
|
18
|
+
setItem(c: string, id: string, data: Data): Promise<void>;
|
|
19
|
+
updateItem(c: string, id: string, updates: Updates): Promise<void>;
|
|
20
|
+
deleteItem(c: string, id: string): Promise<void>;
|
|
21
|
+
getQuery(c: string, q: ItemQuery): Promise<ItemArray>;
|
|
22
|
+
getQuerySequence(c: string, q: ItemQuery): AsyncIterable<ItemArray>;
|
|
23
|
+
setQuery(c: string, q: ItemQuery, data: Data): Promise<number>;
|
|
24
|
+
updateQuery(c: string, q: ItemQuery, updates: Updates): Promise<number>;
|
|
25
|
+
deleteQuery(c: string, q: ItemQuery): Promise<number>;
|
|
26
26
|
}
|
|
@@ -1,41 +1,38 @@
|
|
|
1
|
-
import { addDoc,
|
|
1
|
+
import { addDoc, collection, deleteDoc, doc, documentId, getDoc, getDocs, increment, limit, onSnapshot, orderBy, query, setDoc, updateDoc, where } from "firebase/firestore";
|
|
2
2
|
import { LazyDeferredSequence } from "../../sequence/LazyDeferredSequence.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { Increment } from "../../update/Increment.js";
|
|
8
|
-
import { Update } from "../../update/Update.js";
|
|
3
|
+
import { getObject } from "../../util/object.js";
|
|
4
|
+
import { getFilters, getSorts } from "../../util/query.js";
|
|
5
|
+
import { mapItems } from "../../util/transform.js";
|
|
6
|
+
import { getUpdates } from "../../util/update.js";
|
|
9
7
|
// Constants.
|
|
10
|
-
const ID =
|
|
8
|
+
const ID = documentId();
|
|
11
9
|
// Map `Filter.types` to `WhereFilterOp`
|
|
12
10
|
const OPERATORS = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
// Map `Filter.types` to `OrderByDirection`
|
|
24
|
-
const DIRECTIONS = {
|
|
25
|
-
ASC: "asc",
|
|
26
|
-
DESC: "desc",
|
|
11
|
+
is: "==",
|
|
12
|
+
not: "!=",
|
|
13
|
+
in: "in",
|
|
14
|
+
out: "not-in",
|
|
15
|
+
contains: "array-contains",
|
|
16
|
+
gt: ">",
|
|
17
|
+
gte: ">=",
|
|
18
|
+
lt: "<",
|
|
19
|
+
lte: "<=",
|
|
27
20
|
};
|
|
28
21
|
/** Get a Firestore QueryReference for a given query. */
|
|
29
|
-
function _getQuery(firestore,
|
|
30
|
-
return
|
|
22
|
+
function _getQuery(firestore, c, q) {
|
|
23
|
+
return query(collection(firestore, c), ..._getConstraints(q));
|
|
31
24
|
}
|
|
32
|
-
function*
|
|
33
|
-
for (const {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
function* _getConstraints(q) {
|
|
26
|
+
for (const { keys, direction } of getSorts(q)) {
|
|
27
|
+
const key = keys.join(".");
|
|
28
|
+
yield orderBy(key === "id" ? ID : key, direction);
|
|
29
|
+
}
|
|
30
|
+
for (const { keys, operator, value } of getFilters(q)) {
|
|
31
|
+
const key = keys.join(".");
|
|
32
|
+
yield where(key === "id" ? ID : key, OPERATORS[operator], value);
|
|
33
|
+
}
|
|
34
|
+
if (typeof q.$limit === "number")
|
|
35
|
+
yield limit(q.$limit);
|
|
39
36
|
}
|
|
40
37
|
function _getItems(snapshot) {
|
|
41
38
|
return snapshot.docs.map(_getItemData);
|
|
@@ -48,35 +45,9 @@ function _getItemValue(snapshot) {
|
|
|
48
45
|
const data = snapshot.data();
|
|
49
46
|
return data ? { ...data, id: snapshot.id } : null;
|
|
50
47
|
}
|
|
51
|
-
/** Convert `
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (update instanceof DataUpdate || update instanceof DictionaryUpdate) {
|
|
55
|
-
yield* _getFieldValues(update, `${prefix}${key}.`);
|
|
56
|
-
}
|
|
57
|
-
else if (update instanceof ArrayUpdate) {
|
|
58
|
-
if (update.adds.length) {
|
|
59
|
-
yield `${prefix}${key}`;
|
|
60
|
-
yield firestoreArrayUnion(...update.adds);
|
|
61
|
-
}
|
|
62
|
-
if (update.deletes.length) {
|
|
63
|
-
yield `${prefix}${key}`;
|
|
64
|
-
yield firestoreArrayRemove(...update.deletes);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
yield `${prefix}${key}`;
|
|
69
|
-
if (!(update instanceof Update))
|
|
70
|
-
yield update;
|
|
71
|
-
else if (update instanceof Delete)
|
|
72
|
-
yield firestoreDeleteField();
|
|
73
|
-
else if (update instanceof Increment)
|
|
74
|
-
yield firestoreIncrement(update.amount);
|
|
75
|
-
else
|
|
76
|
-
yield update.transform();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
48
|
+
/** Convert `Updates` object into corresponding Firestore `FieldValue` instances. */
|
|
49
|
+
const _getFieldValues = (updates) => getObject(mapItems(getUpdates(updates), _getFieldValue));
|
|
50
|
+
const _getFieldValue = ({ keys, action, value }) => [keys.join("."), action === "sum" ? increment(value) : action === "set" ? value : action];
|
|
80
51
|
/**
|
|
81
52
|
* Firestore client database provider.
|
|
82
53
|
* - Works with the Firebase JS SDK.
|
|
@@ -87,48 +58,48 @@ export class FirestoreClientProvider {
|
|
|
87
58
|
constructor(firestore) {
|
|
88
59
|
this._firestore = firestore;
|
|
89
60
|
}
|
|
90
|
-
async getItem(
|
|
91
|
-
return _getItemValue(await getDoc(
|
|
61
|
+
async getItem(c, id) {
|
|
62
|
+
return _getItemValue(await getDoc(doc(this._firestore, c, id)));
|
|
92
63
|
}
|
|
93
|
-
getItemSequence(
|
|
94
|
-
return new LazyDeferredSequence(({ resolve, reject }) => onSnapshot(
|
|
64
|
+
getItemSequence(c, id) {
|
|
65
|
+
return new LazyDeferredSequence(({ resolve, reject }) => onSnapshot(doc(this._firestore, c, id), //
|
|
95
66
|
//
|
|
96
67
|
snapshot => resolve(_getItemValue(snapshot)), reject));
|
|
97
68
|
}
|
|
98
|
-
async addItem(
|
|
99
|
-
const reference = await addDoc(
|
|
69
|
+
async addItem(c, data) {
|
|
70
|
+
const reference = await addDoc(collection(this._firestore, c), data);
|
|
100
71
|
return reference.id;
|
|
101
72
|
}
|
|
102
|
-
async setItem(
|
|
103
|
-
await setDoc(
|
|
73
|
+
async setItem(c, id, data) {
|
|
74
|
+
await setDoc(doc(this._firestore, c, id), data);
|
|
104
75
|
}
|
|
105
|
-
async updateItem(
|
|
106
|
-
await updateDoc(
|
|
76
|
+
async updateItem(c, id, updates) {
|
|
77
|
+
await updateDoc(doc(this._firestore, c, id), _getFieldValues(updates));
|
|
107
78
|
}
|
|
108
|
-
async deleteItem(
|
|
109
|
-
await deleteDoc(
|
|
79
|
+
async deleteItem(c, id) {
|
|
80
|
+
await deleteDoc(doc(this._firestore, c, id));
|
|
110
81
|
}
|
|
111
|
-
async getQuery(
|
|
112
|
-
return _getItems(await getDocs(_getQuery(this._firestore,
|
|
82
|
+
async getQuery(c, q) {
|
|
83
|
+
return _getItems(await getDocs(_getQuery(this._firestore, c, q)));
|
|
113
84
|
}
|
|
114
|
-
getQuerySequence(
|
|
115
|
-
return new LazyDeferredSequence(({ resolve, reject }) => onSnapshot(_getQuery(this._firestore,
|
|
85
|
+
getQuerySequence(c, q) {
|
|
86
|
+
return new LazyDeferredSequence(({ resolve, reject }) => onSnapshot(_getQuery(this._firestore, c, q), //
|
|
116
87
|
//
|
|
117
88
|
snapshot => resolve(_getItems(snapshot)), reject));
|
|
118
89
|
}
|
|
119
|
-
async setQuery(
|
|
120
|
-
const snapshot = await getDocs(_getQuery(this._firestore,
|
|
90
|
+
async setQuery(c, q, data) {
|
|
91
|
+
const snapshot = await getDocs(_getQuery(this._firestore, c, q));
|
|
121
92
|
await Promise.all(snapshot.docs.map(s => setDoc(s.ref, data)));
|
|
122
93
|
return snapshot.size;
|
|
123
94
|
}
|
|
124
|
-
async updateQuery(
|
|
125
|
-
const snapshot = await getDocs(_getQuery(this._firestore,
|
|
126
|
-
const fieldValues =
|
|
127
|
-
await Promise.all(snapshot.docs.map(s => updateDoc(s.ref,
|
|
95
|
+
async updateQuery(c, q, updates) {
|
|
96
|
+
const snapshot = await getDocs(_getQuery(this._firestore, c, q));
|
|
97
|
+
const fieldValues = _getFieldValues(updates);
|
|
98
|
+
await Promise.all(snapshot.docs.map(s => updateDoc(s.ref, fieldValues)));
|
|
128
99
|
return snapshot.size;
|
|
129
100
|
}
|
|
130
|
-
async deleteQuery(
|
|
131
|
-
const snapshot = await getDocs(_getQuery(this._firestore,
|
|
101
|
+
async deleteQuery(c, q) {
|
|
102
|
+
const snapshot = await getDocs(_getQuery(this._firestore, c, q));
|
|
132
103
|
await Promise.all(snapshot.docs.map(s => deleteDoc(s.ref)));
|
|
133
104
|
return snapshot.size;
|
|
134
105
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ItemArray,
|
|
1
|
+
import type { ItemArray, ItemQuery, ItemValue } from "../../db/ItemReference.js";
|
|
2
2
|
import type { AsyncProvider } from "../../provider/Provider.js";
|
|
3
|
-
import type { Updates } from "../../update/DataUpdate.js";
|
|
4
3
|
import type { Data } from "../../util/data.js";
|
|
4
|
+
import type { Updates } from "../../util/update.js";
|
|
5
5
|
import type { Firestore } from "firebase/firestore/lite";
|
|
6
6
|
/**
|
|
7
7
|
* Firestore Lite client database provider.
|
|
@@ -12,15 +12,15 @@ import type { Firestore } from "firebase/firestore/lite";
|
|
|
12
12
|
export declare class FirestoreLiteProvider implements AsyncProvider {
|
|
13
13
|
private readonly _firestore;
|
|
14
14
|
constructor(firestore: Firestore);
|
|
15
|
-
getItem(
|
|
15
|
+
getItem(c: string, id: string): Promise<ItemValue>;
|
|
16
16
|
getItemSequence(): AsyncIterableIterator<ItemValue>;
|
|
17
|
-
addItem(
|
|
18
|
-
setItem(
|
|
19
|
-
updateItem(
|
|
20
|
-
deleteItem(
|
|
21
|
-
getQuery(
|
|
17
|
+
addItem(c: string, data: Data): Promise<string>;
|
|
18
|
+
setItem(c: string, id: string, data: Data): Promise<void>;
|
|
19
|
+
updateItem(c: string, id: string, updates: Updates): Promise<void>;
|
|
20
|
+
deleteItem(c: string, id: string): Promise<void>;
|
|
21
|
+
getQuery(c: string, q: ItemQuery): Promise<ItemArray>;
|
|
22
22
|
getQuerySequence(): AsyncIterableIterator<ItemArray>;
|
|
23
|
-
setQuery(
|
|
24
|
-
updateQuery(
|
|
25
|
-
deleteQuery(
|
|
23
|
+
setQuery(c: string, q: ItemQuery, data: Data): Promise<number>;
|
|
24
|
+
updateQuery(c: string, q: ItemQuery, updates: Updates): Promise<number>;
|
|
25
|
+
deleteQuery(c: string, q: ItemQuery): Promise<number>;
|
|
26
26
|
}
|