shelving 1.22.0 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/api/Resource.d.ts +8 -1
  2. package/api/Resource.js +10 -1
  3. package/db/Database.d.ts +22 -46
  4. package/db/Database.js +35 -49
  5. package/db/Pagination.js +1 -1
  6. package/db/Write.d.ts +30 -0
  7. package/db/Write.js +37 -0
  8. package/db/index.d.ts +1 -1
  9. package/db/index.js +1 -1
  10. package/firestore/client/FirestoreClientProvider.d.ts +3 -3
  11. package/firestore/client/FirestoreClientProvider.js +2 -2
  12. package/firestore/lite/FirestoreLiteProvider.d.ts +3 -3
  13. package/firestore/server/FirestoreServerProvider.d.ts +3 -3
  14. package/firestore/server/FirestoreServerProvider.js +2 -2
  15. package/package.json +1 -1
  16. package/provider/BatchProvider.js +2 -2
  17. package/provider/CacheProvider.js +3 -3
  18. package/provider/MemoryProvider.js +20 -20
  19. package/query/Filter.d.ts +1 -1
  20. package/query/Filter.js +1 -1
  21. package/query/Filters.d.ts +1 -1
  22. package/query/Filters.js +1 -1
  23. package/query/Query.d.ts +1 -1
  24. package/query/Query.js +2 -2
  25. package/query/Rule.d.ts +3 -3
  26. package/query/Sort.d.ts +1 -1
  27. package/query/Sort.js +1 -1
  28. package/query/Sorts.d.ts +1 -1
  29. package/query/Sorts.js +1 -1
  30. package/react/useDocument.js +3 -3
  31. package/react/useFetch.js +2 -2
  32. package/react/usePureState.d.ts +4 -4
  33. package/react/useQuery.js +4 -4
  34. package/react/useSubscribe.js +1 -1
  35. package/stream/DataState.d.ts +2 -2
  36. package/stream/DataState.js +2 -2
  37. package/stream/LastStream.js +1 -1
  38. package/stream/LazyState.d.ts +1 -1
  39. package/stream/LazyState.js +4 -4
  40. package/stream/LazyStream.d.ts +1 -1
  41. package/stream/LazyStream.js +5 -5
  42. package/stream/State.d.ts +5 -5
  43. package/stream/State.js +6 -6
  44. package/stream/Stream.d.ts +13 -13
  45. package/stream/Stream.js +25 -25
  46. package/transform/AddEntriesTransform.d.ts +1 -1
  47. package/transform/AddEntriesTransform.js +1 -1
  48. package/transform/AddItemsTransform.d.ts +1 -1
  49. package/transform/AddItemsTransform.js +1 -1
  50. package/transform/DataTransform.d.ts +1 -1
  51. package/transform/DataTransform.js +3 -3
  52. package/transform/IncrementTransform.d.ts +1 -1
  53. package/transform/IncrementTransform.js +1 -1
  54. package/transform/RemoveEntriesTransform.d.ts +1 -1
  55. package/transform/RemoveEntriesTransform.js +1 -1
  56. package/transform/RemoveItemsTransform.d.ts +1 -1
  57. package/transform/RemoveItemsTransform.js +1 -1
  58. package/transform/Transform.d.ts +3 -3
  59. package/transform/hydrations.d.ts +1 -1
  60. package/transform/hydrations.js +1 -1
  61. package/transform/util.js +2 -2
  62. package/util/async.d.ts +6 -6
  63. package/util/clone.js +3 -3
  64. package/util/error.js +1 -1
  65. package/util/filter.d.ts +4 -4
  66. package/util/filter.js +5 -5
  67. package/util/function.d.ts +8 -0
  68. package/util/function.js +19 -0
  69. package/util/hydrate.d.ts +7 -7
  70. package/util/hydrate.js +13 -13
  71. package/util/index.d.ts +2 -3
  72. package/util/index.js +2 -3
  73. package/util/observable.d.ts +15 -19
  74. package/util/observable.js +22 -28
  75. package/util/sort.d.ts +4 -4
  76. package/util/sort.js +5 -6
  77. package/util/transform.d.ts +88 -0
  78. package/util/transform.js +48 -0
  79. package/db/Change.d.ts +0 -37
  80. package/db/Change.js +0 -60
  81. package/util/derive.d.ts +0 -88
  82. package/util/derive.js +0 -48
  83. package/util/dispatch.d.ts +0 -29
  84. package/util/dispatch.js +0 -43
package/api/Resource.d.ts CHANGED
@@ -12,9 +12,16 @@ export declare class Resource<P = unknown, R = void> implements Validatable<R> {
12
12
  readonly result: Validator<R>;
13
13
  constructor(payload: Validator<P>, result: Validator<R>);
14
14
  /**
15
- * Validate a result for this resource.
15
+ * Validate a payload for this resource.
16
16
  *
17
17
  * @returns The validated payload for this resource.
18
+ * @throws InvalidFeedback if the payload could not be validated.
19
+ */
20
+ prepare(unsafePayload: unknown): P;
21
+ /**
22
+ * Validate a result for this resource.
23
+ *
24
+ * @returns The validated result for this resource.
18
25
  * @throws ValidationError if the result could not be validated.
19
26
  */
20
27
  validate(unsafeResult: unknown): R;
package/api/Resource.js CHANGED
@@ -14,9 +14,18 @@ export class Resource {
14
14
  this.result = result;
15
15
  }
16
16
  /**
17
- * Validate a result for this resource.
17
+ * Validate a payload for this resource.
18
18
  *
19
19
  * @returns The validated payload for this resource.
20
+ * @throws InvalidFeedback if the payload could not be validated.
21
+ */
22
+ prepare(unsafePayload) {
23
+ return validate(unsafePayload, this.payload);
24
+ }
25
+ /**
26
+ * Validate a result for this resource.
27
+ *
28
+ * @returns The validated result for this resource.
20
29
  * @throws ValidationError if the result could not be validated.
21
30
  */
22
31
  validate(unsafeResult) {
package/db/Database.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { Dispatcher, Entry, Observable, Observer, Result, Unsubscriber, ResultsMap, Validatable, Validator, Key, Data, Results, Datas, Validators, ValidatorType } from "../util/index.js";
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 observer Observer with `next`, `error`, or `complete` methods that the document results are reported back to.
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>>, error?: Dispatcher<Error | unknown>, complete?: Dispatcher<void>): Unsubscriber;
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 observer Observer with `next`, `error`, or `complete` methods that the document results are reported back to.
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>>, error?: Dispatcher<Error | unknown>, complete?: Dispatcher<void>): Unsubscriber;
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 observer Observer with `next`, `error`, or `complete` methods.
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>>, error?: Dispatcher<Error | unknown>, complete?: Dispatcher<void>): Unsubscriber;
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, createObserver, getFirstItem, throwAsync, validate, toMap, countItems, DeriveObserver, } from "../util/index.js";
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 observer Observer with `next`, `error`, or `complete` methods that the document results are reported back to.
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, error, complete) {
90
- return this.provider.subscribeQuery(this, createObserver(next, error, complete));
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 observer Observer with `next`, `error`, or `complete` methods that the document results are reported back to.
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, error, complete) {
104
- return this.provider.subscribeQuery(this, new DeriveObserver(toMap, createObserver(next, error, complete)));
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 observer Observer with `next`, `error`, or `complete` methods.
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, error, complete) {
221
- return this.provider.subscribe(this, createObserver(next, error, complete));
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.derive(yieldMerged(more, this.value))));
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 DATABASE_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 DATABASE_HYDRATIONS = {
34
+ writes: Writes,
35
+ write: DocumentWrite,
36
+ };
37
+ DATABASE_HYDRATIONS;
package/db/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from "./Database.js";
2
- export * from "./Change.js";
3
2
  export * from "./Pagination.js";
3
+ export * from "./Write.js";
4
4
  export * from "./errors.js";
package/db/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from "./Database.js";
2
- export * from "./Change.js";
3
2
  export * from "./Pagination.js";
3
+ export * from "./Write.js";
4
4
  export * from "./errors.js";
@@ -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>>): () => void;
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>>): () => void;
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(), observer), thrown => dispatchError(thrown, observer));
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), observer), thrown => dispatchError(thrown, observer));
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(): () => void;
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(): () => void;
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>>): () => void;
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>>): () => void;
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(), observer), thrown => dispatchError(thrown, observer));
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), observer), thrown => dispatchError(thrown, observer));
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
@@ -11,7 +11,7 @@
11
11
  "state-management",
12
12
  "query-builder"
13
13
  ],
14
- "version": "1.22.0",
14
+ "version": "1.23.1",
15
15
  "repository": "https://github.com/dhoulb/shelving",
16
16
  "author": "Dave Houlbrooke <dave@shax.com>",
17
17
  "license": "0BSD",
@@ -1,4 +1,4 @@
1
- import { isAsync, toMap, DeriveObserver, awaitNext, } from "../util/index.js";
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 DeriveObserver(toMap, o));
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 { DeriveObserver } from "../util/index.js";
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 DeriveObserver(result => this._cacheResult(ref, result), observer));
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 DeriveObserver(results => this._cacheResults(ref, results), observer));
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, dispatch, dispatchNext, isMapEqual } from "../util/index.js";
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), observer);
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), observer);
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.derive(existing));
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.derive(this._table(ref).data);
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.derive(table.data));
62
- dispatchNext(lastResults, observer);
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.derive(table.data));
71
+ const nextResults = new Map(ref.transform(table.data));
72
72
  if (!isMapEqual(lastResults, nextResults)) {
73
73
  lastResults = nextResults;
74
- dispatchNext(lastResults, observer);
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.derive(table.data) : ref.filters.derive(table.data))
86
- table.write(id, value instanceof Transform ? value.derive(existing) : 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.dispatchers = new Set();
102
+ this.listeners = new Set();
103
103
  this.fire = () => {
104
104
  if (this.changes.size) {
105
- for (const dispatcher of this.dispatchers)
106
- dispatch(this.changes, dispatcher);
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(dispatcher) {
124
- this.dispatchers.add(dispatcher);
125
- return this.off.bind(this, dispatcher);
123
+ on(listener) {
124
+ this.listeners.add(listener);
125
+ return this.off.bind(this, listener);
126
126
  }
127
- off(dispatcher) {
128
- this.dispatchers.delete(dispatcher);
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.dispatchers.clear();
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
- derive(results: Results<T>): Results<T>;
20
+ transform(results: Results<T>): Results<T>;
21
21
  toString(): string;
22
22
  }
23
23
  /** Filter a set of values with an `IS` clause. */