shelving 1.64.0 → 1.66.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.
Files changed (154) hide show
  1. package/api/Resource.js +2 -2
  2. package/db/Reference.d.ts +37 -23
  3. package/db/Reference.js +65 -33
  4. package/db/index.d.ts +0 -3
  5. package/db/index.js +0 -3
  6. package/error/ThroughError.d.ts +8 -0
  7. package/error/ThroughError.js +13 -0
  8. package/firestore/client/FirestoreClientProvider.d.ts +11 -10
  9. package/firestore/client/FirestoreClientProvider.js +18 -17
  10. package/firestore/lite/FirestoreLiteProvider.d.ts +10 -10
  11. package/firestore/lite/FirestoreLiteProvider.js +15 -14
  12. package/firestore/server/FirestoreServerProvider.d.ts +11 -10
  13. package/firestore/server/FirestoreServerProvider.js +18 -17
  14. package/index.d.ts +2 -1
  15. package/index.js +2 -1
  16. package/markup/rules.js +4 -4
  17. package/observe/AbstractObserver.d.ts +15 -0
  18. package/observe/AbstractObserver.js +42 -0
  19. package/observe/AsyncObserver.d.ts +5 -0
  20. package/observe/AsyncObserver.js +8 -0
  21. package/{stream/LastStream.d.ts → observe/LastSubject.d.ts} +2 -2
  22. package/observe/LastSubject.js +12 -0
  23. package/observe/MatchObserver.d.ts +9 -0
  24. package/observe/MatchObserver.js +12 -0
  25. package/observe/MatchableObserver.d.ts +7 -0
  26. package/observe/MatchableObserver.js +10 -0
  27. package/observe/Observable.d.ts +20 -0
  28. package/observe/Observable.js +7 -0
  29. package/observe/Observer.d.ts +31 -0
  30. package/observe/Observer.js +48 -0
  31. package/observe/OnceObserver.d.ts +5 -0
  32. package/observe/OnceObserver.js +8 -0
  33. package/observe/Subject.d.ts +46 -0
  34. package/observe/Subject.js +110 -0
  35. package/observe/ThroughObserver.d.ts +5 -0
  36. package/observe/ThroughObserver.js +8 -0
  37. package/observe/TransformObserver.d.ts +9 -0
  38. package/observe/TransformObserver.js +12 -0
  39. package/observe/TransformableObserver.d.ts +7 -0
  40. package/observe/TransformableObserver.js +8 -0
  41. package/observe/index.d.ts +13 -0
  42. package/observe/index.js +13 -0
  43. package/observe/util.d.ts +24 -0
  44. package/observe/util.js +34 -0
  45. package/package.json +1 -1
  46. package/provider/BatchProvider.d.ts +8 -8
  47. package/provider/BatchProvider.js +26 -31
  48. package/provider/CacheProvider.d.ts +12 -21
  49. package/provider/CacheProvider.js +40 -74
  50. package/provider/DebugProvider.d.ts +20 -0
  51. package/provider/DebugProvider.js +170 -0
  52. package/provider/MemoryProvider.d.ts +38 -24
  53. package/provider/MemoryProvider.js +141 -102
  54. package/provider/Provider.d.ts +23 -22
  55. package/provider/ThroughProvider.d.ts +20 -11
  56. package/provider/ThroughProvider.js +12 -12
  57. package/provider/ValidationProvider.d.ts +10 -9
  58. package/provider/ValidationProvider.js +31 -28
  59. package/provider/index.d.ts +1 -1
  60. package/provider/index.js +1 -1
  61. package/query/Filter.d.ts +1 -1
  62. package/query/Filter.js +4 -3
  63. package/query/Filters.d.ts +1 -1
  64. package/react/index.d.ts +0 -6
  65. package/react/index.js +3 -6
  66. package/react/useDocument.d.ts +34 -38
  67. package/react/useDocument.js +80 -79
  68. package/react/useInstance.d.ts +4 -7
  69. package/react/useInstance.js +6 -9
  70. package/react/useLazy.d.ts +5 -9
  71. package/react/useQuery.d.ts +52 -46
  72. package/react/useQuery.js +125 -87
  73. package/react/useReduce.d.ts +8 -1
  74. package/react/useReduce.js +1 -3
  75. package/react/useSubscribe.d.ts +5 -6
  76. package/react/useSubscribe.js +10 -11
  77. package/{stream → state}/ArrayState.d.ts +2 -2
  78. package/{stream → state}/ArrayState.js +9 -11
  79. package/{stream → state}/BooleanState.d.ts +1 -1
  80. package/{stream → state}/BooleanState.js +3 -5
  81. package/{stream → state}/DataState.d.ts +4 -4
  82. package/{stream → state}/DataState.js +7 -13
  83. package/{stream → state}/ObjectState.d.ts +2 -2
  84. package/{stream → state}/ObjectState.js +7 -9
  85. package/state/SelfClosingState.d.ts +18 -0
  86. package/state/SelfClosingState.js +34 -0
  87. package/state/State.d.ts +32 -0
  88. package/state/State.js +69 -0
  89. package/{stream → state}/index.d.ts +1 -4
  90. package/{stream → state}/index.js +1 -4
  91. package/util/array.d.ts +0 -8
  92. package/util/array.js +0 -4
  93. package/util/async.d.ts +4 -5
  94. package/util/async.js +3 -2
  95. package/util/clone.js +3 -2
  96. package/util/data.d.ts +7 -3
  97. package/util/data.js +1 -1
  98. package/util/entry.d.ts +1 -3
  99. package/util/equal.d.ts +4 -5
  100. package/util/filter.d.ts +1 -26
  101. package/util/filter.js +1 -25
  102. package/util/function.d.ts +5 -5
  103. package/util/function.js +3 -3
  104. package/util/hydrate.js +2 -2
  105. package/util/index.d.ts +1 -1
  106. package/util/index.js +1 -1
  107. package/util/iterate.d.ts +3 -9
  108. package/util/iterate.js +7 -11
  109. package/util/match.d.ts +20 -0
  110. package/util/match.js +14 -0
  111. package/util/object.d.ts +0 -19
  112. package/util/object.js +0 -8
  113. package/util/search.d.ts +1 -1
  114. package/util/sort.d.ts +4 -10
  115. package/util/sort.js +0 -11
  116. package/util/timeout.d.ts +2 -0
  117. package/util/timeout.js +8 -1
  118. package/util/transform.d.ts +41 -9
  119. package/util/transform.js +18 -4
  120. package/util/validate.d.ts +6 -10
  121. package/util/validate.js +1 -3
  122. package/api/errors.d.ts +0 -8
  123. package/api/errors.js +0 -9
  124. package/db/PaginationState.d.ts +0 -28
  125. package/db/PaginationState.js +0 -59
  126. package/db/errors.d.ts +0 -13
  127. package/db/errors.js +0 -17
  128. package/db/util.d.ts +0 -11
  129. package/db/util.js +0 -21
  130. package/provider/ErrorProvider.d.ts +0 -31
  131. package/provider/ErrorProvider.js +0 -175
  132. package/react/useCompare.d.ts +0 -3
  133. package/react/useCompare.js +0 -8
  134. package/react/useFetch.d.ts +0 -17
  135. package/react/useFetch.js +0 -41
  136. package/react/usePagination.d.ts +0 -8
  137. package/react/usePagination.js +0 -25
  138. package/react/usePureEffect.d.ts +0 -10
  139. package/react/usePureEffect.js +0 -17
  140. package/react/usePureState.d.ts +0 -11
  141. package/react/usePureState.js +0 -16
  142. package/react/useState.d.ts +0 -39
  143. package/react/useState.js +0 -65
  144. package/stream/LastStream.js +0 -12
  145. package/stream/LazyState.d.ts +0 -11
  146. package/stream/LazyState.js +0 -28
  147. package/stream/LazyStream.d.ts +0 -12
  148. package/stream/LazyStream.js +0 -28
  149. package/stream/State.d.ts +0 -46
  150. package/stream/State.js +0 -66
  151. package/stream/Stream.d.ts +0 -66
  152. package/stream/Stream.js +0 -122
  153. package/util/observe.d.ts +0 -103
  154. package/util/observe.js +0 -147
package/api/Resource.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { validate } from "../util/validate.js";
2
2
  import { getUndefined } from "../util/undefined.js";
3
3
  import { Feedback } from "../feedback/Feedback.js";
4
- import { ResourceValidationError } from "./errors.js";
4
+ import { ValidationError } from "../error/ValidationError.js";
5
5
  /**
6
6
  * An abstract API resource definition, used to specify types for e.g. serverless functions..
7
7
  *
@@ -34,7 +34,7 @@ export class Resource {
34
34
  return validate(unsafeResult, this.result);
35
35
  }
36
36
  catch (thrown) {
37
- throw thrown instanceof Feedback ? new ResourceValidationError(this, thrown) : thrown;
37
+ throw thrown instanceof Feedback ? new ValidationError(`Invalid result for resource`, thrown) : thrown;
38
38
  }
39
39
  }
40
40
  }
package/db/Reference.d.ts CHANGED
@@ -1,14 +1,15 @@
1
- import type { Data, Result, Entity } from "../util/data.js";
2
- import type { Dispatcher } from "../util/function.js";
1
+ import type { Data, OptionalData, Entity, OptionalEntity, Entities } from "../util/data.js";
2
+ import type { Dispatch } from "../util/function.js";
3
3
  import type { SortKeys } from "../query/Sort.js";
4
4
  import { ImmutableArray } from "../util/array.js";
5
- import { Observable, Observer, Unsubscriber } from "../util/observe.js";
6
- import { Validator } from "../util/validate.js";
5
+ import type { PartialObserver } from "../observe/Observer.js";
6
+ import type { Validator } from "../util/validate.js";
7
7
  import { Query } from "../query/Query.js";
8
8
  import { Filters } from "../query/Filters.js";
9
9
  import { Sorts } from "../query/Sorts.js";
10
10
  import { DataUpdate, PropUpdates } from "../update/DataUpdate.js";
11
11
  import { FilterProps } from "../query/Filter.js";
12
+ import { Observable, Unsubscribe } from "../observe/Observable.js";
12
13
  import type { Database } from "./Database.js";
13
14
  /** A refence to a location in a database. */
14
15
  export interface Reference {
@@ -32,15 +33,10 @@ export declare class QueryReference<T extends Data = Data> extends Query<Entity<
32
33
  */
33
34
  add(data: T): string | PromiseLike<string>;
34
35
  /**
35
- * Get an iterable that yields the entities of this query.
36
- * @return Map containing the results.
36
+ * Get array of entities for this query.
37
+ * @return Array of entities.
37
38
  */
38
- get items(): Iterable<Entity<T>> | PromiseLike<Iterable<Entity<T>>>;
39
- /**
40
- * Get an array of the results of this .
41
- * @return Array containing the entities.
42
- */
43
- get array(): ImmutableArray<Entity<T>> | PromiseLike<ImmutableArray<Entity<T>>>;
39
+ get value(): Entities<T> | PromiseLike<Entities<T>>;
44
40
  /**
45
41
  * Count the number of results of this set of documents.
46
42
  * @return Number of documents matching the query (possibly promised).
@@ -53,18 +49,24 @@ export declare class QueryReference<T extends Data = Data> extends Query<Entity<
53
49
  get exists(): boolean | PromiseLike<boolean>;
54
50
  /**
55
51
  * Get the first document matched by this query or `null` if this query has no results.
56
- *
57
- * @return Entry in `[id, data]` format for the first document.
58
52
  * @throws RequiredError if there were no results for this query.
59
53
  */
60
- get result(): Result<Entity<T>> | PromiseLike<Result<Entity<T>>>;
54
+ get firstValue(): OptionalEntity<T> | PromiseLike<OptionalEntity<T>>;
61
55
  /**
62
56
  * Get the first document matched by this query.
63
- *
64
- * @return Entry in `[id, data]` format for the first document.
65
57
  * @throws RequiredError if there were no results for this query.
66
58
  */
67
- get data(): Entity<T> | PromiseLike<Entity<T>>;
59
+ get firstData(): Entity<T> | PromiseLike<Entity<T>>;
60
+ /**
61
+ * Get the last document matched by this query or `null` if this query has no results.
62
+ * @throws RequiredError if there were no results for this query.
63
+ */
64
+ get lastValue(): OptionalEntity<T> | PromiseLike<OptionalEntity<T>>;
65
+ /**
66
+ * Get the last document matched by this query.
67
+ * @throws RequiredError if there were no results for this query.
68
+ */
69
+ get lastData(): Entity<T> | PromiseLike<Entity<T>>;
68
70
  /**
69
71
  * Subscribe to all matching documents.
70
72
  * - `next()` is called once with the initial results, and again any time the results change.
@@ -72,7 +74,7 @@ export declare class QueryReference<T extends Data = Data> extends Query<Entity<
72
74
  * @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
73
75
  * @return Function that ends the subscription.
74
76
  */
75
- subscribe(next: Observer<ImmutableArray<Entity<T>>> | Dispatcher<[ImmutableArray<Entity<T>>]>): Unsubscriber;
77
+ subscribe(next: PartialObserver<ImmutableArray<Entity<T>>> | Dispatch<[ImmutableArray<Entity<T>>]>): Unsubscribe;
76
78
  /**
77
79
  * Set all matching documents to the same exact value.
78
80
  *
@@ -95,7 +97,7 @@ export declare class QueryReference<T extends Data = Data> extends Query<Entity<
95
97
  toString(): string;
96
98
  }
97
99
  /** A document reference within a specific database. */
98
- export declare class DocumentReference<T extends Data = Data> implements Observable<Result<T>>, Reference {
100
+ export declare class DocumentReference<T extends Data = Data> implements Observable<OptionalData<T>>, Reference {
99
101
  readonly db: Database;
100
102
  readonly validator: Validator<T>;
101
103
  readonly collection: string;
@@ -111,10 +113,10 @@ export declare class DocumentReference<T extends Data = Data> implements Observa
111
113
  */
112
114
  get exists(): boolean | PromiseLike<boolean>;
113
115
  /**
114
- * Get the result of this document.
116
+ * Get the optional data of this document.
115
117
  * @return Document's data, or `null` if the document doesn't exist (possibly promised).
116
118
  */
117
- get result(): Result<Entity<T>> | PromiseLike<Result<Entity<T>>>;
119
+ get value(): OptionalEntity<T> | PromiseLike<OptionalEntity<T>>;
118
120
  /**
119
121
  * Get the data of this document.
120
122
  * - Useful for destructuring, e.g. `{ name, title } = await documentThatMustExist.asyncData`
@@ -130,7 +132,7 @@ export declare class DocumentReference<T extends Data = Data> implements Observa
130
132
  * @param next Observer with `next`, `error`, or `complete` methods or a `next()` dispatcher.
131
133
  * @return Function that ends the subscription.
132
134
  */
133
- subscribe(next: Observer<Result<Entity<T>>> | Dispatcher<[Result<Entity<T>>]>): Unsubscriber;
135
+ subscribe(next: PartialObserver<OptionalEntity<T>> | Dispatch<[OptionalEntity<T>]>): Unsubscribe;
134
136
  /** Set the complete data of this document. */
135
137
  set(data: T): void | PromiseLike<void>;
136
138
  /** Update this document. */
@@ -139,3 +141,15 @@ export declare class DocumentReference<T extends Data = Data> implements Observa
139
141
  delete(): void | PromiseLike<void>;
140
142
  toString(): string;
141
143
  }
144
+ /** Get the data for a document from a result for that document. */
145
+ export declare function getDocumentData<T extends Data>(entity: OptionalEntity<T>, ref: DocumentReference<T>): Entity<T>;
146
+ /** Get the data for a document from a set of queried entities. */
147
+ export declare function getQueryFirstData<T extends Data>(entities: Entities<T>, ref: QueryReference<T>): Entity<T>;
148
+ /** Get the data for a document from a set of queried entities. */
149
+ export declare function getQueryLastData<T extends Data>(entities: Entities<T>, ref: QueryReference<T>): Entity<T>;
150
+ /** Get the optional data for a document from a set of queried entities. */
151
+ export declare function getQueryFirstValue<T extends Data>(entities: Entities<T>): OptionalEntity<T>;
152
+ /** Get the optional data for a document from a set of queried entities. */
153
+ export declare function getQueryLastValue<T extends Data>(entities: Entities<T>): OptionalEntity<T>;
154
+ /** Are two database references equal? */
155
+ export declare const isSameReference: (left: Reference, right: Reference) => boolean;
package/db/Reference.js CHANGED
@@ -1,5 +1,4 @@
1
- import { getArray } from "../util/array.js";
2
- import { ArrayObserver } from "../util/observe.js";
1
+ import { getFirstItem, getLastItem } from "../util/array.js";
3
2
  import { Query } from "../query/Query.js";
4
3
  import { Filters } from "../query/Filters.js";
5
4
  import { Sorts } from "../query/Sorts.js";
@@ -7,7 +6,7 @@ import { callAsync } from "../util/async.js";
7
6
  import { countItems, hasItems } from "../util/iterate.js";
8
7
  import { DataUpdate } from "../update/DataUpdate.js";
9
8
  import { Filter } from "../query/Filter.js";
10
- import { getDocumentData, getQueryData, getQueryResult } from "./util.js";
9
+ import { RequiredError } from "../error/RequiredError.js";
11
10
  /** A query reference within a specific database. */
12
11
  export class QueryReference extends Query {
13
12
  constructor(db, validator, collection, filters, sorts, limit) {
@@ -28,28 +27,21 @@ export class QueryReference extends Query {
28
27
  * @return String ID for the created document (possibly promised).
29
28
  */
30
29
  add(data) {
31
- return this.db.provider.add(this, data);
30
+ return this.db.provider.addDocument(this, data);
32
31
  }
33
32
  /**
34
- * Get an iterable that yields the entities of this query.
35
- * @return Map containing the results.
33
+ * Get array of entities for this query.
34
+ * @return Array of entities.
36
35
  */
37
- get items() {
36
+ get value() {
38
37
  return this.db.provider.getQuery(this);
39
38
  }
40
- /**
41
- * Get an array of the results of this .
42
- * @return Array containing the entities.
43
- */
44
- get array() {
45
- return callAsync(getArray, this.db.provider.getQuery(this));
46
- }
47
39
  /**
48
40
  * Count the number of results of this set of documents.
49
41
  * @return Number of documents matching the query (possibly promised).
50
42
  */
51
43
  get count() {
52
- return callAsync(countItems, this.items);
44
+ return callAsync(countItems, this.value);
53
45
  }
54
46
  /**
55
47
  * Does at least one document exist for this query?
@@ -60,21 +52,31 @@ export class QueryReference extends Query {
60
52
  }
61
53
  /**
62
54
  * Get the first document matched by this query or `null` if this query has no results.
63
- *
64
- * @return Entry in `[id, data]` format for the first document.
65
55
  * @throws RequiredError if there were no results for this query.
66
56
  */
67
- get result() {
68
- return callAsync(getQueryResult, this.db.provider.getQuery(this.max(1)));
57
+ get firstValue() {
58
+ return callAsync(getQueryFirstValue, this.db.provider.getQuery(this.max(1)));
69
59
  }
70
60
  /**
71
61
  * Get the first document matched by this query.
72
- *
73
- * @return Entry in `[id, data]` format for the first document.
74
62
  * @throws RequiredError if there were no results for this query.
75
63
  */
76
- get data() {
77
- return callAsync(getQueryData, this.db.provider.getQuery(this.max(1)), this);
64
+ get firstData() {
65
+ return callAsync(getQueryFirstData, this.db.provider.getQuery(this.max(1)), this);
66
+ }
67
+ /**
68
+ * Get the last document matched by this query or `null` if this query has no results.
69
+ * @throws RequiredError if there were no results for this query.
70
+ */
71
+ get lastValue() {
72
+ return callAsync(getQueryLastValue, this.db.provider.getQuery(this.max(1)));
73
+ }
74
+ /**
75
+ * Get the last document matched by this query.
76
+ * @throws RequiredError if there were no results for this query.
77
+ */
78
+ get lastData() {
79
+ return callAsync(getQueryLastData, this.db.provider.getQuery(this.max(1)), this);
78
80
  }
79
81
  /**
80
82
  * Subscribe to all matching documents.
@@ -84,7 +86,7 @@ export class QueryReference extends Query {
84
86
  * @return Function that ends the subscription.
85
87
  */
86
88
  subscribe(next) {
87
- return this.db.provider.subscribeQuery(this, new ArrayObserver(typeof next === "function" ? { next } : next));
89
+ return this.db.provider.subscribeQuery(this, typeof next === "function" ? { next } : next);
88
90
  }
89
91
  /**
90
92
  * Set all matching documents to the same exact value.
@@ -137,14 +139,14 @@ export class DocumentReference {
137
139
  * @return `true` if a document exists or `false` otherwise (possibly promised).
138
140
  */
139
141
  get exists() {
140
- return callAsync(Boolean, this.db.provider.get(this));
142
+ return callAsync(Boolean, this.db.provider.getDocument(this));
141
143
  }
142
144
  /**
143
- * Get the result of this document.
145
+ * Get the optional data of this document.
144
146
  * @return Document's data, or `null` if the document doesn't exist (possibly promised).
145
147
  */
146
- get result() {
147
- return this.db.provider.get(this);
148
+ get value() {
149
+ return this.db.provider.getDocument(this);
148
150
  }
149
151
  /**
150
152
  * Get the data of this document.
@@ -154,7 +156,7 @@ export class DocumentReference {
154
156
  * @throws RequiredError if the document does not exist.
155
157
  */
156
158
  get data() {
157
- return callAsync(getDocumentData, this.db.provider.get(this), this);
159
+ return callAsync(getDocumentData, this.db.provider.getDocument(this), this);
158
160
  }
159
161
  /**
160
162
  * Subscribe to the result of this document (indefinitely).
@@ -164,22 +166,52 @@ export class DocumentReference {
164
166
  * @return Function that ends the subscription.
165
167
  */
166
168
  subscribe(next) {
167
- return this.db.provider.subscribe(this, typeof next === "function" ? { next } : next);
169
+ return this.db.provider.subscribeDocument(this, typeof next === "function" ? { next } : next);
168
170
  }
169
171
  /** Set the complete data of this document. */
170
172
  set(data) {
171
- return this.db.provider.set(this, data);
173
+ return this.db.provider.setDocument(this, data);
172
174
  }
173
175
  /** Update this document. */
174
176
  update(updates) {
175
- return this.db.provider.update(this, updates instanceof DataUpdate ? updates : new DataUpdate(updates));
177
+ return this.db.provider.updateDocument(this, updates instanceof DataUpdate ? updates : new DataUpdate(updates));
176
178
  }
177
179
  /** Delete this document. */
178
180
  delete() {
179
- return this.db.provider.delete(this);
181
+ return this.db.provider.deleteDocument(this);
180
182
  }
181
183
  // Implement toString()
182
184
  toString() {
183
185
  return `${this.collection}/${this.id}`;
184
186
  }
185
187
  }
188
+ /** Get the data for a document from a result for that document. */
189
+ export function getDocumentData(entity, ref) {
190
+ if (entity)
191
+ return entity;
192
+ throw new RequiredError(`Document "${ref}" does not exist`);
193
+ }
194
+ /** Get the data for a document from a set of queried entities. */
195
+ export function getQueryFirstData(entities, ref) {
196
+ const entity = getQueryFirstValue(entities);
197
+ if (entity)
198
+ return entity;
199
+ throw new RequiredError(`Query "${ref}" has no documents`);
200
+ }
201
+ /** Get the data for a document from a set of queried entities. */
202
+ export function getQueryLastData(entities, ref) {
203
+ const entity = getQueryLastValue(entities);
204
+ if (entity)
205
+ return entity;
206
+ throw new RequiredError(`Query "${ref}" has no documents`);
207
+ }
208
+ /** Get the optional data for a document from a set of queried entities. */
209
+ export function getQueryFirstValue(entities) {
210
+ return getFirstItem(entities) || null;
211
+ }
212
+ /** Get the optional data for a document from a set of queried entities. */
213
+ export function getQueryLastValue(entities) {
214
+ return getLastItem(entities) || null;
215
+ }
216
+ /** Are two database references equal? */
217
+ export const isSameReference = (left, right) => left === right || left.toString() === right.toString();
package/db/index.d.ts CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from "./Database.js";
2
2
  export * from "./Reference.js";
3
3
  export * from "./Operation.js";
4
- export * from "./PaginationState.js";
5
- export * from "./util.js";
6
- export * from "./errors.js";
package/db/index.js CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from "./Database.js";
2
2
  export * from "./Reference.js";
3
3
  export * from "./Operation.js";
4
- export * from "./PaginationState.js";
5
- export * from "./util.js";
6
- export * from "./errors.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Thrown to wrap an error with another error.
3
+ * - Merges the message and stack of the previous message.
4
+ */
5
+ export declare class ThroughError extends Error {
6
+ readonly cause: Error | unknown;
7
+ constructor(message: string, cause: Error | unknown);
8
+ }
@@ -0,0 +1,13 @@
1
+ import { debug } from "../util/debug.js";
2
+ /**
3
+ * Thrown to wrap an error with another error.
4
+ * - Merges the message and stack of the previous message.
5
+ */
6
+ export class ThroughError extends Error {
7
+ constructor(message, cause) {
8
+ super(message);
9
+ this.cause = cause;
10
+ this.stack = `${this.stack}\nCause: ${cause instanceof Error ? cause.stack : debug(cause)}`;
11
+ }
12
+ }
13
+ ThroughError.prototype.name = "ThroughError";
@@ -1,9 +1,10 @@
1
1
  import type { Firestore } from "firebase/firestore";
2
2
  import type { DocumentReference, QueryReference } from "../../db/Reference.js";
3
- import type { Data, Result, Entity } from "../../util/data.js";
3
+ import type { Data, Entities, OptionalEntity } from "../../util/data.js";
4
+ import type { Unsubscribe } from "../../observe/Observable.js";
4
5
  import { AsynchronousProvider, Provider } from "../../provider/Provider.js";
5
6
  import { DataUpdate } from "../../update/DataUpdate.js";
6
- import { Observer, Unsubscriber } from "../../util/observe.js";
7
+ import { Observer } from "../../observe/Observer.js";
7
8
  /**
8
9
  * Firestore client database provider.
9
10
  * - Works with the Firebase JS SDK.
@@ -13,14 +14,14 @@ import { Observer, Unsubscriber } from "../../util/observe.js";
13
14
  export declare class FirestoreClientProvider extends Provider implements AsynchronousProvider {
14
15
  readonly firestore: Firestore;
15
16
  constructor(firestore: Firestore);
16
- get<T extends Data>(ref: DocumentReference<T>): Promise<Result<Entity<T>>>;
17
- subscribe<T extends Data>(ref: DocumentReference<T>, observer: Observer<Result<Entity<T>>>): Unsubscriber;
18
- add<T extends Data>(ref: QueryReference<T>, data: T): Promise<string>;
19
- set<T extends Data>(ref: DocumentReference<T>, data: T): Promise<void>;
20
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): Promise<void>;
21
- delete<T extends Data>(ref: DocumentReference<T>): Promise<void>;
22
- getQuery<T extends Data>(ref: QueryReference<T>): Promise<Iterable<Entity<T>>>;
23
- subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Iterable<Entity<T>>>): Unsubscriber;
17
+ getDocument<T extends Data>(ref: DocumentReference<T>): Promise<OptionalEntity<T>>;
18
+ subscribeDocument<T extends Data>(ref: DocumentReference<T>, observer: Observer<OptionalEntity<T>>): Unsubscribe;
19
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): Promise<string>;
20
+ setDocument<T extends Data>(ref: DocumentReference<T>, data: T): Promise<void>;
21
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): Promise<void>;
22
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): Promise<void>;
23
+ getQuery<T extends Data>(ref: QueryReference<T>): Promise<Entities<T>>;
24
+ subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Entities<T>>): Unsubscribe;
24
25
  setQuery<T extends Data>(ref: QueryReference<T>, data: T): Promise<number>;
25
26
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): Promise<number>;
26
27
  deleteQuery<T extends Data>(ref: QueryReference<T>): Promise<number>;
@@ -5,7 +5,7 @@ import { ArrayUpdate } from "../../update/ArrayUpdate.js";
5
5
  import { DataUpdate } from "../../update/DataUpdate.js";
6
6
  import { Increment } from "../../update/Increment.js";
7
7
  import { ObjectUpdate } from "../../update/ObjectUpdate.js";
8
- import { dispatchError, dispatchNext } from "../../util/observe.js";
8
+ import { dispatchError, dispatchNext } from "../../observe/Observer.js";
9
9
  // Constants.
10
10
  // const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
11
11
  const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
@@ -46,13 +46,14 @@ function getQuery(firestore, ref) {
46
46
  constraints.push(firestoreLimit(limit));
47
47
  return firestoreQuery(getCollection(firestore, ref), ...constraints);
48
48
  }
49
- /** Create a set of results from a collection snapshot. */
50
- function* getResults(snapshot) {
51
- for (const s of snapshot.docs)
52
- yield { ...s.data(), id: s.id };
49
+ function getEntities(snapshot) {
50
+ return snapshot.docs.map(getEntity);
53
51
  }
54
- /** Get a result from a document snapshot. */
55
- function getResult(snapshot) {
52
+ function getEntity(snapshot) {
53
+ const data = snapshot.data();
54
+ return { ...data, id: snapshot.id };
55
+ }
56
+ function getOptionalEntity(snapshot) {
56
57
  const data = snapshot.data();
57
58
  return data ? { ...data, id: snapshot.id } : null;
58
59
  }
@@ -88,31 +89,31 @@ export class FirestoreClientProvider extends Provider {
88
89
  super();
89
90
  this.firestore = firestore;
90
91
  }
91
- async get(ref) {
92
- return getResult(await getDoc(getDocument(this.firestore, ref)));
92
+ async getDocument(ref) {
93
+ return getOptionalEntity(await getDoc(getDocument(this.firestore, ref)));
93
94
  }
94
- subscribe(ref, observer) {
95
- return onSnapshot(getDocument(this.firestore, ref), snapshot => dispatchNext(observer, getResult(snapshot)), thrown => dispatchError(observer, thrown));
95
+ subscribeDocument(ref, observer) {
96
+ return onSnapshot(getDocument(this.firestore, ref), snapshot => dispatchNext(observer, getOptionalEntity(snapshot)), thrown => dispatchError(observer, thrown));
96
97
  }
97
- async add(ref, data) {
98
+ async addDocument(ref, data) {
98
99
  const reference = await addDoc(getCollection(this.firestore, ref), data);
99
100
  return reference.id;
100
101
  }
101
- async set(ref, data) {
102
+ async setDocument(ref, data) {
102
103
  await setDoc(getDocument(this.firestore, ref), data);
103
104
  }
104
- async update(ref, update) {
105
+ async updateDocument(ref, update) {
105
106
  const fieldValues = Object.fromEntries(yieldFieldValues(update));
106
107
  await updateDoc(getDocument(this.firestore, ref), fieldValues);
107
108
  }
108
- async delete(ref) {
109
+ async deleteDocument(ref) {
109
110
  await deleteDoc(getDocument(this.firestore, ref));
110
111
  }
111
112
  async getQuery(ref) {
112
- return getResults(await getDocs(getQuery(this.firestore, ref)));
113
+ return getEntities(await getDocs(getQuery(this.firestore, ref)));
113
114
  }
114
115
  subscribeQuery(ref, observer) {
115
- return onSnapshot(getQuery(this.firestore, ref), snapshot => dispatchNext(observer, getResults(snapshot)), thrown => dispatchError(observer, thrown));
116
+ return onSnapshot(getQuery(this.firestore, ref), snapshot => dispatchNext(observer, getEntities(snapshot)), thrown => dispatchError(observer, thrown));
116
117
  }
117
118
  async setQuery(ref, data) {
118
119
  const snapshot = await getDocs(getQuery(this.firestore, ref));
@@ -1,7 +1,7 @@
1
1
  import type { Firestore } from "firebase/firestore/lite";
2
2
  import type { DocumentReference, QueryReference } from "../../db/Reference.js";
3
- import type { Data, Result, Entity } from "../../util/data.js";
4
- import type { Unsubscriber } from "../../util/observe.js";
3
+ import type { Data, Entities, OptionalEntity } from "../../util/data.js";
4
+ import type { Unsubscribe } from "../../observe/Observable.js";
5
5
  import { AsynchronousProvider, Provider } from "../../provider/Provider.js";
6
6
  import { DataUpdate } from "../../update/DataUpdate.js";
7
7
  /**
@@ -13,14 +13,14 @@ import { DataUpdate } from "../../update/DataUpdate.js";
13
13
  export declare class FirestoreClientProvider extends Provider implements AsynchronousProvider {
14
14
  readonly firestore: Firestore;
15
15
  constructor(firestore: Firestore);
16
- get<T extends Data>(ref: DocumentReference<T>): Promise<Result<Entity<T>>>;
17
- subscribe(): Unsubscriber;
18
- add<T extends Data>(ref: QueryReference<T>, data: T): Promise<string>;
19
- set<T extends Data>(ref: DocumentReference<T>, data: T): Promise<void>;
20
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): Promise<void>;
21
- delete<T extends Data>(ref: DocumentReference<T>): Promise<void>;
22
- getQuery<T extends Data>(ref: QueryReference<T>): Promise<Iterable<Entity<T>>>;
23
- subscribeQuery(): Unsubscriber;
16
+ getDocument<T extends Data>(ref: DocumentReference<T>): Promise<OptionalEntity<T>>;
17
+ subscribeDocument(): Unsubscribe;
18
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): Promise<string>;
19
+ setDocument<T extends Data>(ref: DocumentReference<T>, data: T): Promise<void>;
20
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): Promise<void>;
21
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): Promise<void>;
22
+ getQuery<T extends Data>(ref: QueryReference<T>): Promise<Entities<T>>;
23
+ subscribeQuery(): Unsubscribe;
24
24
  setQuery<T extends Data>(ref: QueryReference<T>, data: T): Promise<number>;
25
25
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): Promise<number>;
26
26
  deleteQuery<T extends Data>(ref: QueryReference<T>): Promise<number>;
@@ -45,13 +45,14 @@ function getQuery(firestore, ref) {
45
45
  constraints.push(firestoreLimit(limit));
46
46
  return firestoreQuery(getCollection(firestore, ref), ...constraints);
47
47
  }
48
- /** Create a set of results from a collection snapshot. */
49
- function* getResults(snapshot) {
50
- for (const s of snapshot.docs)
51
- yield { ...s.data(), id: s.id };
48
+ function getEntities(snapshot) {
49
+ return snapshot.docs.map(getEntity);
52
50
  }
53
- /** Get a result from a document snapshot. */
54
- function getResult(snapshot) {
51
+ function getEntity(snapshot) {
52
+ const data = snapshot.data();
53
+ return { ...data, id: snapshot.id };
54
+ }
55
+ function getOptionalData(snapshot) {
55
56
  const data = snapshot.data();
56
57
  return data ? { ...data, id: snapshot.id } : null;
57
58
  }
@@ -87,28 +88,28 @@ export class FirestoreClientProvider extends Provider {
87
88
  super();
88
89
  this.firestore = firestore;
89
90
  }
90
- async get(ref) {
91
- return getResult(await getDoc(getDocument(this.firestore, ref)));
91
+ async getDocument(ref) {
92
+ return getOptionalData(await getDoc(getDocument(this.firestore, ref)));
92
93
  }
93
- subscribe() {
94
+ subscribeDocument() {
94
95
  throw new UnsupportedError("FirestoreLiteProvider does not support realtime subscriptions");
95
96
  }
96
- async add(ref, data) {
97
+ async addDocument(ref, data) {
97
98
  const reference = await addDoc(getCollection(this.firestore, ref), data);
98
99
  return reference.id;
99
100
  }
100
- async set(ref, data) {
101
+ async setDocument(ref, data) {
101
102
  await setDoc(getDocument(this.firestore, ref), data);
102
103
  }
103
- async update(ref, update) {
104
+ async updateDocument(ref, update) {
104
105
  const fieldValues = Object.fromEntries(yieldFieldValues(update));
105
106
  await updateDoc(getDocument(this.firestore, ref), fieldValues);
106
107
  }
107
- async delete(ref) {
108
+ async deleteDocument(ref) {
108
109
  await deleteDoc(getDocument(this.firestore, ref));
109
110
  }
110
111
  async getQuery(ref) {
111
- return getResults(await getDocs(getQuery(this.firestore, ref)));
112
+ return getEntities(await getDocs(getQuery(this.firestore, ref)));
112
113
  }
113
114
  subscribeQuery() {
114
115
  throw new UnsupportedError("FirestoreLiteProvider does not support realtime subscriptions");
@@ -1,9 +1,10 @@
1
1
  import { Firestore } from "@google-cloud/firestore";
2
2
  import type { DocumentReference, QueryReference } from "../../db/Reference.js";
3
- import type { Data, Result, Entity } from "../../util/data.js";
3
+ import type { Data, Entities, OptionalEntity } from "../../util/data.js";
4
+ import type { Unsubscribe } from "../../observe/Observable.js";
4
5
  import { AsynchronousProvider, Provider } from "../../provider/Provider.js";
5
6
  import { DataUpdate } from "../../update/DataUpdate.js";
6
- import { Observer, Unsubscriber } from "../../util/observe.js";
7
+ import { Observer } from "../../observe/Observer.js";
7
8
  /**
8
9
  * Firestore server database provider.
9
10
  * - Works with the Firebase Admin SDK for Node.JS
@@ -11,14 +12,14 @@ import { Observer, Unsubscriber } from "../../util/observe.js";
11
12
  export declare class FirestoreServerProvider extends Provider implements AsynchronousProvider {
12
13
  readonly firestore: Firestore;
13
14
  constructor(firestore?: Firestore);
14
- get<T extends Data>(ref: DocumentReference<T>): Promise<Result<Entity<T>>>;
15
- subscribe<T extends Data>(ref: DocumentReference<T>, observer: Observer<Result<Entity<T>>>): Unsubscriber;
16
- add<T extends Data>(ref: QueryReference<T>, data: T): Promise<string>;
17
- set<T extends Data>(ref: DocumentReference<T>, data: T): Promise<void>;
18
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): Promise<void>;
19
- delete<T extends Data>(ref: DocumentReference<T>): Promise<void>;
20
- getQuery<T extends Data>(ref: QueryReference<T>): Promise<Iterable<Entity<T>>>;
21
- subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Iterable<Entity<T>>>): Unsubscriber;
15
+ getDocument<T extends Data>(ref: DocumentReference<T>): Promise<OptionalEntity<T>>;
16
+ subscribeDocument<T extends Data>(ref: DocumentReference<T>, observer: Observer<OptionalEntity<T>>): Unsubscribe;
17
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): Promise<string>;
18
+ setDocument<T extends Data>(ref: DocumentReference<T>, data: T): Promise<void>;
19
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): Promise<void>;
20
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): Promise<void>;
21
+ getQuery<T extends Data>(ref: QueryReference<T>): Promise<Entities<T>>;
22
+ subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Entities<T>>): Unsubscribe;
22
23
  setQuery<T extends Data>(ref: QueryReference<T>, data: T): Promise<number>;
23
24
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): Promise<number>;
24
25
  deleteQuery<T extends Data>(ref: QueryReference<T>): Promise<number>;