shelving 1.22.1 → 1.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/db/Database.d.ts +22 -46
- package/db/Database.js +35 -49
- package/db/Pagination.js +1 -1
- package/db/Write.d.ts +30 -0
- package/db/Write.js +37 -0
- package/db/index.d.ts +1 -1
- package/db/index.js +1 -1
- package/firestore/client/FirestoreClientProvider.d.ts +3 -3
- package/firestore/client/FirestoreClientProvider.js +2 -2
- package/firestore/lite/FirestoreLiteProvider.d.ts +3 -3
- package/firestore/server/FirestoreServerProvider.d.ts +3 -3
- package/firestore/server/FirestoreServerProvider.js +2 -2
- package/package.json +1 -1
- package/provider/BatchProvider.js +2 -2
- package/provider/CacheProvider.js +3 -3
- package/provider/MemoryProvider.js +20 -20
- package/query/Filter.d.ts +1 -1
- package/query/Filter.js +1 -1
- package/query/Filters.d.ts +1 -1
- package/query/Filters.js +1 -1
- package/query/Query.d.ts +1 -1
- package/query/Query.js +2 -2
- package/query/Rule.d.ts +3 -3
- package/query/Sort.d.ts +1 -1
- package/query/Sort.js +1 -1
- package/query/Sorts.d.ts +1 -1
- package/query/Sorts.js +1 -1
- package/react/useDocument.js +3 -3
- package/react/useFetch.js +2 -2
- package/react/usePureState.d.ts +4 -4
- package/react/useQuery.js +4 -4
- package/react/useSubscribe.js +1 -1
- package/stream/DataState.d.ts +2 -2
- package/stream/DataState.js +2 -2
- package/stream/LastStream.js +1 -1
- package/stream/LazyState.d.ts +1 -1
- package/stream/LazyState.js +4 -4
- package/stream/LazyStream.d.ts +1 -1
- package/stream/LazyStream.js +5 -5
- package/stream/State.d.ts +5 -5
- package/stream/State.js +6 -6
- package/stream/Stream.d.ts +13 -13
- package/stream/Stream.js +25 -25
- package/transform/AddEntriesTransform.d.ts +1 -1
- package/transform/AddEntriesTransform.js +1 -1
- package/transform/AddItemsTransform.d.ts +1 -1
- package/transform/AddItemsTransform.js +1 -1
- package/transform/DataTransform.d.ts +1 -1
- package/transform/DataTransform.js +3 -3
- package/transform/IncrementTransform.d.ts +1 -1
- package/transform/IncrementTransform.js +1 -1
- package/transform/RemoveEntriesTransform.d.ts +1 -1
- package/transform/RemoveEntriesTransform.js +1 -1
- package/transform/RemoveItemsTransform.d.ts +1 -1
- package/transform/RemoveItemsTransform.js +1 -1
- package/transform/Transform.d.ts +3 -3
- package/transform/hydrations.d.ts +1 -1
- package/transform/hydrations.js +1 -1
- package/transform/util.js +2 -2
- package/util/async.d.ts +6 -6
- package/util/clone.js +3 -3
- package/util/error.js +1 -1
- package/util/filter.d.ts +4 -4
- package/util/filter.js +5 -5
- package/util/function.d.ts +8 -0
- package/util/function.js +19 -0
- package/util/hydrate.d.ts +7 -7
- package/util/hydrate.js +13 -13
- package/util/index.d.ts +2 -3
- package/util/index.js +2 -3
- package/util/observable.d.ts +15 -19
- package/util/observable.js +22 -28
- package/util/sort.d.ts +4 -4
- package/util/sort.js +5 -6
- package/util/transform.d.ts +88 -0
- package/util/transform.js +48 -0
- package/db/Change.d.ts +0 -37
- package/db/Change.js +0 -60
- package/util/derive.d.ts +0 -88
- package/util/derive.js +0 -48
- package/util/dispatch.d.ts +0 -29
- package/util/dispatch.js +0 -43
package/db/Database.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Entry, Observable, Observer, Result, Unsubscriber, ResultsMap, Validatable, Validator, Key, Data, Results, Datas, Validators, ValidatorType, Dispatcher } from "../util/index.js";
|
|
2
2
|
import { Transform, Transforms } from "../transform/index.js";
|
|
3
3
|
import type { Provider } from "../provider/Provider.js";
|
|
4
4
|
import { Filters, Sorts, Query } from "../query/index.js";
|
|
5
|
+
import { DocumentWrite, Write } from "./Write.js";
|
|
5
6
|
/**
|
|
6
7
|
* Combines a database model and a provider.
|
|
7
8
|
*
|
|
@@ -17,6 +18,8 @@ export declare class Database<V extends Validators<Datas> = Validators<Datas>> {
|
|
|
17
18
|
query<K extends Key<V>>(collection: K, filters?: Filters<ValidatorType<V[K]>>, sorts?: Sorts<ValidatorType<V[K]>>, limit?: number | null): DataQuery<ValidatorType<V[K]>>;
|
|
18
19
|
/** Reference a document in a collection in this model. */
|
|
19
20
|
doc<K extends Key<V>>(collection: K, id: string): DataDocument<ValidatorType<V[K]>>;
|
|
21
|
+
/** Perform a write on this database. */
|
|
22
|
+
write(write: Write): void | PromiseLike<void>;
|
|
20
23
|
}
|
|
21
24
|
/** A documents reference within a specific database. */
|
|
22
25
|
export declare class DataQuery<T extends Data = Data> extends Query<T> implements Observable<Results<T>>, Validatable<Results<T>>, Iterable<Entry<T>> {
|
|
@@ -58,26 +61,18 @@ export declare class DataQuery<T extends Data = Data> extends Query<T> implement
|
|
|
58
61
|
* Subscribe to all matching documents.
|
|
59
62
|
* - `next()` is called once with the initial results, and again any time the results change.
|
|
60
63
|
*
|
|
61
|
-
* @param
|
|
62
|
-
* @param next Callback that is called once initially and again whenever the results change.
|
|
63
|
-
* @param error Callback that is called if an error occurs.
|
|
64
|
-
* @param complete Callback that is called when the subscription is done.
|
|
65
|
-
*
|
|
64
|
+
* @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
|
|
66
65
|
* @return Function that ends the subscription.
|
|
67
66
|
*/
|
|
68
|
-
subscribe(next: Observer<Results<T>> | Dispatcher<Results<T
|
|
67
|
+
subscribe(next: Observer<Results<T>> | Dispatcher<[Results<T>]>): Unsubscriber;
|
|
69
68
|
/**
|
|
70
69
|
* Subscribe to all matching documents.
|
|
71
70
|
* - `next()` is called once with the initial results, and again any time the results change.
|
|
72
71
|
*
|
|
73
|
-
* @param
|
|
74
|
-
* @param next Callback that is called once initially and again whenever the results change.
|
|
75
|
-
* @param error Callback that is called if an error occurs.
|
|
76
|
-
* @param complete Callback that is called when the subscription is done.
|
|
77
|
-
*
|
|
72
|
+
* @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
|
|
78
73
|
* @return Function that ends the subscription.
|
|
79
74
|
*/
|
|
80
|
-
subscribeMap(next: Observer<ResultsMap<T>> | Dispatcher<ResultsMap<T
|
|
75
|
+
subscribeMap(next: Observer<ResultsMap<T>> | Dispatcher<[ResultsMap<T>]>): Unsubscriber;
|
|
81
76
|
/**
|
|
82
77
|
* Set all matching documents to the same exact value.
|
|
83
78
|
*
|
|
@@ -145,45 +140,26 @@ export declare class DataDocument<T extends Data = Data> implements Observable<R
|
|
|
145
140
|
* Subscribe to the result of this document (indefinitely).
|
|
146
141
|
* - `next()` is called once with the initial result, and again any time the result changes.
|
|
147
142
|
*
|
|
148
|
-
* @param
|
|
149
|
-
* @param next Callback that is called once initially and again whenever the result changes.
|
|
150
|
-
* @param error Callback that is called if an error occurs.
|
|
151
|
-
* @param complete Callback that is called when the subscription is done.
|
|
152
|
-
*
|
|
143
|
+
* @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
|
|
153
144
|
* @return Function that ends the subscription.
|
|
154
145
|
*/
|
|
155
|
-
subscribe(next: Observer<Result<T>> | Dispatcher<Result<T
|
|
156
|
-
/**
|
|
157
|
-
* Set the complete data of this document.
|
|
158
|
-
*
|
|
159
|
-
* @param data Complete data to set the document to.
|
|
160
|
-
*
|
|
161
|
-
* @return Nothing (possibly promised).
|
|
162
|
-
*/
|
|
146
|
+
subscribe(next: Observer<Result<T>> | Dispatcher<[Result<T>]>): Unsubscriber;
|
|
147
|
+
/** Set the complete data of this document. */
|
|
163
148
|
set(data: T): void | PromiseLike<void>;
|
|
164
|
-
/**
|
|
165
|
-
* Update this document with partial data.
|
|
166
|
-
* - If the document exists, merge the partial data into it.
|
|
167
|
-
* - If the document doesn't exist, throw an error.
|
|
168
|
-
*
|
|
169
|
-
* @param transforms `Transform` instance or set of transforms to apply to the existing document.
|
|
170
|
-
* - Not all transforms may be supported by all providers.
|
|
171
|
-
*
|
|
172
|
-
* @return Nothing (possibly promised).
|
|
173
|
-
* @throws Error If the document does not exist (ideally a `RequiredError` but may be provider-specific).
|
|
174
|
-
*/
|
|
149
|
+
/** Update this document. */
|
|
175
150
|
update(transforms: Transform<T> | Transforms<T>): void | PromiseLike<void>;
|
|
176
|
-
/**
|
|
177
|
-
* Delete this document.
|
|
178
|
-
* - Will not throw an error if the document doesn't exist.
|
|
179
|
-
*
|
|
180
|
-
* @return Nothing (possibly promised).
|
|
181
|
-
*/
|
|
151
|
+
/** Delete this document. */
|
|
182
152
|
delete(): void | PromiseLike<void>;
|
|
183
|
-
/**
|
|
184
|
-
* Combine `set()`, `update()`, `delete()` into a single method.
|
|
185
|
-
*/
|
|
153
|
+
/** Set, update, or delete this document. */
|
|
186
154
|
write(value: Result<T> | Transform<T>): void | PromiseLike<void>;
|
|
155
|
+
/** Represent a write that sets the complete data of this document in a database. */
|
|
156
|
+
setter(data: T): DocumentWrite<T>;
|
|
157
|
+
/** Represent a write that updates this document in a database. */
|
|
158
|
+
updater(transforms: Transform<T> | Transforms<T>): DocumentWrite<T>;
|
|
159
|
+
/** Represent a write that deletes this document in a database. */
|
|
160
|
+
deleter(): DocumentWrite<T>;
|
|
161
|
+
/** Represent a write that sets, updates, or deletes this document in a database. */
|
|
162
|
+
writer(value: Result<T> | Transform<T>): DocumentWrite<T>;
|
|
187
163
|
/** Validate data for this query reference. */
|
|
188
164
|
validate(unsafeData: Data): T;
|
|
189
165
|
toString(): string;
|
package/db/Database.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { callAsync,
|
|
1
|
+
import { callAsync, getFirstItem, throwAsync, validate, toMap, countItems, TransformObserver, } from "../util/index.js";
|
|
2
2
|
import { DataTransform, Transform } from "../transform/index.js";
|
|
3
3
|
import { Feedback, InvalidFeedback } from "../feedback/index.js";
|
|
4
4
|
import { Filters, Query, EqualFilter } from "../query/index.js";
|
|
5
5
|
import { DocumentRequiredError, DocumentValidationError, QueryValidationError } from "./errors.js";
|
|
6
|
+
import { DocumentWrite } from "./Write.js";
|
|
6
7
|
/**
|
|
7
8
|
* Combines a database model and a provider.
|
|
8
9
|
*
|
|
@@ -24,6 +25,10 @@ export class Database {
|
|
|
24
25
|
doc(collection, id) {
|
|
25
26
|
return new DataDocument(this.provider, this.validators[collection], collection, id);
|
|
26
27
|
}
|
|
28
|
+
/** Perform a write on this database. */
|
|
29
|
+
write(write) {
|
|
30
|
+
return write.transform(this);
|
|
31
|
+
}
|
|
27
32
|
}
|
|
28
33
|
/** A documents reference within a specific database. */
|
|
29
34
|
export class DataQuery extends Query {
|
|
@@ -79,29 +84,21 @@ export class DataQuery extends Query {
|
|
|
79
84
|
* Subscribe to all matching documents.
|
|
80
85
|
* - `next()` is called once with the initial results, and again any time the results change.
|
|
81
86
|
*
|
|
82
|
-
* @param
|
|
83
|
-
* @param next Callback that is called once initially and again whenever the results change.
|
|
84
|
-
* @param error Callback that is called if an error occurs.
|
|
85
|
-
* @param complete Callback that is called when the subscription is done.
|
|
86
|
-
*
|
|
87
|
+
* @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
|
|
87
88
|
* @return Function that ends the subscription.
|
|
88
89
|
*/
|
|
89
|
-
subscribe(next
|
|
90
|
-
return this.provider.subscribeQuery(this,
|
|
90
|
+
subscribe(next) {
|
|
91
|
+
return this.provider.subscribeQuery(this, typeof next === "function" ? { next } : next);
|
|
91
92
|
}
|
|
92
93
|
/**
|
|
93
94
|
* Subscribe to all matching documents.
|
|
94
95
|
* - `next()` is called once with the initial results, and again any time the results change.
|
|
95
96
|
*
|
|
96
|
-
* @param
|
|
97
|
-
* @param next Callback that is called once initially and again whenever the results change.
|
|
98
|
-
* @param error Callback that is called if an error occurs.
|
|
99
|
-
* @param complete Callback that is called when the subscription is done.
|
|
100
|
-
*
|
|
97
|
+
* @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
|
|
101
98
|
* @return Function that ends the subscription.
|
|
102
99
|
*/
|
|
103
|
-
subscribeMap(next
|
|
104
|
-
return this.provider.subscribeQuery(this, new
|
|
100
|
+
subscribeMap(next) {
|
|
101
|
+
return this.provider.subscribeQuery(this, new TransformObserver(toMap, typeof next === "function" ? { next } : next));
|
|
105
102
|
}
|
|
106
103
|
/**
|
|
107
104
|
* Set all matching documents to the same exact value.
|
|
@@ -210,55 +207,44 @@ export class DataDocument {
|
|
|
210
207
|
* Subscribe to the result of this document (indefinitely).
|
|
211
208
|
* - `next()` is called once with the initial result, and again any time the result changes.
|
|
212
209
|
*
|
|
213
|
-
* @param
|
|
214
|
-
* @param next Callback that is called once initially and again whenever the result changes.
|
|
215
|
-
* @param error Callback that is called if an error occurs.
|
|
216
|
-
* @param complete Callback that is called when the subscription is done.
|
|
217
|
-
*
|
|
210
|
+
* @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
|
|
218
211
|
* @return Function that ends the subscription.
|
|
219
212
|
*/
|
|
220
|
-
subscribe(next
|
|
221
|
-
return this.provider.subscribe(this,
|
|
213
|
+
subscribe(next) {
|
|
214
|
+
return this.provider.subscribe(this, typeof next === "function" ? { next } : next);
|
|
222
215
|
}
|
|
223
|
-
/**
|
|
224
|
-
* Set the complete data of this document.
|
|
225
|
-
*
|
|
226
|
-
* @param data Complete data to set the document to.
|
|
227
|
-
*
|
|
228
|
-
* @return Nothing (possibly promised).
|
|
229
|
-
*/
|
|
216
|
+
/** Set the complete data of this document. */
|
|
230
217
|
set(data) {
|
|
231
218
|
return this.write(data);
|
|
232
219
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Update this document with partial data.
|
|
235
|
-
* - If the document exists, merge the partial data into it.
|
|
236
|
-
* - If the document doesn't exist, throw an error.
|
|
237
|
-
*
|
|
238
|
-
* @param transforms `Transform` instance or set of transforms to apply to the existing document.
|
|
239
|
-
* - Not all transforms may be supported by all providers.
|
|
240
|
-
*
|
|
241
|
-
* @return Nothing (possibly promised).
|
|
242
|
-
* @throws Error If the document does not exist (ideally a `RequiredError` but may be provider-specific).
|
|
243
|
-
*/
|
|
220
|
+
/** Update this document. */
|
|
244
221
|
update(transforms) {
|
|
245
222
|
return this.write(transforms instanceof Transform ? transforms : new DataTransform(transforms));
|
|
246
223
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Delete this document.
|
|
249
|
-
* - Will not throw an error if the document doesn't exist.
|
|
250
|
-
*
|
|
251
|
-
* @return Nothing (possibly promised).
|
|
252
|
-
*/
|
|
224
|
+
/** Delete this document. */
|
|
253
225
|
delete() {
|
|
254
226
|
return this.write(undefined);
|
|
255
227
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Combine `set()`, `update()`, `delete()` into a single method.
|
|
258
|
-
*/
|
|
228
|
+
/** Set, update, or delete this document. */
|
|
259
229
|
write(value) {
|
|
260
230
|
return this.provider.write(this, value);
|
|
261
231
|
}
|
|
232
|
+
/** Represent a write that sets the complete data of this document in a database. */
|
|
233
|
+
setter(data) {
|
|
234
|
+
return this.writer(data);
|
|
235
|
+
}
|
|
236
|
+
/** Represent a write that updates this document in a database. */
|
|
237
|
+
updater(transforms) {
|
|
238
|
+
return this.writer(transforms instanceof Transform ? transforms : new DataTransform(transforms));
|
|
239
|
+
}
|
|
240
|
+
/** Represent a write that deletes this document in a database. */
|
|
241
|
+
deleter() {
|
|
242
|
+
return this.writer(undefined);
|
|
243
|
+
}
|
|
244
|
+
/** Represent a write that sets, updates, or deletes this document in a database. */
|
|
245
|
+
writer(value) {
|
|
246
|
+
return new DocumentWrite(this, value);
|
|
247
|
+
}
|
|
262
248
|
/** Validate data for this query reference. */
|
|
263
249
|
validate(unsafeData) {
|
|
264
250
|
try {
|
package/db/Pagination.js
CHANGED
|
@@ -71,7 +71,7 @@ export class Pagination extends State {
|
|
|
71
71
|
* @return The change in the number of results.
|
|
72
72
|
*/
|
|
73
73
|
merge(more) {
|
|
74
|
-
this.next(toMap(this.ref.sorts.
|
|
74
|
+
this.next(toMap(this.ref.sorts.transform(yieldMerged(more, this.value))));
|
|
75
75
|
}
|
|
76
76
|
/** Iterate over the entries of the values currently in the pagination. */
|
|
77
77
|
[Symbol.iterator]() {
|
package/db/Write.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Transform } from "../transform/index.js";
|
|
2
|
+
import { ImmutableArray, Data, Transformable } from "../util/index.js";
|
|
3
|
+
import type { Database, DataDocument } from "./Database.js";
|
|
4
|
+
/** Write to a database. */
|
|
5
|
+
export declare abstract class Write implements Transformable<Database, void | PromiseLike<void>> {
|
|
6
|
+
abstract transform(db: Database): void | PromiseLike<void>;
|
|
7
|
+
}
|
|
8
|
+
/** Represent a write made to a single document in a database. */
|
|
9
|
+
export declare class DocumentWrite<T extends Data> extends Write {
|
|
10
|
+
readonly collection: string;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly value: Data | Transform<Data> | undefined;
|
|
13
|
+
constructor({ collection, id }: DataDocument<T>, value: T | Transform<T> | undefined);
|
|
14
|
+
transform(db: Database): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Represent a list of writes made to a database.
|
|
18
|
+
* - Sets of writes are predictable and repeatable, so unpredictable operations like `create()` and query operations are not supported.
|
|
19
|
+
* - Every write must be applied to a specific database document in a specific collection and are applied in the specified order.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Writes extends Write {
|
|
22
|
+
readonly writes: ImmutableArray<Write>;
|
|
23
|
+
constructor(...writes: Write[]);
|
|
24
|
+
transform(db: Database): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/** Set of hydrations for all change classes. */
|
|
27
|
+
export declare const WRITE_HYDRATIONS: {
|
|
28
|
+
writes: typeof Writes;
|
|
29
|
+
write: typeof DocumentWrite;
|
|
30
|
+
};
|
package/db/Write.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { transform } from "../util/index.js";
|
|
2
|
+
/** Write to a database. */
|
|
3
|
+
export class Write {
|
|
4
|
+
}
|
|
5
|
+
/** Represent a write made to a single document in a database. */
|
|
6
|
+
export class DocumentWrite extends Write {
|
|
7
|
+
constructor({ collection, id }, value) {
|
|
8
|
+
super();
|
|
9
|
+
this.collection = collection;
|
|
10
|
+
this.id = id;
|
|
11
|
+
this.value = value;
|
|
12
|
+
}
|
|
13
|
+
async transform(db) {
|
|
14
|
+
await db.doc(this.collection, this.id).write(this.value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Represent a list of writes made to a database.
|
|
19
|
+
* - Sets of writes are predictable and repeatable, so unpredictable operations like `create()` and query operations are not supported.
|
|
20
|
+
* - Every write must be applied to a specific database document in a specific collection and are applied in the specified order.
|
|
21
|
+
*/
|
|
22
|
+
export class Writes extends Write {
|
|
23
|
+
constructor(...writes) {
|
|
24
|
+
super();
|
|
25
|
+
this.writes = writes;
|
|
26
|
+
}
|
|
27
|
+
async transform(db) {
|
|
28
|
+
for (const writes of this.writes)
|
|
29
|
+
await transform(db, writes);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Set of hydrations for all change classes. */
|
|
33
|
+
export const WRITE_HYDRATIONS = {
|
|
34
|
+
writes: Writes,
|
|
35
|
+
write: DocumentWrite,
|
|
36
|
+
};
|
|
37
|
+
WRITE_HYDRATIONS;
|
package/db/index.d.ts
CHANGED
package/db/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Firestore } from "firebase/firestore";
|
|
2
|
-
import { Results, Provider, DataDocument, DataQuery, Result, Observer, Transform, AsynchronousProvider, Data } from "../../index.js";
|
|
2
|
+
import { Results, Provider, DataDocument, DataQuery, Result, Observer, Transform, AsynchronousProvider, Data, Unsubscriber } from "../../index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Firestore client database provider.
|
|
5
5
|
* - Works with the Firebase JS SDK.
|
|
@@ -10,10 +10,10 @@ export declare class FirestoreClientProvider extends Provider implements Asynchr
|
|
|
10
10
|
readonly firestore: Firestore;
|
|
11
11
|
constructor(firestore: Firestore);
|
|
12
12
|
get<T extends Data>(ref: DataDocument<T>): Promise<Result<T>>;
|
|
13
|
-
subscribe<T extends Data>(ref: DataDocument<T>, observer: Observer<Result<T>>):
|
|
13
|
+
subscribe<T extends Data>(ref: DataDocument<T>, observer: Observer<Result<T>>): Unsubscriber;
|
|
14
14
|
add<T extends Data>(ref: DataQuery<T>, data: T): Promise<string>;
|
|
15
15
|
write<T extends Data>(ref: DataDocument<T>, value: T | Transform<T> | undefined): Promise<void>;
|
|
16
16
|
getQuery<T extends Data>(ref: DataQuery<T>): Promise<Results<T>>;
|
|
17
|
-
subscribeQuery<T extends Data>(ref: DataQuery<T>, observer: Observer<Results<T>>):
|
|
17
|
+
subscribeQuery<T extends Data>(ref: DataQuery<T>, observer: Observer<Results<T>>): Unsubscriber;
|
|
18
18
|
writeQuery<T extends Data>(ref: DataQuery<T>, value: T | Transform<T> | undefined): Promise<void>;
|
|
19
19
|
}
|
|
@@ -88,7 +88,7 @@ export class FirestoreClientProvider extends Provider {
|
|
|
88
88
|
return snapshot.data();
|
|
89
89
|
}
|
|
90
90
|
subscribe(ref, observer) {
|
|
91
|
-
return onSnapshot(getDocument(this.firestore, ref), snapshot => dispatchNext(snapshot.data()
|
|
91
|
+
return onSnapshot(getDocument(this.firestore, ref), snapshot => dispatchNext(observer, snapshot.data()), thrown => dispatchError(observer, thrown));
|
|
92
92
|
}
|
|
93
93
|
async add(ref, data) {
|
|
94
94
|
const reference = await addDoc(getCollection(this.firestore, ref), data); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -106,7 +106,7 @@ export class FirestoreClientProvider extends Provider {
|
|
|
106
106
|
return getResults(await getDocs(getQuery(this.firestore, ref)));
|
|
107
107
|
}
|
|
108
108
|
subscribeQuery(ref, observer) {
|
|
109
|
-
return onSnapshot(getQuery(this.firestore, ref), snapshot => dispatchNext(getResults(snapshot)
|
|
109
|
+
return onSnapshot(getQuery(this.firestore, ref), snapshot => dispatchNext(observer, getResults(snapshot)), thrown => dispatchError(observer, thrown));
|
|
110
110
|
}
|
|
111
111
|
async writeQuery(ref, value) {
|
|
112
112
|
const snapshot = await getDocs(getQuery(this.firestore, ref));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Firestore } from "firebase/firestore/lite";
|
|
2
|
-
import { Provider, DataDocument, DataQuery, Result, Transform, AsynchronousProvider, Data, Results } from "../../index.js";
|
|
2
|
+
import { Provider, DataDocument, DataQuery, Result, Transform, AsynchronousProvider, Data, Results, Unsubscriber } from "../../index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Firestore Lite client database provider.
|
|
5
5
|
* - Works with the Firebase JS SDK.
|
|
@@ -10,10 +10,10 @@ export declare class FirestoreClientProvider extends Provider implements Asynchr
|
|
|
10
10
|
readonly firestore: Firestore;
|
|
11
11
|
constructor(firestore: Firestore);
|
|
12
12
|
get<T extends Data>(ref: DataDocument<T>): Promise<Result<T>>;
|
|
13
|
-
subscribe():
|
|
13
|
+
subscribe(): Unsubscriber;
|
|
14
14
|
add<T extends Data>(ref: DataQuery<T>, data: T): Promise<string>;
|
|
15
15
|
write<T extends Data>(ref: DataDocument<T>, value: T | Transform<T> | undefined): Promise<void>;
|
|
16
16
|
getQuery<T extends Data>(ref: DataQuery<T>): Promise<Results<T>>;
|
|
17
|
-
subscribeQuery():
|
|
17
|
+
subscribeQuery(): Unsubscriber;
|
|
18
18
|
writeQuery<T extends Data>(ref: DataQuery<T>, value: T | Transform<T> | undefined): Promise<void>;
|
|
19
19
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Firestore } from "@google-cloud/firestore";
|
|
2
|
-
import { Provider, DataDocument, DataQuery, Observer, Result, Transform, Data, AsynchronousProvider, Entry, Results } from "../../index.js";
|
|
2
|
+
import { Provider, DataDocument, DataQuery, Observer, Result, Transform, Data, AsynchronousProvider, Entry, Results, Unsubscriber } from "../../index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Firestore server database provider.
|
|
5
5
|
* - Works with the Firebase Admin SDK for Node.JS
|
|
@@ -8,10 +8,10 @@ export declare class FirestoreServerProvider extends Provider implements Asynchr
|
|
|
8
8
|
readonly firestore: Firestore;
|
|
9
9
|
constructor(firestore?: Firestore);
|
|
10
10
|
get<T extends Data>(ref: DataDocument<T>): Promise<Result<T>>;
|
|
11
|
-
subscribe<T extends Data>(ref: DataDocument<T>, observer: Observer<Result<T>>):
|
|
11
|
+
subscribe<T extends Data>(ref: DataDocument<T>, observer: Observer<Result<T>>): Unsubscriber;
|
|
12
12
|
add<T extends Data>(ref: DataQuery<T>, data: T): Promise<string>;
|
|
13
13
|
write<T extends Data>(ref: DataDocument<T>, value: T | Transform<T> | undefined): Promise<void>;
|
|
14
14
|
getQuery<T extends Data>(ref: DataQuery<T>): Promise<Iterable<Entry<T>>>;
|
|
15
|
-
subscribeQuery<T extends Data>(ref: DataQuery<T>, observer: Observer<Results<T>>):
|
|
15
|
+
subscribeQuery<T extends Data>(ref: DataQuery<T>, observer: Observer<Results<T>>): Unsubscriber;
|
|
16
16
|
writeQuery<T extends Data>(ref: DataQuery<T>, value: T | Transform<T> | undefined): Promise<void>;
|
|
17
17
|
}
|
|
@@ -85,7 +85,7 @@ export class FirestoreServerProvider extends Provider {
|
|
|
85
85
|
return (await getDocument(this.firestore, ref).get()).data();
|
|
86
86
|
}
|
|
87
87
|
subscribe(ref, observer) {
|
|
88
|
-
return getDocument(this.firestore, ref).onSnapshot(snapshot => dispatchNext(snapshot.data()
|
|
88
|
+
return getDocument(this.firestore, ref).onSnapshot(snapshot => dispatchNext(observer, snapshot.data()), thrown => dispatchError(observer, thrown));
|
|
89
89
|
}
|
|
90
90
|
async add(ref, data) {
|
|
91
91
|
return (await getCollection(this.firestore, ref).add(data)).id;
|
|
@@ -102,7 +102,7 @@ export class FirestoreServerProvider extends Provider {
|
|
|
102
102
|
return getResults(await getQuery(this.firestore, ref).get());
|
|
103
103
|
}
|
|
104
104
|
subscribeQuery(ref, observer) {
|
|
105
|
-
return getQuery(this.firestore, ref).onSnapshot(snapshot => dispatchNext(getResults(snapshot)
|
|
105
|
+
return getQuery(this.firestore, ref).onSnapshot(snapshot => dispatchNext(observer, getResults(snapshot)), thrown => dispatchError(observer, thrown));
|
|
106
106
|
}
|
|
107
107
|
async writeQuery(ref, value) {
|
|
108
108
|
const writer = this.firestore.bulkWriter();
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isAsync, toMap,
|
|
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. */
|
|
@@ -80,7 +80,7 @@ export class BatchProvider extends ThroughProvider {
|
|
|
80
80
|
const sub = ((_a = this._subs)[key] || (_a[key] = new LazyState(STOP_DELAY).from(o => {
|
|
81
81
|
var _a;
|
|
82
82
|
// Convert the iterable to a map because it might be read multiple times.
|
|
83
|
-
const stop = super.subscribeQuery(ref, new
|
|
83
|
+
const stop = super.subscribeQuery(ref, new TransformObserver(toMap, o));
|
|
84
84
|
// The first value from the subscription can be reused for any concurrent get requests.
|
|
85
85
|
(_a = this._gets)[key] || (_a[key] = this._awaitDocuments(ref, awaitNext(sub)));
|
|
86
86
|
return () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transform } from "../transform/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TransformObserver } from "../util/index.js";
|
|
3
3
|
import { MemoryProvider } from "./MemoryProvider.js";
|
|
4
4
|
import { ThroughProvider } from "./ThroughProvider.js";
|
|
5
5
|
/** Keep a copy of received data in a local cache. */
|
|
@@ -33,7 +33,7 @@ export class CacheProvider extends ThroughProvider {
|
|
|
33
33
|
}
|
|
34
34
|
// Override to cache any got results.
|
|
35
35
|
subscribe(ref, observer) {
|
|
36
|
-
return super.subscribe(ref, new
|
|
36
|
+
return super.subscribe(ref, new TransformObserver(result => this._cacheResult(ref, result), observer));
|
|
37
37
|
}
|
|
38
38
|
async add(ref, data) {
|
|
39
39
|
const id = await super.add(ref, data);
|
|
@@ -72,7 +72,7 @@ export class CacheProvider extends ThroughProvider {
|
|
|
72
72
|
}
|
|
73
73
|
// Override to cache any got results.
|
|
74
74
|
subscribeQuery(ref, observer) {
|
|
75
|
-
return super.subscribeQuery(ref, new
|
|
75
|
+
return super.subscribeQuery(ref, new TransformObserver(results => this._cacheResults(ref, results), observer));
|
|
76
76
|
}
|
|
77
77
|
async writeQuery(ref, value) {
|
|
78
78
|
await super.writeQuery(ref, value);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomId,
|
|
1
|
+
import { randomId, dispatchNext, isMapEqual, } from "../util/index.js";
|
|
2
2
|
import { Transform } from "../transform/index.js";
|
|
3
3
|
import { DocumentRequiredError } from "../db/index.js";
|
|
4
4
|
import { Provider } from "./Provider.js";
|
|
@@ -25,10 +25,10 @@ export class MemoryProvider extends Provider {
|
|
|
25
25
|
const table = this._table(ref);
|
|
26
26
|
const id = ref.id;
|
|
27
27
|
// Call next() immediately with initial results.
|
|
28
|
-
dispatchNext(table.data.get(id)
|
|
28
|
+
dispatchNext(observer, table.data.get(id));
|
|
29
29
|
// Call next() every time the collection changes.
|
|
30
30
|
return table.on(changes => {
|
|
31
|
-
changes.has(id) && dispatchNext(changes.get(id)
|
|
31
|
+
changes.has(id) && dispatchNext(observer, changes.get(id));
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
add(ref, data) {
|
|
@@ -46,20 +46,20 @@ export class MemoryProvider extends Provider {
|
|
|
46
46
|
const existing = table.data.get(id);
|
|
47
47
|
if (!existing)
|
|
48
48
|
throw new DocumentRequiredError(ref);
|
|
49
|
-
table.write(id, value.
|
|
49
|
+
table.write(id, value.transform(existing));
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
52
|
table.write(id, value);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
getQuery(ref) {
|
|
56
|
-
return ref.
|
|
56
|
+
return ref.transform(this._table(ref).data);
|
|
57
57
|
}
|
|
58
58
|
subscribeQuery(ref, observer) {
|
|
59
59
|
const table = this._table(ref);
|
|
60
60
|
// Call `next()` immediately with the initial results.
|
|
61
|
-
let lastResults = new Map(ref.
|
|
62
|
-
dispatchNext(
|
|
61
|
+
let lastResults = new Map(ref.transform(table.data));
|
|
62
|
+
dispatchNext(observer, lastResults);
|
|
63
63
|
// Possibly call `next()` when the collection changes if any changes affect the subscription.
|
|
64
64
|
return table.on(changes => {
|
|
65
65
|
for (const [id, next] of changes) {
|
|
@@ -68,10 +68,10 @@ export class MemoryProvider extends Provider {
|
|
|
68
68
|
// 2) the next document matches the query so might be added to the next results.
|
|
69
69
|
// Re-running the entire query is not the most efficient way to do this, but itis the most simple!
|
|
70
70
|
if (lastResults.has(id) || (next && ref.match([id, next]))) {
|
|
71
|
-
const nextResults = new Map(ref.
|
|
71
|
+
const nextResults = new Map(ref.transform(table.data));
|
|
72
72
|
if (!isMapEqual(lastResults, nextResults)) {
|
|
73
73
|
lastResults = nextResults;
|
|
74
|
-
dispatchNext(
|
|
74
|
+
dispatchNext(observer, lastResults);
|
|
75
75
|
}
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
@@ -82,8 +82,8 @@ export class MemoryProvider extends Provider {
|
|
|
82
82
|
const table = this._table(ref);
|
|
83
83
|
// If there's a limit set: run the full query.
|
|
84
84
|
// If there's no limit set: only need to run the filtering (more efficient because sort order doesn't matter).
|
|
85
|
-
for (const [id, existing] of ref.limit ? ref.
|
|
86
|
-
table.write(id, value instanceof Transform ? value.
|
|
85
|
+
for (const [id, existing] of ref.limit ? ref.transform(table.data) : ref.filters.transform(table.data))
|
|
86
|
+
table.write(id, value instanceof Transform ? value.transform(existing) : value);
|
|
87
87
|
}
|
|
88
88
|
/** Reset this provider and clear all data. */
|
|
89
89
|
reset() {
|
|
@@ -99,11 +99,11 @@ class Table {
|
|
|
99
99
|
constructor() {
|
|
100
100
|
this.data = new Map();
|
|
101
101
|
this.changes = new Map();
|
|
102
|
-
this.
|
|
102
|
+
this.listeners = new Set();
|
|
103
103
|
this.fire = () => {
|
|
104
104
|
if (this.changes.size) {
|
|
105
|
-
for (const dispatcher of this.
|
|
106
|
-
|
|
105
|
+
for (const dispatcher of this.listeners)
|
|
106
|
+
dispatcher(this.changes);
|
|
107
107
|
this.changes.clear();
|
|
108
108
|
}
|
|
109
109
|
};
|
|
@@ -120,16 +120,16 @@ class Table {
|
|
|
120
120
|
this.changes.set(id, value);
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
on(
|
|
124
|
-
this.
|
|
125
|
-
return this.off.bind(this,
|
|
123
|
+
on(listener) {
|
|
124
|
+
this.listeners.add(listener);
|
|
125
|
+
return this.off.bind(this, listener);
|
|
126
126
|
}
|
|
127
|
-
off(
|
|
128
|
-
this.
|
|
127
|
+
off(listener) {
|
|
128
|
+
this.listeners.delete(listener);
|
|
129
129
|
}
|
|
130
130
|
reset() {
|
|
131
131
|
this.data.clear();
|
|
132
132
|
this.changes.clear();
|
|
133
|
-
this.
|
|
133
|
+
this.listeners.clear();
|
|
134
134
|
}
|
|
135
135
|
}
|
package/query/Filter.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare abstract class Filter<T extends Data> extends Rule<T> implements
|
|
|
17
17
|
readonly value: unknown;
|
|
18
18
|
constructor(key: QueryKey<T>, value: unknown);
|
|
19
19
|
match([id, data]: Entry<T>): boolean;
|
|
20
|
-
|
|
20
|
+
transform(results: Results<T>): Results<T>;
|
|
21
21
|
toString(): string;
|
|
22
22
|
}
|
|
23
23
|
/** Filter a set of values with an `IS` clause. */
|
package/query/Filter.js
CHANGED
package/query/Filters.d.ts
CHANGED
|
@@ -13,5 +13,5 @@ export declare class Filters<T extends Data> extends Rules<T, Filter<T>> impleme
|
|
|
13
13
|
gt<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
14
14
|
gte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
15
15
|
match(entry: Entry<T>): boolean;
|
|
16
|
-
|
|
16
|
+
transform(iterable: Results<T>): Results<T>;
|
|
17
17
|
}
|
package/query/Filters.js
CHANGED
package/query/Query.d.ts
CHANGED
|
@@ -25,6 +25,6 @@ export declare class Query<T extends Data> extends Rule<T> implements Queryable<
|
|
|
25
25
|
max(limit: number | null): this;
|
|
26
26
|
after(id: string, data: T): this;
|
|
27
27
|
before(id: string, data: T): this;
|
|
28
|
-
|
|
28
|
+
transform(results: Results<T>): Results<T>;
|
|
29
29
|
toString(): string;
|
|
30
30
|
}
|