shelving 1.64.0 → 1.65.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 +31 -38
  67. package/react/useDocument.js +71 -76
  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 +48 -46
  72. package/react/useQuery.js +116 -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 +1 -1
  78. package/{stream → state}/ArrayState.js +8 -10
  79. package/{stream → state}/BooleanState.d.ts +1 -1
  80. package/{stream → state}/BooleanState.js +3 -5
  81. package/{stream → state}/DataState.d.ts +3 -3
  82. package/{stream → state}/DataState.js +6 -6
  83. package/{stream → state}/ObjectState.d.ts +1 -1
  84. package/{stream → state}/ObjectState.js +6 -8
  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
@@ -1,8 +1,11 @@
1
1
  import type { DocumentReference, QueryReference } from "../db/Reference.js";
2
- import type { Data, Result, Entity } from "../util/data.js";
2
+ import type { Data, Entity, Entities, OptionalEntity } from "../util/data.js";
3
3
  import type { DataUpdate } from "../update/DataUpdate.js";
4
- import type { Dispatcher } from "../util/function.js";
5
- import { Observer, Unsubscriber } from "../util/observe.js";
4
+ import type { Dispatch } from "../util/function.js";
5
+ import type { Unsubscribe } from "../observe/Observable.js";
6
+ import { Query } from "../query/Query.js";
7
+ import { Subject } from "../observe/Subject.js";
8
+ import { PartialObserver } from "../observe/Observer.js";
6
9
  import { Provider, SynchronousProvider } from "./Provider.js";
7
10
  /**
8
11
  * Fast in-memory store for data.
@@ -12,15 +15,17 @@ import { Provider, SynchronousProvider } from "./Provider.js";
12
15
  export declare class MemoryProvider extends Provider implements SynchronousProvider {
13
16
  /** List of tables in `{ path: Table }` format. */
14
17
  private _tables;
15
- table<T extends Data>({ collection }: DocumentReference<T> | QueryReference<T>): Table<T>;
16
- get<T extends Data>(ref: DocumentReference<T>): 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): string;
19
- set<T extends Data>(ref: DocumentReference<T>, data: T): void;
20
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void;
21
- delete<T extends Data>(ref: DocumentReference<T>): void;
22
- getQuery<T extends Data>(ref: QueryReference<T>): Iterable<Entity<T>>;
23
- subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Iterable<Entity<T>>>): Unsubscriber;
18
+ getTable<T extends Data>({ collection }: DocumentReference<T> | QueryReference<T>): MemoryTable<T>;
19
+ getDocumentTime<T extends Data>(ref: DocumentReference<T>): number | undefined;
20
+ getDocument<T extends Data>(ref: DocumentReference<T>): OptionalEntity<T>;
21
+ subscribeDocument<T extends Data>(ref: DocumentReference<T>, observer: PartialObserver<OptionalEntity<T>>): Unsubscribe;
22
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): string;
23
+ setDocument<T extends Data>(ref: DocumentReference<T>, data: T): void;
24
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void;
25
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): void;
26
+ getQueryTime<T extends Data>(ref: QueryReference<T>): number | undefined;
27
+ getQuery<T extends Data>(ref: QueryReference<T>): Entities<T>;
28
+ subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: PartialObserver<Entities<T>>): Unsubscribe;
24
29
  setQuery<T extends Data>(ref: QueryReference<T>, data: T): number;
25
30
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): number;
26
31
  deleteQuery<T extends Data>(ref: QueryReference<T>): number;
@@ -29,16 +34,25 @@ export declare class MemoryProvider extends Provider implements SynchronousProvi
29
34
  * An individual table of data.
30
35
  * - Fires with an array of string IDs.
31
36
  */
32
- declare class Table<T extends Data> {
33
- protected data: Map<string, Entity<T>>;
34
- protected changes: Set<string>;
35
- protected listeners: Set<Dispatcher<[Set<string>]>>;
36
- get(id: string): Result<Entity<T>>;
37
- get entities(): Iterable<Entity<T>>;
38
- set(entity: Entity<T>): void;
39
- delete(id: string): void;
40
- fire: () => void;
41
- on(listener: Dispatcher<[Set<string>]>): Unsubscriber;
42
- off(listener: Dispatcher<[Set<string>]>): void;
37
+ export declare class MemoryTable<T extends Data> extends Subject<void> {
38
+ protected _data: Map<string, Entity<T>>;
39
+ protected _times: Map<string, number>;
40
+ protected _listeners: Set<Dispatch<[]>>;
41
+ protected _firing: boolean;
42
+ getDocumentTime(id: string): number | undefined;
43
+ getDocument(id: string): OptionalEntity<T>;
44
+ subscribeDocument(id: string, observer: PartialObserver<OptionalEntity<T>>): Unsubscribe;
45
+ addDocument(data: T): string;
46
+ setEntity(entity: Entity<T>): void;
47
+ setDocument(id: string, data: T): void;
48
+ updateDocument(id: string, update: DataUpdate<T>): void;
49
+ deleteDocument(id: string): void;
50
+ getQueryTime(query: Query<Entity<T>>): number | undefined;
51
+ getQuery(query: Query<Entity<T>>): Entities<T>;
52
+ subscribeQuery(query: Query<Entity<T>>, observer: PartialObserver<Entities<T>>): Unsubscribe;
53
+ protected _getWrites(query: Query<Entity<T>>): Iterable<Entity<T>>;
54
+ setEntities(query: Query<Entity<T>>, entities: Entities<T>): number;
55
+ setQuery(query: Query<Entity<T>>, data: T): number;
56
+ updateQuery(query: Query<Entity<T>>, update: DataUpdate<T>): number;
57
+ deleteQuery(query: Query<Entity<T>>): number;
43
58
  }
44
- export {};
@@ -1,8 +1,11 @@
1
- import { dispatchNext } from "../util/observe.js";
2
1
  import { getRandomKey } from "../util/random.js";
3
2
  import { isArrayEqual } from "../util/equal.js";
4
- import { DocumentRequiredError } from "../db/errors.js";
5
3
  import { transformProps } from "../util/transform.js";
4
+ import { Query } from "../query/Query.js";
5
+ import { RequiredError } from "../error/RequiredError.js";
6
+ import { Subject } from "../observe/Subject.js";
7
+ import { dispatchNext } from "../observe/Observer.js";
8
+ import { getArray } from "../util/array.js";
6
9
  import { Provider } from "./Provider.js";
7
10
  /**
8
11
  * Fast in-memory store for data.
@@ -16,146 +19,182 @@ export class MemoryProvider extends Provider {
16
19
  this._tables = {}; // eslint-disable-line @typescript-eslint/no-explicit-any
17
20
  }
18
21
  // Get a named collection (or create a new one).
19
- table({ collection }) {
22
+ getTable({ collection }) {
20
23
  var _a;
21
- return ((_a = this._tables)[collection] || (_a[collection] = new Table()));
24
+ return ((_a = this._tables)[collection] || (_a[collection] = new MemoryTable()));
22
25
  }
23
- get(ref) {
24
- return this.table(ref).get(ref.id);
26
+ getDocumentTime(ref) {
27
+ return this.getTable(ref).getDocumentTime(ref.id);
25
28
  }
26
- subscribe(ref, observer) {
27
- const table = this.table(ref);
28
- const id = ref.id;
29
+ getDocument(ref) {
30
+ return this.getTable(ref).getDocument(ref.id);
31
+ }
32
+ subscribeDocument(ref, observer) {
33
+ return this.getTable(ref).subscribeDocument(ref.id, observer);
34
+ }
35
+ addDocument(ref, data) {
36
+ return this.getTable(ref).addDocument(data);
37
+ }
38
+ setDocument(ref, data) {
39
+ return this.getTable(ref).setDocument(ref.id, data);
40
+ }
41
+ updateDocument(ref, update) {
42
+ return this.getTable(ref).updateDocument(ref.id, update);
43
+ }
44
+ deleteDocument(ref) {
45
+ return this.getTable(ref).deleteDocument(ref.id);
46
+ }
47
+ getQueryTime(ref) {
48
+ return this.getTable(ref).getQueryTime(ref);
49
+ }
50
+ getQuery(ref) {
51
+ return this.getTable(ref).getQuery(ref);
52
+ }
53
+ subscribeQuery(ref, observer) {
54
+ return this.getTable(ref).subscribeQuery(ref, observer);
55
+ }
56
+ setQuery(ref, data) {
57
+ return this.getTable(ref).setQuery(ref, data);
58
+ }
59
+ updateQuery(ref, update) {
60
+ return this.getTable(ref).updateQuery(ref, update);
61
+ }
62
+ deleteQuery(ref) {
63
+ return this.getTable(ref).deleteQuery(ref);
64
+ }
65
+ }
66
+ /**
67
+ * An individual table of data.
68
+ * - Fires with an array of string IDs.
69
+ */
70
+ export class MemoryTable extends Subject {
71
+ constructor() {
72
+ super(...arguments);
73
+ this._data = new Map();
74
+ this._times = new Map();
75
+ this._listeners = new Set();
76
+ this._firing = false;
77
+ }
78
+ getDocumentTime(id) {
79
+ return this._times.get(id);
80
+ }
81
+ getDocument(id) {
82
+ return this._data.get(id) || null;
83
+ }
84
+ subscribeDocument(id, observer) {
29
85
  // Call next() immediately with initial results.
30
- dispatchNext(observer, table.get(id));
86
+ let last = this.getDocument(id);
87
+ dispatchNext(observer, last);
31
88
  // Call next() every time the collection changes.
32
- return table.on(changes => {
33
- changes.has(id) && dispatchNext(observer, table.get(id));
89
+ return this.subscribe(() => {
90
+ const next = this.getDocument(id);
91
+ if (next !== last) {
92
+ last = next;
93
+ dispatchNext(observer, last);
94
+ }
34
95
  });
35
96
  }
36
- add(ref, data) {
37
- const table = this.table(ref);
97
+ addDocument(data) {
38
98
  let id = getRandomKey();
39
- while (table.get(id))
99
+ while (this._data.has(id))
40
100
  id = getRandomKey(); // Regenerate ID until unique.
41
- table.set({ ...data, id });
101
+ this.setEntity({ ...data, id });
42
102
  return id;
43
103
  }
44
- set(ref, data) {
45
- const table = this.table(ref);
46
- const id = ref.id;
47
- table.set({ ...data, id });
104
+ setEntity(entity) {
105
+ const id = entity.id;
106
+ this._data.set(id, entity);
107
+ this._times.set(id, Date.now());
108
+ this.next();
48
109
  }
49
- update(ref, update) {
50
- const table = this.table(ref);
51
- const id = ref.id;
52
- const entity = table.get(id);
110
+ setDocument(id, data) {
111
+ this.setEntity({ ...data, id });
112
+ }
113
+ updateDocument(id, update) {
114
+ const entity = this._data.get(id);
53
115
  if (!entity)
54
- throw new DocumentRequiredError(ref);
55
- table.set({ ...entity, ...Object.fromEntries(transformProps(entity, update.updates)), id: entity.id });
116
+ throw new RequiredError(`Document "${id}" does not exist`);
117
+ this.setEntity({ ...entity, ...Object.fromEntries(transformProps(entity, update.updates)), id });
56
118
  }
57
- delete(ref) {
58
- const table = this.table(ref);
59
- const id = ref.id;
60
- table.delete(id);
119
+ deleteDocument(id) {
120
+ this._data.delete(id);
121
+ this._times.set(id, Date.now());
122
+ this.next();
61
123
  }
62
- getQuery(ref) {
63
- return ref.transform(this.table(ref).entities);
124
+ getQueryTime(query) {
125
+ return this._times.get(_getQueryReference(query));
64
126
  }
65
- subscribeQuery(ref, observer) {
66
- const table = this.table(ref);
127
+ getQuery(query) {
128
+ return getArray(query.transform(this._data.values()));
129
+ }
130
+ subscribeQuery(query, observer) {
67
131
  // Call `next()` immediately with the initial results.
68
- let last = Array.from(ref.transform(table.entities));
132
+ let last = this.getQuery(query);
69
133
  dispatchNext(observer, last);
70
134
  // Possibly call `next()` when the collection changes if any changes affect the subscription.
71
- return table.on(() => {
72
- const next = Array.from(ref.transform(table.entities));
135
+ return this.subscribe(() => {
136
+ const next = this.getQuery(query);
73
137
  if (!isArrayEqual(last, next)) {
74
138
  last = next;
75
139
  dispatchNext(observer, last);
76
140
  }
77
141
  });
78
142
  }
79
- setQuery(ref, data) {
80
- const table = this.table(ref);
81
- // If there's a limit set: run the full query.
82
- // If there's no limit set: only need to run the filtering (more efficient because sort order doesn't matter).
143
+ _getWrites(query) {
144
+ // Queries that have no limit don't care about sorting either.
145
+ // So sorting can be skipped for performance.
146
+ return query.limit ? query.transform(this._data.values()) : query.filters.transform(this._data.values());
147
+ }
148
+ setEntities(query, entities) {
149
+ const now = Date.now();
83
150
  let count = 0;
84
- for (const { id } of ref.limit ? ref.transform(table.entities) : ref.filters.transform(table.entities)) {
85
- table.set({ ...data, id });
151
+ for (const entity of entities) {
152
+ const id = entity.id;
153
+ this._data.set(id, entity);
154
+ this._times.set(id, now);
86
155
  count++;
87
156
  }
157
+ this._times.set(_getQueryReference(query), now);
88
158
  return count;
89
159
  }
90
- updateQuery(ref, update) {
91
- const table = this.table(ref);
92
- // If there's a limit set: run the full query.
93
- // If there's no limit set: only need to run the filtering (more efficient because sort order doesn't matter).
160
+ setQuery(query, data) {
161
+ const now = Date.now();
94
162
  let count = 0;
95
- for (const entity of ref.limit ? ref.transform(table.entities) : ref.filters.transform(table.entities)) {
96
- table.set({ ...entity, ...Object.fromEntries(transformProps(entity, update.updates)), id: entity.id });
163
+ for (const { id } of this._getWrites(query)) {
164
+ this._data.set(id, { ...data, id });
165
+ this._times.set(id, now);
97
166
  count++;
98
167
  }
168
+ this._times.set(_getQueryReference(query), now);
169
+ this.next();
99
170
  return count;
100
171
  }
101
- deleteQuery(ref) {
102
- const table = this.table(ref);
103
- // If there's a limit set: run the full query.
104
- // If there's no limit set: only need to run the filtering (more efficient because sort order doesn't matter).
172
+ updateQuery(query, update) {
173
+ const now = Date.now();
105
174
  let count = 0;
106
- for (const { id } of ref.limit ? ref.transform(table.entities) : ref.filters.transform(table.entities)) {
107
- table.delete(id);
175
+ for (const entity of this._getWrites(query)) {
176
+ const id = entity.id;
177
+ this._data.set(id, { ...entity, ...Object.fromEntries(transformProps(entity, update.updates)), id });
178
+ this._times.set(id, now);
108
179
  count++;
109
180
  }
181
+ this._times.set(_getQueryReference(query), now);
182
+ this.next();
110
183
  return count;
111
184
  }
112
- }
113
- /**
114
- * An individual table of data.
115
- * - Fires with an array of string IDs.
116
- */
117
- class Table {
118
- constructor() {
119
- this.data = new Map();
120
- this.changes = new Set();
121
- this.listeners = new Set();
122
- this.fire = () => {
123
- if (this.changes.size) {
124
- for (const dispatcher of this.listeners)
125
- dispatcher(this.changes);
126
- this.changes.clear();
127
- }
128
- };
129
- }
130
- get(id) {
131
- return this.data.get(id) || null;
132
- }
133
- get entities() {
134
- return this.data.values();
135
- }
136
- set(entity) {
137
- if (entity !== this.get(entity.id)) {
138
- this.data.set(entity.id, entity);
139
- // Queue `this.fire()` if we've created a change.
140
- if (!this.changes.size)
141
- queueMicrotask(this.fire);
142
- this.changes.add(entity.id);
143
- }
144
- }
145
- delete(id) {
146
- if (this.data.has(id)) {
147
- this.data.delete(id);
148
- // Queue `this.fire()` if we've created a change.
149
- if (!this.changes.size)
150
- queueMicrotask(this.fire);
151
- this.changes.add(id);
185
+ deleteQuery(query) {
186
+ let count = 0;
187
+ for (const { id } of this._getWrites(query)) {
188
+ this._data.delete(id);
189
+ this._times.set(id, Date.now());
190
+ count++;
152
191
  }
192
+ this._times.set(_getQueryReference(query), Date.now());
193
+ this.next();
194
+ return count;
153
195
  }
154
- on(listener) {
155
- this.listeners.add(listener);
156
- return this.off.bind(this, listener);
157
- }
158
- off(listener) {
159
- this.listeners.delete(listener);
160
- }
196
+ }
197
+ function _getQueryReference(query) {
198
+ // Queries that have no limit don't care about sorting either.
199
+ return query.limit ? `filters=${query.filters.toString()}` : Query.prototype.toString.call(query);
161
200
  }
@@ -1,7 +1,8 @@
1
1
  import type { DocumentReference, QueryReference } from "../db/Reference.js";
2
+ import type { Unsubscribe } from "../observe/Observable.js";
3
+ import type { PartialObserver } from "../observe/Observer.js";
2
4
  import type { DataUpdate } from "../update/DataUpdate.js";
3
- import type { Data, Result, Entity } from "../util/data.js";
4
- import type { Observer, Unsubscriber } from "../util/observe.js";
5
+ import type { Data, Entities, OptionalEntity } from "../util/data.js";
5
6
  /** Provides access to data (e.g. IndexedDB, Firebase, or in-memory cache providers). */
6
7
  export declare abstract class Provider {
7
8
  /**
@@ -10,7 +11,7 @@ export declare abstract class Provider {
10
11
  * @param ref Document reference specifying which document to get.
11
12
  * @return The document object, or `undefined` if it doesn't exist.
12
13
  */
13
- abstract get<T extends Data>(ref: DocumentReference<T>): Result<Entity<T>> | PromiseLike<Result<Entity<T>>>;
14
+ abstract getDocument<T extends Data>(ref: DocumentReference<T>): OptionalEntity<T> | PromiseLike<OptionalEntity<T>>;
14
15
  /**
15
16
  * Subscribe to the result of a document.
16
17
  * - `next()` is called once with the initial result, and again any time the result changes.
@@ -20,7 +21,7 @@ export declare abstract class Provider {
20
21
  *
21
22
  * @return Function that ends the subscription.
22
23
  */
23
- abstract subscribe<T extends Data>(ref: DocumentReference<T>, observer: Observer<Result<Entity<T>>>): Unsubscriber;
24
+ abstract subscribeDocument<T extends Data>(ref: DocumentReference<T>, observer: PartialObserver<OptionalEntity<T>>): Unsubscribe;
24
25
  /**
25
26
  * Create a new document with a random ID.
26
27
  * - Created document is guaranteed to have a unique ID.
@@ -30,7 +31,7 @@ export declare abstract class Provider {
30
31
  *
31
32
  * @return String ID for the created document (possibly promised).
32
33
  */
33
- abstract add<T extends Data>(ref: QueryReference<T>, data: T): string | PromiseLike<string>;
34
+ abstract addDocument<T extends Data>(ref: QueryReference<T>, data: T): string | PromiseLike<string>;
34
35
  /**
35
36
  * Set the data a document.
36
37
  * - If the document exists, set the value of it.
@@ -41,7 +42,7 @@ export declare abstract class Provider {
41
42
  *
42
43
  * @throws Error If a `Update` was provided but the document does not exist (ideally a `RequiredError` but may be provider-specific).
43
44
  */
44
- abstract set<T extends Data>(ref: DocumentReference<T>, data: T): void | PromiseLike<void>;
45
+ abstract setDocument<T extends Data>(ref: DocumentReference<T>, data: T): void | PromiseLike<void>;
45
46
  /**
46
47
  * Update the data an existing document.
47
48
  *
@@ -50,19 +51,19 @@ export declare abstract class Provider {
50
51
  *
51
52
  * @throws Error If the document does not exist (ideally a `RequiredError` but may be provider-specific).
52
53
  */
53
- abstract update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void | PromiseLike<void>;
54
+ abstract updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void | PromiseLike<void>;
54
55
  /**
55
56
  * Delete a specified document.
56
57
  * @param ref Document reference specifying which document to delete.
57
58
  */
58
- abstract delete<T extends Data>(ref: DocumentReference<T>): void | PromiseLike<void>;
59
+ abstract deleteDocument<T extends Data>(ref: DocumentReference<T>): void | PromiseLike<void>;
59
60
  /**
60
61
  * Get all matching documents.
61
62
  *
62
63
  * @param ref Documents reference specifying which collection to get documents from.
63
64
  * @return Set of results in `id: data` format.
64
65
  */
65
- abstract getQuery<T extends Data>(ref: QueryReference<T>): Iterable<Entity<T>> | PromiseLike<Iterable<Entity<T>>>;
66
+ abstract getQuery<T extends Data>(ref: QueryReference<T>): Entities<T> | PromiseLike<Entities<T>>;
66
67
  /**
67
68
  * Subscribe to all matching documents.
68
69
  * - `next()` is called once with the initial results, and again any time the results change.
@@ -72,7 +73,7 @@ export declare abstract class Provider {
72
73
  *
73
74
  * @return Function that ends the subscription.
74
75
  */
75
- abstract subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Iterable<Entity<T>>>): Unsubscriber;
76
+ abstract subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: PartialObserver<Entities<T>>): Unsubscribe;
76
77
  /**
77
78
  * Set the data of all matching documents.
78
79
  *
@@ -98,24 +99,24 @@ export declare abstract class Provider {
98
99
  }
99
100
  /** Provider with a fully synchronous interface */
100
101
  export interface SynchronousProvider extends Provider {
101
- get<T extends Data>(ref: DocumentReference<T>): Result<Entity<T>>;
102
- add<T extends Data>(ref: QueryReference<T>, data: T): string;
103
- set<T extends Data>(ref: DocumentReference<T>, value: T): void;
104
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void;
105
- delete<T extends Data>(ref: DocumentReference<T>): void;
106
- getQuery<T extends Data>(ref: QueryReference<T>): Iterable<Entity<T>>;
102
+ getDocument<T extends Data>(ref: DocumentReference<T>): OptionalEntity<T>;
103
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): string;
104
+ setDocument<T extends Data>(ref: DocumentReference<T>, value: T): void;
105
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void;
106
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): void;
107
+ getQuery<T extends Data>(ref: QueryReference<T>): Entities<T>;
107
108
  setQuery<T extends Data>(ref: QueryReference<T>, value: T): number;
108
109
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): number;
109
110
  deleteQuery<T extends Data>(ref: QueryReference<T>): number;
110
111
  }
111
112
  /** Provider with a fully asynchronous interface */
112
113
  export interface AsynchronousProvider extends Provider {
113
- get<T extends Data>(ref: DocumentReference<T>): PromiseLike<Result<Entity<T>>>;
114
- add<T extends Data>(ref: QueryReference<T>, data: T): PromiseLike<string>;
115
- set<T extends Data>(ref: DocumentReference<T>, value: T): PromiseLike<void>;
116
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): PromiseLike<void>;
117
- delete<T extends Data>(ref: DocumentReference<T>): PromiseLike<void>;
118
- getQuery<T extends Data>(ref: QueryReference<T>): PromiseLike<Iterable<Entity<T>>>;
114
+ getDocument<T extends Data>(ref: DocumentReference<T>): PromiseLike<OptionalEntity<T>>;
115
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): PromiseLike<string>;
116
+ setDocument<T extends Data>(ref: DocumentReference<T>, value: T): PromiseLike<void>;
117
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): PromiseLike<void>;
118
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): PromiseLike<void>;
119
+ getQuery<T extends Data>(ref: QueryReference<T>): PromiseLike<Entities<T>>;
119
120
  setQuery<T extends Data>(ref: QueryReference<T>, value: T): PromiseLike<number>;
120
121
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): PromiseLike<number>;
121
122
  deleteQuery<T extends Data>(ref: QueryReference<T>): PromiseLike<number>;
@@ -1,26 +1,35 @@
1
- import type { Data, Result, Entity } from "../util/data.js";
1
+ import type { Data, Entities, OptionalEntity } from "../util/data.js";
2
2
  import type { DocumentReference, QueryReference } from "../db/Reference.js";
3
3
  import type { DataUpdate } from "../update/DataUpdate.js";
4
- import type { Observer, Unsubscriber } from "../util/observe.js";
5
4
  import type { Class } from "../util/class.js";
6
- import { Provider } from "./Provider.js";
5
+ import type { PartialObserver } from "../observe/Observer.js";
6
+ import type { Unsubscribe } from "../observe/Observable.js";
7
+ import { AsynchronousProvider, Provider, SynchronousProvider } from "./Provider.js";
7
8
  /**
8
9
  * Pass all reads and writes through to a source provider.
9
10
  */
10
11
  export declare class ThroughProvider extends Provider {
11
12
  readonly source: Provider;
12
13
  constructor(source: Provider);
13
- get<T extends Data>(ref: DocumentReference<T>): Result<Entity<T>> | PromiseLike<Result<Entity<T>>>;
14
- subscribe<T extends Data>(ref: DocumentReference<T>, observer: Observer<Result<Entity<T>>>): Unsubscriber;
15
- add<T extends Data>(ref: QueryReference<T>, data: T): string | PromiseLike<string>;
16
- set<T extends Data>(ref: DocumentReference<T>, data: T): void | PromiseLike<void>;
17
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void | PromiseLike<void>;
18
- delete<T extends Data>(ref: DocumentReference<T>): void | PromiseLike<void>;
19
- getQuery<T extends Data>(ref: QueryReference<T>): Iterable<Entity<T>> | PromiseLike<Iterable<Entity<T>>>;
20
- subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Iterable<Entity<T>>>): Unsubscriber;
14
+ getDocument<T extends Data>(ref: DocumentReference<T>): OptionalEntity<T> | PromiseLike<OptionalEntity<T>>;
15
+ subscribeDocument<T extends Data>(ref: DocumentReference<T>, observer: PartialObserver<OptionalEntity<T>>): Unsubscribe;
16
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): string | PromiseLike<string>;
17
+ setDocument<T extends Data>(ref: DocumentReference<T>, data: T): void | PromiseLike<void>;
18
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void | PromiseLike<void>;
19
+ deleteDocument<T extends Data>(ref: DocumentReference<T>): void | PromiseLike<void>;
20
+ getQuery<T extends Data>(ref: QueryReference<T>): Entities<T> | PromiseLike<Entities<T>>;
21
+ subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: PartialObserver<Entities<T>>): Unsubscribe;
21
22
  setQuery<T extends Data>(ref: QueryReference<T>, data: T): number | PromiseLike<number>;
22
23
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): number | PromiseLike<number>;
23
24
  deleteQuery<T extends Data>(ref: QueryReference<T>): number | PromiseLike<number>;
24
25
  }
26
+ /** Synchronous through provider must have synchronous source provider. */
27
+ export interface SynchronousThroughProvider extends SynchronousProvider {
28
+ new (source: SynchronousProvider): SynchronousProvider;
29
+ }
30
+ /** Asynchronous through provider must have asynchronous source provider. */
31
+ export interface AsynchronousThroughProvider extends AsynchronousProvider {
32
+ new (source: AsynchronousProvider): AsynchronousProvider;
33
+ }
25
34
  /** Find a specific source provider in a database's provider stack. */
26
35
  export declare function findSourceProvider<P extends Provider>(provider: Provider, type: Class<P>): P;
@@ -8,23 +8,23 @@ export class ThroughProvider extends Provider {
8
8
  super();
9
9
  this.source = source;
10
10
  }
11
- get(ref) {
12
- return this.source.get(ref);
11
+ getDocument(ref) {
12
+ return this.source.getDocument(ref);
13
13
  }
14
- subscribe(ref, observer) {
15
- return this.source.subscribe(ref, observer);
14
+ subscribeDocument(ref, observer) {
15
+ return this.source.subscribeDocument(ref, observer);
16
16
  }
17
- add(ref, data) {
18
- return this.source.add(ref, data);
17
+ addDocument(ref, data) {
18
+ return this.source.addDocument(ref, data);
19
19
  }
20
- set(ref, data) {
21
- return this.source.set(ref, data);
20
+ setDocument(ref, data) {
21
+ return this.source.setDocument(ref, data);
22
22
  }
23
- update(ref, update) {
24
- return this.source.update(ref, update);
23
+ updateDocument(ref, update) {
24
+ return this.source.updateDocument(ref, update);
25
25
  }
26
- delete(ref) {
27
- return this.source.delete(ref);
26
+ deleteDocument(ref) {
27
+ return this.source.deleteDocument(ref);
28
28
  }
29
29
  getQuery(ref) {
30
30
  return this.source.getQuery(ref);
@@ -1,17 +1,18 @@
1
1
  import type { DocumentReference, QueryReference } from "../db/Reference.js";
2
- import type { Data, Result, Entity } from "../util/data.js";
2
+ import type { Data, OptionalData, OptionalEntity, Entities } from "../util/data.js";
3
3
  import type { DataUpdate } from "../update/DataUpdate.js";
4
- import { Observer, Unsubscriber } from "../util/observe.js";
4
+ import type { PartialObserver } from "../observe/Observer.js";
5
+ import type { Unsubscribe } from "../observe/Observable.js";
5
6
  import { ThroughProvider } from "./ThroughProvider.js";
6
7
  /** Validates any values that are read from or written to a source provider. */
7
8
  export declare class ValidationProvider extends ThroughProvider {
8
- get<T extends Data>(ref: DocumentReference<T>): Result<Entity<T>> | PromiseLike<Result<Entity<T>>>;
9
- subscribe<T extends Data>(ref: DocumentReference<T>, observer: Observer<Result>): Unsubscriber;
10
- add<T extends Data>(ref: QueryReference<T>, data: T): string | PromiseLike<string>;
11
- set<T extends Data>(ref: DocumentReference<T>, value: T): void | PromiseLike<void>;
12
- update<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void | PromiseLike<void>;
13
- getQuery<T extends Data>(ref: QueryReference<T>): Iterable<Entity<T>> | PromiseLike<Iterable<Entity<T>>>;
14
- subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: Observer<Iterable<Entity<T>>>): Unsubscriber;
9
+ getDocument<T extends Data>(ref: DocumentReference<T>): OptionalEntity<T> | PromiseLike<OptionalEntity<T>>;
10
+ subscribeDocument<T extends Data>(ref: DocumentReference<T>, observer: PartialObserver<OptionalData>): Unsubscribe;
11
+ addDocument<T extends Data>(ref: QueryReference<T>, data: T): string | PromiseLike<string>;
12
+ setDocument<T extends Data>(ref: DocumentReference<T>, value: T): void | PromiseLike<void>;
13
+ updateDocument<T extends Data>(ref: DocumentReference<T>, update: DataUpdate<T>): void | PromiseLike<void>;
14
+ getQuery<T extends Data>(ref: QueryReference<T>): Entities<T> | PromiseLike<Entities<T>>;
15
+ subscribeQuery<T extends Data>(ref: QueryReference<T>, observer: PartialObserver<Entities<T>>): Unsubscribe;
15
16
  setQuery<T extends Data>(ref: QueryReference<T>, value: T): number | PromiseLike<number>;
16
17
  updateQuery<T extends Data>(ref: QueryReference<T>, update: DataUpdate<T>): number | PromiseLike<number>;
17
18
  }