Skip to content

Untangle FieldValues #3001

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 5 commits into from
May 1, 2020
Merged

Untangle FieldValues #3001

merged 5 commits into from
May 1, 2020

Conversation

schmidt-sebastian
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian commented Apr 30, 2020

This PR shaves off 6KB for all users that don't use FieldValue sentinels (in the up and coming tree-shaken world).

It does so by exposing parseData as a top-level function using it in the different FieldValue implementations to directly serialize into a FieldTransform. UserDataConverter then no longer needs to know about each specific implementation.

In order to not endlessly complicate the construction of UserDataConverter, I also removed the PreConverter, which doesn't exist on Android. It should not be needed since Rollup bundles everything into one single file, which should removes the need to avoid circular dependencies.

(*) Ideally, we should Copybara this build into Google3 to make sure that it doesn't break. Our current build has lots of circular dependencies and works in Google3.

This PR contains a lot of whitespace diff. Append "?w=1" to remove it from the view in GitHub.

@schmidt-sebastian schmidt-sebastian force-pushed the mrschmidt/userdatareader branch from 4cb9866 to df25951 Compare April 30, 2020 04:21
@google-oss-bot
Copy link
Contributor

google-oss-bot commented Apr 30, 2020

Binary Size Report

Affected SDKs

  • @firebase/firestore

    Type Base (ff53387) Head (8e5d2f9) Diff
    browser 247 kB 247 kB +89 B (+0.0%)
    esm2017 193 kB 193 kB -159 B (-0.1%)
    main 488 kB 488 kB -76 B (-0.0%)
    module 245 kB 245 kB +89 B (+0.0%)
  • @firebase/firestore/memory

    Type Base (ff53387) Head (8e5d2f9) Diff
    browser 188 kB 188 kB +89 B (+0.0%)
    esm2017 148 kB 148 kB -159 B (-0.1%)
    main 365 kB 365 kB -76 B (-0.0%)
    module 187 kB 187 kB +89 B (+0.0%)
  • firebase

    Type Base (ff53387) Head (8e5d2f9) Diff
    firebase-firestore.js 289 kB 289 kB +76 B (+0.0%)
    firebase-firestore.memory.js 231 kB 232 kB +76 B (+0.0%)
    firebase.js 823 kB 823 kB +76 B (+0.0%)

Test Logs

@@ -2586,3 +2561,7 @@ export const PublicCollectionReference = makeConstructorPrivate(
CollectionReference,
'Use firebase.firestore().collection() instead.'
);
export const PublicFieldValue = makeConstructorPrivate(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved here since want to use FieldValue in the RestWrapper, but not pull in these constants as they break tree-shaking.

@@ -499,28 +496,6 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
return this._firestoreClient.start(componentProvider, persistenceSettings);
}

private createDataReader(databaseId: DatabaseId): UserDataReader {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As alluded to in the PR transcription, UserDataReader now knows how to deal with DocumentReferences and the pre-converter is removed. This matches Android.

// update() since we need access to the Firestore instance.
return new ArrayRemoveFieldValueImpl(elements);
toFieldTransform(context: ParseContext): null {
if (context.dataSource === UserDataSource.MergeSet) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All toFieldTransform code is copied from UserDataReader.


isEqual(other: FieldValue): boolean {
// TODO(mrschmidt): Implement isEquals
return false;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think our isEqual ever worked with more complex field values since we used instance equality.

}
/** Singleton instance. */
static instance = new DeleteFieldValueImpl();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These constants break tree-shaking.

private constructor() {
super('FieldValue.serverTimestamp');
isEqual(other: FieldValue): boolean {
return other instanceof ServerTimestampFieldValueImpl;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Instanceof check since there can now be more than one ServerTimestampFieldValueImpl.

@@ -140,22 +129,34 @@ function isWrite(dataSource: UserDataSource): boolean {
}
}

interface ParseSettings {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This type is new. It basically bundles the arguments from ParseContext and allows for easier manipulation (using the new contextWith method).

export class Datastore {
// Make sure that the structural type of `Datastore` is unique.
// See https://github.com/microsoft/TypeScript/issues/5451
private _ = undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unrelated fix for compile time woes in RestWrapper... I can explain more if the GitHub issue isn't helpful. The goal is to make sure that methods that take Datastore don't accept {}.

Copy link
Contributor

@dconeybe dconeybe left a comment

Choose a reason for hiding this comment

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

LGTM

this.methodName,
childPath,
/*arrayElement=*/ false,
get path(): FieldPath | null {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a thought... would it make sense to instead just change the visibility of this.settings to "public" and make the variables of ParseSettings readonly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed some of them, but kept the ones that are used from other modules (mostly for style). I also moved DatabaseId and Serializer back into the class. These are never mutated and this allows me to get rid of the getter.

dataSource,
databaseId: this.databaseId,
serializer: this.serializer,
methodName,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason that the key name was omitted for "methodName"? If not, please add it in for readability and robustness.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a lint setting in our repo that prohibits non-shorthand property notations if they are possible.
E.g. { foo1 : foo } is allowed but since { foo: foo } is the same as { foo } we are meant to use { foo }

See also https://alligator.io/js/object-property-shorthand-es6/

Copy link
Contributor

Choose a reason for hiding this comment

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

TIL about "Object Property Value Shorthand"!

@schmidt-sebastian schmidt-sebastian merged commit 96cd91d into master May 1, 2020
scottcrossen pushed a commit that referenced this pull request May 4, 2020
@firebase firebase locked and limited conversation to collaborators Jun 1, 2020
@schmidt-sebastian schmidt-sebastian deleted the mrschmidt/userdatareader branch November 9, 2020 22:37
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants