Skip to content

Commit 338dbfa

Browse files
Tree-Shakeable Serialization (#3231)
1 parent d525b69 commit 338dbfa

File tree

16 files changed

+2155
-3945
lines changed

16 files changed

+2155
-3945
lines changed

packages/firestore/lite/test/dependencies.json

Lines changed: 943 additions & 2906 deletions
Large diffs are not rendered by default.

packages/firestore/src/api/user_data_reader.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ import { Code, FirestoreError } from '../util/error';
3737
import { isPlainObject, valueDescription } from '../util/input_validation';
3838
import { Dict, forEach, isEmpty } from '../util/obj';
3939
import { ObjectValue, ObjectValueBuilder } from '../model/object_value';
40-
import { JsonProtoSerializer } from '../remote/serializer';
40+
import {
41+
JsonProtoSerializer,
42+
toBytes,
43+
toNumber,
44+
toResourceName,
45+
toTimestamp
46+
} from '../remote/serializer';
4147
import { Blob } from './blob';
4248
import { BaseFieldPath, fromDotSeparatedString } from './field_path';
4349
import { DeleteFieldValueImpl, SerializableFieldValue } from './field_value';
@@ -647,14 +653,16 @@ function parseScalarValue(
647653
if (value === null) {
648654
return { nullValue: 'NULL_VALUE' };
649655
} else if (typeof value === 'number') {
650-
return context.serializer.toNumber(value);
656+
return toNumber(context.serializer, value);
651657
} else if (typeof value === 'boolean') {
652658
return { booleanValue: value };
653659
} else if (typeof value === 'string') {
654660
return { stringValue: value };
655661
} else if (value instanceof Date) {
656662
const timestamp = Timestamp.fromDate(value);
657-
return { timestampValue: context.serializer.toTimestamp(timestamp) };
663+
return {
664+
timestampValue: toTimestamp(context.serializer, timestamp)
665+
};
658666
} else if (value instanceof Timestamp) {
659667
// Firestore backend truncates precision down to microseconds. To ensure
660668
// offline mode works the same with regards to truncation, perform the
@@ -663,7 +671,9 @@ function parseScalarValue(
663671
value.seconds,
664672
Math.floor(value.nanoseconds / 1000) * 1000
665673
);
666-
return { timestampValue: context.serializer.toTimestamp(timestamp) };
674+
return {
675+
timestampValue: toTimestamp(context.serializer, timestamp)
676+
};
667677
} else if (value instanceof GeoPoint) {
668678
return {
669679
geoPointValue: {
@@ -672,7 +682,7 @@ function parseScalarValue(
672682
}
673683
};
674684
} else if (value instanceof Blob) {
675-
return { bytesValue: context.serializer.toBytes(value) };
685+
return { bytesValue: toBytes(context.serializer, value) };
676686
} else if (value instanceof DocumentKeyReference) {
677687
const thisDb = context.databaseId;
678688
const otherDb = value._databaseId;
@@ -684,9 +694,9 @@ function parseScalarValue(
684694
);
685695
}
686696
return {
687-
referenceValue: context.serializer.toResourceName(
688-
value._key.path,
689-
value._databaseId
697+
referenceValue: toResourceName(
698+
value._databaseId || context.databaseId,
699+
value._key.path
690700
)
691701
};
692702
} else if (value === undefined && context.ignoreUndefinedProperties) {

packages/firestore/src/local/indexeddb_schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ export class DbMutationBatch {
483483
/**
484484
* A list of mutations to apply. All mutations will be applied atomically.
485485
*
486-
* Mutations are serialized via JsonProtoSerializer.toMutation().
486+
* Mutations are serialized via toMutation().
487487
*/
488488
public mutations: api.Write[]
489489
) {}

packages/firestore/src/local/local_serializer.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,17 @@ import {
2626
import { DocumentKey } from '../model/document_key';
2727
import { MutationBatch } from '../model/mutation_batch';
2828
import * as api from '../protos/firestore_proto_api';
29-
import { JsonProtoSerializer } from '../remote/serializer';
29+
import {
30+
fromDocument,
31+
fromDocumentsTarget,
32+
fromMutation,
33+
fromQueryTarget,
34+
JsonProtoSerializer,
35+
toDocument,
36+
toDocumentsTarget,
37+
toMutation,
38+
toQueryTarget
39+
} from '../remote/serializer';
3040
import { debugAssert, fail } from '../util/assert';
3141
import { ByteString } from '../util/byte_string';
3242
import { Target } from '../core/target';
@@ -49,7 +59,8 @@ export class LocalSerializer {
4959
/** Decodes a remote document from storage locally to a Document. */
5060
fromDbRemoteDocument(remoteDoc: DbRemoteDocument): MaybeDocument {
5161
if (remoteDoc.document) {
52-
return this.remoteSerializer.fromDocument(
62+
return fromDocument(
63+
this.remoteSerializer,
5364
remoteDoc.document,
5465
!!remoteDoc.hasCommittedMutations
5566
);
@@ -76,7 +87,7 @@ export class LocalSerializer {
7687
const dbReadTime = this.toDbTimestampKey(readTime);
7788
const parentPath = maybeDoc.key.path.popLast().toArray();
7889
if (maybeDoc instanceof Document) {
79-
const doc = this.remoteSerializer.toDocument(maybeDoc);
90+
const doc = toDocument(this.remoteSerializer, maybeDoc);
8091
const hasCommittedMutations = maybeDoc.hasCommittedMutations;
8192
return new DbRemoteDocument(
8293
/* unknownDocument= */ null,
@@ -140,10 +151,10 @@ export class LocalSerializer {
140151
/** Encodes a batch of mutations into a DbMutationBatch for local storage. */
141152
toDbMutationBatch(userId: string, batch: MutationBatch): DbMutationBatch {
142153
const serializedBaseMutations = batch.baseMutations.map(m =>
143-
this.remoteSerializer.toMutation(m)
154+
toMutation(this.remoteSerializer, m)
144155
);
145156
const serializedMutations = batch.mutations.map(m =>
146-
this.remoteSerializer.toMutation(m)
157+
toMutation(this.remoteSerializer, m)
147158
);
148159
return new DbMutationBatch(
149160
userId,
@@ -157,10 +168,10 @@ export class LocalSerializer {
157168
/** Decodes a DbMutationBatch into a MutationBatch */
158169
fromDbMutationBatch(dbBatch: DbMutationBatch): MutationBatch {
159170
const baseMutations = (dbBatch.baseMutations || []).map(m =>
160-
this.remoteSerializer.fromMutation(m)
171+
fromMutation(this.remoteSerializer, m)
161172
);
162173
const mutations = dbBatch.mutations.map(m =>
163-
this.remoteSerializer.fromMutation(m)
174+
fromMutation(this.remoteSerializer, m)
164175
);
165176
const timestamp = Timestamp.fromMillis(dbBatch.localWriteTimeMs);
166177
return new MutationBatch(
@@ -181,9 +192,9 @@ export class LocalSerializer {
181192

182193
let target: Target;
183194
if (isDocumentQuery(dbTarget.query)) {
184-
target = this.remoteSerializer.fromDocumentsTarget(dbTarget.query);
195+
target = fromDocumentsTarget(dbTarget.query);
185196
} else {
186-
target = this.remoteSerializer.fromQueryTarget(dbTarget.query);
197+
target = fromQueryTarget(dbTarget.query);
187198
}
188199
return new TargetData(
189200
target,
@@ -211,9 +222,9 @@ export class LocalSerializer {
211222
);
212223
let queryProto: DbQuery;
213224
if (targetData.target.isDocumentQuery()) {
214-
queryProto = this.remoteSerializer.toDocumentsTarget(targetData.target);
225+
queryProto = toDocumentsTarget(this.remoteSerializer, targetData.target);
215226
} else {
216-
queryProto = this.remoteSerializer.toQueryTarget(targetData.target);
227+
queryProto = toQueryTarget(this.remoteSerializer, targetData.target);
217228
}
218229

219230
// We can't store the resumeToken as a ByteString in IndexedDb, so we

packages/firestore/src/model/transform_operation.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ import * as api from '../protos/firestore_proto_api';
1919

2020
import { Timestamp } from '../api/timestamp';
2121
import { debugAssert } from '../util/assert';
22-
import { JsonProtoSerializer } from '../remote/serializer';
22+
import { JsonProtoSerializer, toDouble, toInteger } from '../remote/serializer';
2323
import {
24-
valueEquals,
2524
isArray,
2625
isInteger,
2726
isNumber,
28-
normalizeNumber
27+
normalizeNumber,
28+
valueEquals
2929
} from './values';
3030
import { serverTimestamp } from './server_timestamps';
3131
import { arrayEquals } from '../util/misc';
@@ -209,9 +209,9 @@ export class NumericIncrementTransformOperation implements TransformOperation {
209209
const baseValue = this.computeBaseValue(previousValue);
210210
const sum = this.asNumber(baseValue) + this.asNumber(this.operand);
211211
if (isInteger(baseValue) && isInteger(this.operand)) {
212-
return this.serializer.toInteger(sum);
212+
return toInteger(sum);
213213
} else {
214-
return this.serializer.toDouble(sum);
214+
return toDouble(this.serializer, sum);
215215
}
216216
}
217217

packages/firestore/src/platform_browser/browser_platform.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class BrowserPlatform implements Platform {
5757
}
5858

5959
newSerializer(databaseId: DatabaseId): JsonProtoSerializer {
60-
return new JsonProtoSerializer(databaseId, { useProto3Json: true });
60+
return new JsonProtoSerializer(databaseId, /* useProto3Json= */ true);
6161
}
6262

6363
formatJSON(value: unknown): string {

packages/firestore/src/platform_node/node_platform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ export class NodePlatform implements Platform {
5353
return new NoopConnectivityMonitor();
5454
}
5555

56-
newSerializer(partitionId: DatabaseId): JsonProtoSerializer {
57-
return new JsonProtoSerializer(partitionId, { useProto3Json: false });
56+
newSerializer(databaseId: DatabaseId): JsonProtoSerializer {
57+
return new JsonProtoSerializer(databaseId, /* useProto3Json= */ false);
5858
}
5959

6060
formatJSON(value: unknown): string {

packages/firestore/src/remote/datastore.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,22 @@
1616
*/
1717

1818
import { CredentialsProvider } from '../api/credentials';
19-
import { MaybeDocument, Document } from '../model/document';
19+
import { Document, MaybeDocument } from '../model/document';
2020
import { DocumentKey } from '../model/document_key';
2121
import { Mutation } from '../model/mutation';
2222
import * as api from '../protos/firestore_proto_api';
2323
import { debugCast, hardAssert } from '../util/assert';
2424
import { Code, FirestoreError } from '../util/error';
2525
import { Connection } from './connection';
26-
import { JsonProtoSerializer } from './serializer';
26+
import {
27+
fromDocument,
28+
fromMaybeDocument,
29+
getEncodedDatabaseId,
30+
JsonProtoSerializer,
31+
toMutation,
32+
toName,
33+
toQueryTarget
34+
} from './serializer';
2735
import {
2836
PersistentListenStream,
2937
PersistentWriteStream,
@@ -122,8 +130,8 @@ export async function invokeCommitRpc(
122130
): Promise<void> {
123131
const datastoreImpl = debugCast(datastore, DatastoreImpl);
124132
const params = {
125-
database: datastoreImpl.serializer.encodedDatabaseId,
126-
writes: mutations.map(m => datastoreImpl.serializer.toMutation(m))
133+
database: getEncodedDatabaseId(datastoreImpl.serializer),
134+
writes: mutations.map(m => toMutation(datastoreImpl.serializer, m))
127135
};
128136
await datastoreImpl.invokeRPC('Commit', params);
129137
}
@@ -134,8 +142,8 @@ export async function invokeBatchGetDocumentsRpc(
134142
): Promise<MaybeDocument[]> {
135143
const datastoreImpl = debugCast(datastore, DatastoreImpl);
136144
const params = {
137-
database: datastoreImpl.serializer.encodedDatabaseId,
138-
documents: keys.map(k => datastoreImpl.serializer.toName(k))
145+
database: getEncodedDatabaseId(datastoreImpl.serializer),
146+
documents: keys.map(k => toName(datastoreImpl.serializer, k))
139147
};
140148
const response = await datastoreImpl.invokeStreamingRPC<
141149
api.BatchGetDocumentsRequest,
@@ -144,7 +152,7 @@ export async function invokeBatchGetDocumentsRpc(
144152

145153
const docs = new Map<string, MaybeDocument>();
146154
response.forEach(proto => {
147-
const doc = datastoreImpl.serializer.fromMaybeDocument(proto);
155+
const doc = fromMaybeDocument(datastoreImpl.serializer, proto);
148156
docs.set(doc.key.toString(), doc);
149157
});
150158
const result: MaybeDocument[] = [];
@@ -161,11 +169,12 @@ export async function invokeRunQueryRpc(
161169
query: Query
162170
): Promise<Document[]> {
163171
const datastoreImpl = debugCast(datastore, DatastoreImpl);
164-
const { structuredQuery, parent } = datastoreImpl.serializer.toQueryTarget(
172+
const { structuredQuery, parent } = toQueryTarget(
173+
datastoreImpl.serializer,
165174
query.toTarget()
166175
);
167176
const params = {
168-
database: datastoreImpl.serializer.encodedDatabaseId,
177+
database: getEncodedDatabaseId(datastoreImpl.serializer),
169178
parent,
170179
structuredQuery
171180
};
@@ -179,7 +188,9 @@ export async function invokeRunQueryRpc(
179188
response
180189
// Omit RunQueryResponses that only contain readTimes.
181190
.filter(proto => !!proto.document)
182-
.map(proto => datastoreImpl.serializer.fromDocument(proto.document!))
191+
.map(proto =>
192+
fromDocument(datastoreImpl.serializer, proto.document!, undefined)
193+
)
183194
);
184195
}
185196

0 commit comments

Comments
 (0)