-
Notifications
You must be signed in to change notification settings - Fork 930
Release Bundles for Next SDK #4352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
8d0f686
b5db566
b5cb372
08ddb93
3b1f645
5c62cde
a66c740
e9d0e86
3c747e2
ffff960
5f1b8a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@firebase/firestore": patch | ||
--- | ||
|
||
Release Bundles for Next SDK |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -278,8 +278,33 @@ export function limit(limit: number): QueryConstraint; | |
// @public | ||
export function limitToLast(limit: number): QueryConstraint; | ||
|
||
// @public | ||
export function loadBundle(firestore: FirebaseFirestore, bundleData: ReadableStream<Uint8Array> | ArrayBuffer | string): LoadBundleTask; | ||
|
||
// @public | ||
export class LoadBundleTask implements PromiseLike<LoadBundleTaskProgress> { | ||
catch<R>(onRejected: (a: Error) => R | PromiseLike<R>): Promise<R | LoadBundleTaskProgress>; | ||
_completeWith(progress: LoadBundleTaskProgress): void; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these _ methods should be tagged There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @schmidt-sebastian's script strips things with a leading underscore automatically in the d.ts file, but not in the api report. Ideally this file should be consistent with d.ts. Maybe we can extend the script to update the api report too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't have to do it in this PR of course. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Waiting for review :) #4207 |
||
_failWith(error: FirestoreError): void; | ||
onProgress(next?: (progress: LoadBundleTaskProgress) => unknown, error?: (err: Error) => unknown, complete?: () => void): void; | ||
then<T, R>(onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike<T>, onRejected?: (a: Error) => R | PromiseLike<R>): Promise<T | R>; | ||
_updateProgress(progress: LoadBundleTaskProgress): void; | ||
} | ||
|
||
// @public | ||
export interface LoadBundleTaskProgress { | ||
bytesLoaded: number; | ||
documentsLoaded: number; | ||
taskState: TaskState; | ||
totalBytes: number; | ||
totalDocuments: number; | ||
} | ||
|
||
export { LogLevel } | ||
|
||
// @public | ||
export function namedQuery(firestore: FirebaseFirestore, name: string): Promise<Query | null>; | ||
|
||
// @public | ||
export function onSnapshot<T>(reference: DocumentReference<T>, observer: { | ||
next?: (snapshot: DocumentSnapshot<T>) => void; | ||
|
@@ -463,6 +488,9 @@ export function startAt(snapshot: DocumentSnapshot_2<unknown>): QueryConstraint; | |
// @public | ||
export function startAt(...fieldValues: unknown[]): QueryConstraint; | ||
|
||
// @public | ||
export type TaskState = 'Error' | 'Running' | 'Success'; | ||
|
||
// @public | ||
export function terminate(firestore: FirebaseFirestore): Promise<void>; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,26 +15,42 @@ | |
* limitations under the License. | ||
*/ | ||
|
||
import { | ||
LoadBundleTask as ApiLoadBundleTask, | ||
LoadBundleTaskProgress | ||
} from '@firebase/firestore-types'; | ||
|
||
import { ensureFirestoreConfigured } from '../../src/exp/database'; | ||
import { Query as ExpQuery } from '../../src/exp/reference'; | ||
import { | ||
firestoreClientGetNamedQuery, | ||
firestoreClientLoadBundle | ||
} from '../core/firestore_client'; | ||
import { PartialObserver } from '../api/observer'; | ||
import { debugAssert } from '../util/assert'; | ||
import { FirestoreError } from '../util/error'; | ||
import { Deferred } from '../util/promise'; | ||
|
||
import { Query, Firestore } from './database'; | ||
import { PartialObserver } from './observer'; | ||
/** | ||
* Represents the state of bundle loading tasks. | ||
* | ||
* Both 'Error' and 'Success' are sinking state: task will abort or complete and there will | ||
* be no more updates after they are reported. | ||
*/ | ||
export type TaskState = 'Error' | 'Running' | 'Success'; | ||
|
||
export class LoadBundleTask | ||
implements ApiLoadBundleTask, PromiseLike<LoadBundleTaskProgress> { | ||
/** | ||
* Represents a progress update or a final state from loading bundles. | ||
*/ | ||
export interface LoadBundleTaskProgress { | ||
/** How many documents have been loaded. */ | ||
documentsLoaded: number; | ||
/** How many documents are in the bundle being loaded. */ | ||
totalDocuments: number; | ||
/** How many bytes have been loaded. */ | ||
bytesLoaded: number; | ||
/** How many bytes are in the bundle being loaded. */ | ||
totalBytes: number; | ||
/** Current task state. */ | ||
taskState: TaskState; | ||
} | ||
|
||
/** | ||
* Represents the task of loading a Firestore bundle. It provides progress of bundle | ||
* loading, as well as task completion and error events. | ||
* | ||
* The API is compatible with `Promise<LoadBundleTaskProgress>`. | ||
*/ | ||
export class LoadBundleTask implements PromiseLike<LoadBundleTaskProgress> { | ||
private _progressObserver: PartialObserver<LoadBundleTaskProgress> = {}; | ||
private _taskCompletionResolver = new Deferred<LoadBundleTaskProgress>(); | ||
|
||
|
@@ -46,6 +62,17 @@ export class LoadBundleTask | |
documentsLoaded: 0 | ||
}; | ||
|
||
/** | ||
* Registers functions to listen to bundle loading progress events. | ||
* @param next | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
* Called when there is a progress update from bundle loading. Typically `next` calls occur | ||
* each time a Firestore document is loaded from the bundle. | ||
* @param error | ||
* Called when an error occurs during bundle loading. The task aborts after reporting the | ||
* error, and there should be no more updates after this. | ||
* @param complete | ||
* Called when the loading task is complete. | ||
*/ | ||
onProgress( | ||
next?: (progress: LoadBundleTaskProgress) => unknown, | ||
error?: (err: Error) => unknown, | ||
|
@@ -58,12 +85,27 @@ export class LoadBundleTask | |
}; | ||
} | ||
|
||
/** | ||
* Implements the `Promise<LoadBundleTaskProgress>.catch` interface. | ||
* | ||
* @param onRejected | ||
* Called when an error occurs during bundle loading. | ||
*/ | ||
catch<R>( | ||
onRejected: (a: Error) => R | PromiseLike<R> | ||
): Promise<R | LoadBundleTaskProgress> { | ||
return this._taskCompletionResolver.promise.catch(onRejected); | ||
} | ||
|
||
/** | ||
* Implements the `Promise<LoadBundleTaskProgress>.then` interface. | ||
* | ||
* @param onFulfilled | ||
* Called on the completion of the loading task with a final `LoadBundleTaskProgress` update. | ||
* The update will always have its `taskState` set to `"Success"`. | ||
* @param onRejected | ||
* Called when an error occurs during bundle loading. | ||
*/ | ||
then<T, R>( | ||
onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike<T>, | ||
onRejected?: (a: Error) => R | PromiseLike<R> | ||
|
@@ -122,30 +164,3 @@ export class LoadBundleTask | |
} | ||
} | ||
} | ||
|
||
export function loadBundle( | ||
db: Firestore, | ||
bundleData: ArrayBuffer | ReadableStream<Uint8Array> | string | ||
): LoadBundleTask { | ||
const resultTask = new LoadBundleTask(); | ||
firestoreClientLoadBundle( | ||
ensureFirestoreConfigured(db._delegate), | ||
db._databaseId, | ||
bundleData, | ||
resultTask | ||
); | ||
return resultTask; | ||
} | ||
|
||
export function namedQuery(db: Firestore, name: string): Promise<Query | null> { | ||
return firestoreClientGetNamedQuery( | ||
ensureFirestoreConfigured(db._delegate), | ||
name | ||
).then(namedQuery => { | ||
if (!namedQuery) { | ||
return null; | ||
} | ||
|
||
return new Query(db, new ExpQuery(db._delegate, null, namedQuery.query)); | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,12 +32,15 @@ import { | |
FirestoreClient, | ||
firestoreClientDisableNetwork, | ||
firestoreClientEnableNetwork, | ||
firestoreClientGetNamedQuery, | ||
firestoreClientLoadBundle, | ||
firestoreClientWaitForPendingWrites, | ||
setOfflineComponentProvider, | ||
setOnlineComponentProvider | ||
} from '../core/firestore_client'; | ||
import { makeDatabaseInfo } from '../lite/components'; | ||
import { FirebaseFirestore as LiteFirestore } from '../lite/database'; | ||
import { Query } from '../lite/reference'; | ||
import { | ||
indexedDbClearPersistence, | ||
indexedDbStoragePrefix | ||
|
@@ -51,8 +54,8 @@ import { Code, FirestoreError } from '../util/error'; | |
import { cast } from '../util/input_validation'; | ||
import { Deferred } from '../util/promise'; | ||
|
||
import { LoadBundleTask } from './bundle'; | ||
import { PersistenceSettings, Settings } from './settings'; | ||
|
||
export { useFirestoreEmulator } from '../lite/database'; | ||
|
||
/** DOMException error code constants. */ | ||
|
@@ -460,6 +463,55 @@ export function terminate(firestore: FirebaseFirestore): Promise<void> { | |
return firestore._delete(); | ||
} | ||
|
||
/** | ||
* Loads a Firestore bundle into the local cache. | ||
* | ||
* @param firestore - The `Firestore` instance to load bundles for for. | ||
* @param bundleData - An object representing the bundle to be loaded. Valid objects are | ||
* `ArrayBuffer`, `ReadableStream<Uint8Array>` or `string`. | ||
* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This documentation style (newline versus dash) seems a bit inconsistent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
* @return | ||
* A `LoadBundleTask` object, which notifies callers with progress updates, and completion | ||
* or error events. It can be used as a `Promise<LoadBundleTaskProgress>`. | ||
*/ | ||
export function loadBundle( | ||
firestore: FirebaseFirestore, | ||
bundleData: ReadableStream<Uint8Array> | ArrayBuffer | string | ||
): LoadBundleTask { | ||
firestore = cast(firestore, FirebaseFirestore); | ||
const client = ensureFirestoreConfigured(firestore); | ||
const resultTask = new LoadBundleTask(); | ||
firestoreClientLoadBundle( | ||
client, | ||
firestore._databaseId, | ||
bundleData, | ||
resultTask | ||
); | ||
return resultTask; | ||
} | ||
|
||
/** | ||
* Reads a Firestore `Query` from local cache, identified by the given name. | ||
* | ||
* The named queries are packaged into bundles on the server side (along | ||
* with resulting documents), and loaded to local cache using `loadBundle`. Once in local | ||
* cache, use this method to extract a `Query` by name. | ||
*/ | ||
export function namedQuery( | ||
firestore: FirebaseFirestore, | ||
name: string | ||
): Promise<Query | null> { | ||
firestore = cast(firestore, FirebaseFirestore); | ||
const client = ensureFirestoreConfigured(firestore); | ||
return firestoreClientGetNamedQuery(client, name).then(namedQuery => { | ||
if (!namedQuery) { | ||
return null; | ||
} | ||
|
||
return new Query(firestore, null, namedQuery.query); | ||
}); | ||
} | ||
|
||
function verifyNotInitialized(firestore: FirebaseFirestore): void { | ||
if (firestore._initialized || firestore._terminated) { | ||
throw new FirestoreError( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably don't want Changesets for exp-only changes as they show up in the wrong release notes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Let me Remove.