15
15
* limitations under the License.
16
16
*/
17
17
18
+ import * as firestore from '@firebase/firestore-types' ;
19
+
18
20
import { Query } from './query' ;
19
21
import { SnapshotVersion } from './snapshot_version' ;
20
22
import { JsonProtoSerializer } from '../remote/serializer' ;
@@ -80,19 +82,14 @@ export class BundleConverter {
80
82
}
81
83
}
82
84
83
- export interface LoadBundleTaskProgress {
84
- documentsLoaded : number ;
85
- totalDocuments : number ;
86
- bytesLoaded : number ;
87
- totalBytes : number ;
88
- taskState : TaskState ;
89
- }
90
- export type TaskState = 'Error' | 'Running' | 'Success' ;
91
-
85
+ /**
86
+ * Returns a `LoadBundleTaskProgress` representing the first progress of
87
+ * loading a bundle.
88
+ */
92
89
export function initialProgress (
93
- state : TaskState ,
90
+ state : firestore . TaskState ,
94
91
metadata : BundleMetadata
95
- ) : LoadBundleTaskProgress {
92
+ ) : firestore . LoadBundleTaskProgress {
96
93
return {
97
94
taskState : state ,
98
95
documentsLoaded : state === 'Success' ? metadata . totalDocuments ! : 0 ,
@@ -103,32 +100,21 @@ export function initialProgress(
103
100
}
104
101
105
102
/* eslint-disable @typescript-eslint/no-explicit-any */
106
- export interface LoadBundleTask {
107
- onProgress (
108
- next ?: ( progress : LoadBundleTaskProgress ) => any ,
109
- error ?: ( error : Error ) => any ,
110
- complete ?: ( progress ?: LoadBundleTaskProgress ) => any
111
- ) : Promise < any > ;
112
-
113
- then (
114
- onFulfilled ?: ( a : LoadBundleTaskProgress ) => any ,
115
- onRejected ?: ( a : Error ) => any
116
- ) : Promise < any > ;
117
-
118
- catch ( onRejected : ( a : Error ) => any ) : Promise < any > ;
119
- }
120
-
121
- export class LoadBundleTaskImpl implements LoadBundleTask {
103
+ export class LoadBundleTaskImpl implements firestore . LoadBundleTask {
122
104
private progressResolver = new Deferred < any > ( ) ;
123
- private progressNext ?: ( progress : LoadBundleTaskProgress ) => any ;
105
+ private progressNext ?: ( progress : firestore . LoadBundleTaskProgress ) => any ;
124
106
private progressError ?: ( err : Error ) => any ;
125
- private progressComplete ?: ( progress ?: LoadBundleTaskProgress ) => any ;
107
+ private progressComplete ?: (
108
+ progress ?: firestore . LoadBundleTaskProgress
109
+ ) => any ;
126
110
127
111
private promiseResolver = new Deferred < any > ( ) ;
128
- private promiseFulfilled ?: ( a : LoadBundleTaskProgress ) => any ;
129
- private promiseRejected ?: ( a : Error ) => any ;
112
+ private promiseFulfilled ?: (
113
+ progress : firestore . LoadBundleTaskProgress
114
+ ) => any ;
115
+ private promiseRejected ?: ( err : Error ) => any ;
130
116
131
- private lastProgress : LoadBundleTaskProgress = {
117
+ private lastProgress : firestore . LoadBundleTaskProgress = {
132
118
taskState : 'Running' ,
133
119
totalBytes : 0 ,
134
120
totalDocuments : 0 ,
@@ -137,9 +123,9 @@ export class LoadBundleTaskImpl implements LoadBundleTask {
137
123
} ;
138
124
139
125
onProgress (
140
- next ?: ( progress : LoadBundleTaskProgress ) => any ,
126
+ next ?: ( progress : firestore . LoadBundleTaskProgress ) => any ,
141
127
error ?: ( err : Error ) => any ,
142
- complete ?: ( progress ?: LoadBundleTaskProgress ) => void
128
+ complete ?: ( progress ?: firestore . LoadBundleTaskProgress ) => void
143
129
) : Promise < any > {
144
130
this . progressNext = next ;
145
131
this . progressError = error ;
@@ -153,15 +139,20 @@ export class LoadBundleTaskImpl implements LoadBundleTask {
153
139
}
154
140
155
141
then (
156
- onFulfilled ?: ( a : LoadBundleTaskProgress ) => any ,
142
+ onFulfilled ?: ( a : firestore . LoadBundleTaskProgress ) => any ,
157
143
onRejected ?: ( a : Error ) => any
158
144
) : Promise < any > {
159
145
this . promiseFulfilled = onFulfilled ;
160
146
this . promiseRejected = onRejected ;
161
147
return this . promiseResolver . promise ;
162
148
}
149
+ /* eslint-enable @typescript-eslint/no-explicit-any */
163
150
164
- completeWith ( progress : LoadBundleTaskProgress ) : void {
151
+ /**
152
+ * Notifies the completion of loading a bundle, with a provided
153
+ * `LoadBundleTaskProgress` object.
154
+ */
155
+ completeWith ( progress : firestore . LoadBundleTaskProgress ) : void {
165
156
let result ;
166
157
if ( this . progressComplete ) {
167
158
result = this . progressComplete ( progress ) ;
@@ -175,9 +166,13 @@ export class LoadBundleTaskImpl implements LoadBundleTask {
175
166
this . promiseResolver . resolve ( result ) ;
176
167
}
177
168
169
+ /**
170
+ * Notifies a failure of loading a bundle, with a provided `Error`
171
+ * as the reason.
172
+ */
178
173
failedWith ( error : Error ) : void {
179
174
if ( this . progressNext ) {
180
- this . lastProgress ! . taskState = 'Error' ;
175
+ this . lastProgress . taskState = 'Error' ;
181
176
this . progressNext ( this . lastProgress ) ;
182
177
}
183
178
@@ -194,44 +189,65 @@ export class LoadBundleTaskImpl implements LoadBundleTask {
194
189
this . promiseResolver . reject ( result ) ;
195
190
}
196
191
197
- updateProgress ( progress : LoadBundleTaskProgress ) : void {
192
+ /**
193
+ * Notifies a progress update of loading a bundle.
194
+ * @param progress The new progress.
195
+ */
196
+ updateProgress ( progress : firestore . LoadBundleTaskProgress ) : void {
198
197
this . lastProgress = progress ;
199
198
if ( this . progressNext ) {
200
199
this . progressNext ( progress ) ;
201
200
}
202
201
}
203
202
}
204
- /* eslint-enable @typescript-eslint/no-explicit-any */
205
203
206
204
export class LoadResult {
207
205
constructor (
208
- readonly progress : LoadBundleTaskProgress ,
206
+ readonly progress : firestore . LoadBundleTaskProgress ,
209
207
readonly changedDocs ?: MaybeDocumentMap
210
208
) { }
211
209
}
212
210
211
+ /**
212
+ * A class to process the elements from a bundle, load them into local
213
+ * storage and provide progress update while loading.
214
+ */
213
215
export class BundleLoader {
214
- private progress : LoadBundleTaskProgress ;
216
+ /** The current progress of loading */
217
+ private progress : firestore . LoadBundleTaskProgress ;
218
+ /**
219
+ * The threshold multiplier used to determine whether enough elements are
220
+ * batched to be loaded, and a progress update is needed.
221
+ */
215
222
private step = 0.01 ;
223
+ /** Batched queries to be saved into storage */
216
224
private queries : bundleProto . NamedQuery [ ] = [ ] ;
225
+ /** Batched documents to be saved into storage */
217
226
private documents : BundledDocuments = [ ] ;
227
+ /** How many bytes in the bundle are being batched. */
218
228
private bytesIncrement = 0 ;
229
+ /** How many documents in the bundle are being batched. */
219
230
private documentsIncrement = 0 ;
231
+ /**
232
+ * A BundleDocumentMetadata is added to the loader, it is saved here while
233
+ * we wait for the actual document.
234
+ */
220
235
private unpairedDocumentMetadata : bundleProto . BundledDocumentMetadata | null = null ;
221
236
222
237
constructor (
223
238
private metadata : bundleProto . BundleMetadata ,
224
239
private localStore : LocalStore
225
240
) {
226
- this . progress = {
227
- documentsLoaded : 0 ,
228
- totalDocuments : metadata . totalDocuments ! ,
229
- bytesLoaded : 0 ,
230
- totalBytes : metadata . totalBytes ! ,
231
- taskState : 'Running'
232
- } ;
241
+ this . progress = initialProgress ( 'Running' , metadata ) ;
233
242
}
234
243
244
+ /**
245
+ * Adds an element from the bundle to the loader.
246
+ *
247
+ * If adding this element leads to actually saving the batched elements into
248
+ * storage, the returned promise will resolve to a `LoadResult`, otherwise
249
+ * it will resolve to null.
250
+ */
235
251
addSizedElement ( element : SizedBundleElement ) : Promise < LoadResult | null > {
236
252
debugAssert ( ! element . isBundleMetadata ( ) , 'Unexpected bundle metadata.' ) ;
237
253
@@ -293,7 +309,10 @@ export class BundleLoader {
293
309
return new LoadResult ( { ...this . progress } , changedDocs ) ;
294
310
}
295
311
296
- async complete ( ) : Promise < LoadBundleTaskProgress > {
312
+ /**
313
+ * Update the progress to 'Success' and return the updated progress.
314
+ */
315
+ complete ( ) : firestore . LoadBundleTaskProgress {
297
316
debugAssert (
298
317
this . queries . length === 0 && this . documents . length === 0 ,
299
318
'There are more items needs to be saved but complete() is called.'
0 commit comments