Skip to content

Merge firestore bundles implementation without exposing public APIs #3594

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

Merged
merged 41 commits into from
Nov 12, 2020
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f347dea
Add bundle.proto d.ts and introduce IDB object stores for bundles. (…
wu-hui May 21, 2020
b0c8299
Implement a bundle reader for Web (#3097)
wu-hui Jun 5, 2020
2f179bc
Enable bundle reader for Node. (#3167)
wu-hui Jun 10, 2020
d3f0ab4
Implement BundleCache for IDB and memory. (#3170)
wu-hui Jun 14, 2020
6c375b9
Merge branch 'master' into wuandy/Bundles
wu-hui Jun 24, 2020
e8b9ec2
Implement bundle features in local store. (#3200)
wu-hui Jun 25, 2020
2e73801
Merge branch 'master' into wuandy/Bundles
wu-hui Jun 26, 2020
fff6b1b
Merge branch 'master' into wuandy/Bundles
wu-hui Jun 29, 2020
3a78d7c
Fix firestore_bundle_proto rollup issue. (#3316)
wu-hui Jun 29, 2020
0bf9c73
Implement bundle loading. (#3201)
wu-hui Jul 11, 2020
2bfa185
Merge branch 'master' into wuandy/Bundles
wu-hui Jul 11, 2020
9bfb995
Bundles load from secondary tabs (#3393)
wu-hui Jul 23, 2020
a9bf16c
Merge branch 'master' into wuandy/Bundles
wu-hui Jul 24, 2020
8b8a097
Make loadBundle work with exp build (#3488)
wu-hui Jul 28, 2020
5ebf8c3
Bundle's named query resume. (#3395)
wu-hui Aug 6, 2020
8cfb471
Merge branch 'master' into wuandy/Bundles
wu-hui Aug 10, 2020
2bec6d8
Merge remote-tracking branch 'origin/wuandy/Bundles' into wuandy/Bundles
wu-hui Aug 10, 2020
0f697df
Merge with named query change.
wu-hui Aug 10, 2020
dc02c03
Add missing byte_stream_reader.ts for *_lite platforms
wu-hui Aug 10, 2020
15b96a9
Finally builds and passes
wu-hui Aug 11, 2020
b4f9936
Update query-document mapping from bundles. (#3620)
wu-hui Aug 14, 2020
ef202a1
Merge branch 'master' into wuandy/Bundles
wu-hui Aug 17, 2020
c4b0995
Introduce an umbrella target for bundled documents (#3643)
wu-hui Aug 19, 2020
4e09f58
Merge branch 'master' into wuandy/Bundles
wu-hui Oct 8, 2020
775d58a
Restore some files from master
wu-hui Oct 8, 2020
5dd5c9c
Fix build errors
wu-hui Oct 8, 2020
e53cf69
Fix lint errors
wu-hui Oct 8, 2020
4bbcdc0
Merge branch 'master' into wuandy/Bundles
wu-hui Oct 8, 2020
bd6adc6
Hide bundles from public API
wu-hui Oct 9, 2020
259160b
Fix build error.
wu-hui Oct 9, 2020
9a804fc
Add bundle proto to extern, version upgrade and make exp bundle public
wu-hui Oct 13, 2020
72fb466
Merge branch 'master' into wuandy/Bundles
wu-hui Oct 20, 2020
3b208b2
Fix lint error
wu-hui Oct 20, 2020
223bc9a
Move bundle integration tests under api/ and complete exp API (#3962)
wu-hui Oct 27, 2020
b80c880
Merge branch 'master' into wuandy/Bundles
wu-hui Oct 29, 2020
5b0526b
Bundles as free functions (#4006)
wu-hui Nov 9, 2020
089fcdd
Merge branch 'master' into wuandy/Bundles
wu-hui Nov 9, 2020
80dc41d
Address comments
wu-hui Nov 9, 2020
d4ab17f
Remove bundles from public interfaces.
wu-hui Nov 11, 2020
1b3d633
Remove bundles from public interfaces take 2.
wu-hui Nov 12, 2020
205d1c8
Merge branch 'master' into wuandy/Bundles
wu-hui Nov 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changeset/lemon-steaks-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a changeset entry to describe the size increase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


---
13 changes: 12 additions & 1 deletion integration/firestore/firebase_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,16 @@ const Timestamp = firebase.firestore.Timestamp;
const GeoPoint = firebase.firestore.GeoPoint;
const FieldValue = firebase.firestore.FieldValue;
const Blob = firebase.firestore.Blob;
const loadBundle = firebase.firestore.loadBundle;
const namedQuery = firebase.firestore.namedQuery;

export { Firestore, FieldValue, FieldPath, Timestamp, Blob, GeoPoint };
export {
Firestore,
FieldValue,
FieldPath,
Timestamp,
Blob,
GeoPoint,
loadBundle,
namedQuery
};
13 changes: 12 additions & 1 deletion integration/firestore/firebase_export_memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,16 @@ const Timestamp = firebase.firestore.Timestamp;
const GeoPoint = firebase.firestore.GeoPoint;
const FieldValue = firebase.firestore.FieldValue;
const Blob = firebase.firestore.Blob;
const loadBundle = firebase.firestore.loadBundle;
const namedQuery = firebase.firestore.namedQuery;

export { Firestore, FieldValue, FieldPath, Timestamp, Blob, GeoPoint };
export {
Firestore,
FieldValue,
FieldPath,
Timestamp,
Blob,
GeoPoint,
loadBundle,
namedQuery
};
5 changes: 4 additions & 1 deletion packages-exp/auth-exp/index.webworker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ registerAuth(ClientPlatform.WORKER);
export function getAuth(app = getApp()): Auth {
// Unlike the other environments, we need to explicitly check if indexedDb is
// available. That means doing the whole rigamarole
const auth = _getProvider(app, _ComponentName.AUTH).getImmediate() as AuthImpl;
const auth = _getProvider(
app,
_ComponentName.AUTH
).getImmediate() as AuthImpl;

// This promise is intended to float; auth initialization happens in the
// background, meanwhile the auth object may be used by the app.
Expand Down
7 changes: 5 additions & 2 deletions packages/database/src/api/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,17 @@ export class Database implements FirebaseService {
validateUrl(apiName, 1, parsedURL);

const repoInfo = parsedURL.repoInfo;
if (!repoInfo.isCustomHost() && repoInfo.host !== this.repo_.repoInfo_.host) {
if (
!repoInfo.isCustomHost() &&
repoInfo.host !== this.repo_.repoInfo_.host
) {
fatal(
apiName +
': Host name does not match the current database: ' +
'(found ' +
repoInfo.host +
' but expected ' +
this.repo_.repoInfo_.host+
this.repo_.repoInfo_.host +
')'
);
}
Expand Down
37 changes: 37 additions & 0 deletions packages/firebase/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8285,6 +8285,43 @@ declare namespace firebase.firestore {
INTERNAL: { delete: () => Promise<void> };
}

export function loadBundle(
db: Firestore,
bundleData: ArrayBuffer | ReadableStream<ArrayBuffer> | string
): LoadBundleTask;

export function namedQuery(
db: Firestore,
name: string
): Promise<Query<DocumentData> | null>;

export interface LoadBundleTask {
onProgress(
next?: (progress: LoadBundleTaskProgress) => any,
error?: (error: Error) => any,
complete?: () => void
): void;

then<T, R>(
onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike<T>,
onRejected?: (a: Error) => R | PromiseLike<R>
): Promise<T | R>;

catch<R>(
onRejected: (a: Error) => R | PromiseLike<R>
): Promise<R | LoadBundleTaskProgress>;
}

export interface LoadBundleTaskProgress {
documentsLoaded: number;
totalDocuments: number;
bytesLoaded: number;
totalBytes: number;
taskState: TaskState;
}

export type TaskState = 'Error' | 'Running' | 'Success';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove all this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


/**
* An immutable object representing a geo point in Firestore. The geo point
* is represented as latitude/longitude pair.
Expand Down
37 changes: 37 additions & 0 deletions packages/firestore-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,43 @@ export class FirebaseFirestore {
INTERNAL: { delete: () => Promise<void> };
}

export function loadBundle(
db: FirebaseFirestore,
bundleData: ArrayBuffer | ReadableStream<ArrayBuffer> | string
): LoadBundleTask;

export function namedQuery(
db: FirebaseFirestore,
name: string
): Promise<Query<DocumentData> | null>;

export interface LoadBundleTask {
onProgress(
next?: (progress: LoadBundleTaskProgress) => any,
error?: (error: Error) => any,
complete?: () => void
): void;

then<T, R>(
onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike<T>,
onRejected?: (a: Error) => R | PromiseLike<R>
): Promise<T | R>;

catch<R>(
onRejected: (a: Error) => R | PromiseLike<R>
): Promise<R | LoadBundleTaskProgress>;
}

export interface LoadBundleTaskProgress {
documentsLoaded: number;
totalDocuments: number;
bytesLoaded: number;
totalBytes: number;
taskState: TaskState;
}

export type TaskState = 'Error' | 'Running' | 'Success';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, we should remove this from this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will keep it this way, since this is now a release PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove as discussed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


export class GeoPoint {
constructor(latitude: number, longitude: number);

Expand Down
37 changes: 37 additions & 0 deletions packages/firestore/exp-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,43 @@ export function snapshotEqual<T>(
right: DocumentSnapshot<T> | QuerySnapshot<T>
): boolean;

export interface LoadBundleTask {
onProgress(
next?: (progress: LoadBundleTaskProgress) => any,
error?: (error: Error) => any,
complete?: () => void
): void;

then<T, R>(
onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike<T>,
onRejected?: (a: Error) => R | PromiseLike<R>
): Promise<T | R>;

catch<R>(
onRejected: (a: Error) => R | PromiseLike<R>
): Promise<R | LoadBundleTaskProgress>;
}

export interface LoadBundleTaskProgress {
documentsLoaded: number;
totalDocuments: number;
bytesLoaded: number;
totalBytes: number;
taskState: TaskState;
}

export type TaskState = 'Error' | 'Running' | 'Success';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can stay. You can also just make this feature public in firestore-exp.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

export function loadBundle(
firestore: FirebaseFirestore,
bundleData: ArrayBuffer | ReadableStream<Uint8Array> | string
): LoadBundleTask;

export function namedQuery(
firestore: FirebaseFirestore,
name: string
): Promise<Query<DocumentData> | null>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


export type FirestoreErrorCode =
| 'cancelled'
| 'unknown'
Expand Down
3 changes: 1 addition & 2 deletions packages/firestore/exp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ export {
waitForPendingWrites,
disableNetwork,
enableNetwork,
terminate,
Settings
terminate
} from './src/api/database';

export {
Expand Down
3 changes: 2 additions & 1 deletion packages/firestore/exp/test/shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ import {
validateSetOptions
} from '../../src/util/input_validation';
import { Compat } from '../../src/compat/compat';
import { Firestore } from '../../src/api/database';
import { Firestore, loadBundle, namedQuery } from '../../src/api/database';

export { GeoPoint, Timestamp } from '../index';
export { loadBundle, namedQuery };

/* eslint-disable @typescript-eslint/no-explicit-any */

Expand Down
1 change: 1 addition & 0 deletions packages/firestore/externs.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"packages/webchannel-wrapper/src/index.d.ts",
"packages/util/dist/src/crypt.d.ts",
"packages/util/dist/src/environment.d.ts",
"packages/firestore/src/protos/firestore_bundle_proto.ts",
"packages/firestore/src/protos/firestore_proto_api.d.ts",
"packages/firestore/src/util/error.ts",
"packages/firestore/src/local/indexeddb_schema.ts",
Expand Down
2 changes: 2 additions & 0 deletions packages/firestore/register-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ declare module '@firebase/app-types' {
Transaction: typeof types.Transaction;
WriteBatch: typeof types.WriteBatch;
setLogLevel: typeof types.setLogLevel;
loadBundle: typeof types.loadBundle;
namedQuery: typeof types.namedQuery;
};
}
interface FirebaseApp {
Expand Down
3 changes: 2 additions & 1 deletion packages/firestore/rollup.shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ const manglePrivatePropertiesOptions = {
},
mangle: {
properties: {
regex: /^__PRIVATE_/
regex: /^__PRIVATE_/,
reserved: ['do']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just add all JS keywords here? This will fail with if and of next and it is really tough to figure out these failures.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
}
};
Expand Down
118 changes: 118 additions & 0 deletions packages/firestore/src/api/bundle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as firestore from '@firebase/firestore-types';
import { Deferred } from '../util/promise';
import { PartialObserver } from './observer';
import { debugAssert } from '../util/assert';
import { FirestoreError } from '../util/error';

export class LoadBundleTask
implements
firestore.LoadBundleTask,
PromiseLike<firestore.LoadBundleTaskProgress> {
private _progressObserver: PartialObserver<
firestore.LoadBundleTaskProgress
> = {};
private _taskCompletionResolver = new Deferred<
firestore.LoadBundleTaskProgress
>();

private _lastProgress: firestore.LoadBundleTaskProgress = {
taskState: 'Running',
totalBytes: 0,
totalDocuments: 0,
bytesLoaded: 0,
documentsLoaded: 0
};

onProgress(
next?: (progress: firestore.LoadBundleTaskProgress) => unknown,
error?: (err: Error) => unknown,
complete?: () => void
): void {
this._progressObserver = {
next,
error,
complete
};
}

catch<R>(
onRejected: (a: Error) => R | PromiseLike<R>
): Promise<R | firestore.LoadBundleTaskProgress> {
return this._taskCompletionResolver.promise.catch(onRejected);
}

then<T, R>(
onFulfilled?: (a: firestore.LoadBundleTaskProgress) => T | PromiseLike<T>,
onRejected?: (a: Error) => R | PromiseLike<R>
): Promise<T | R> {
return this._taskCompletionResolver.promise.then(onFulfilled, onRejected);
}

/**
* Notifies all observers that bundle loading has completed, with a provided
* `LoadBundleTaskProgress` object.
*/
_completeWith(progress: firestore.LoadBundleTaskProgress): void {
debugAssert(
progress.taskState === 'Success',
'Task is not completed with Success.'
);
this._updateProgress(progress);
if (this._progressObserver.complete) {
this._progressObserver.complete();
}

this._taskCompletionResolver.resolve(progress);
}

/**
* Notifies all observers that bundle loading has failed, with a provided
* `Error` as the reason.
*/
_failWith(error: FirestoreError): void {
this._lastProgress.taskState = 'Error';

if (this._progressObserver.next) {
this._progressObserver.next(this._lastProgress);
}

if (this._progressObserver.error) {
this._progressObserver.error(error);
}

this._taskCompletionResolver.reject(error);
}

/**
* Notifies a progress update of loading a bundle.
* @param progress The new progress.
*/
_updateProgress(progress: firestore.LoadBundleTaskProgress): void {
debugAssert(
this._lastProgress.taskState === 'Running',
'Cannot update progress on a completed or failed task'
);

this._lastProgress = progress;
if (this._progressObserver.next) {
this._progressObserver.next(progress);
}
}
}
Loading