Skip to content

Commit a767054

Browse files
author
Brian Chen
committed
resolve comments rd.1
1 parent 0ff2dc4 commit a767054

File tree

8 files changed

+121
-288
lines changed

8 files changed

+121
-288
lines changed

.changeset/rich-birds-wink.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
---
22
'@firebase/firestore': minor
33
---
4-
5-
Field tranforms performed within a write no longer count as additional operations. However, a field transform on its own still counts as an operation.
4+
A write to a document that contains field transforms is no longer split into separate operations. This reduces the number of writes that the backend performs.

packages/firestore/src/local/local_serializer.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ export function fromDbMutationBatch(
200200
// on the SDK means that old `transform` mutations stored in IndexedDB need
201201
// to be updated to `update_transforms`.
202202
// TODO(b/174608374): Remove this code once we perform a schema migration.
203-
let i = dbBatch.mutations.length - 1;
204-
while (i >= 0) {
203+
for (let i = dbBatch.mutations.length - 1; i >= 0; --i) {
205204
const mutationProto = dbBatch.mutations[i];
206205
if (mutationProto?.transform !== undefined) {
207206
debugAssert(
@@ -215,7 +214,6 @@ export function fromDbMutationBatch(
215214
dbBatch.mutations.splice(i, 1);
216215
--i;
217216
}
218-
--i;
219217
}
220218

221219
const mutations = dbBatch.mutations.map(m =>

packages/firestore/src/model/mutation.ts

+39-61
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function fieldTransformsAreEqual(
107107
return true;
108108
}
109109

110-
if (!!left && !!right) {
110+
if (left && right) {
111111
return arrayEquals(left, right, (l, r) => fieldTransformEquals(l, r));
112112
}
113113

@@ -266,16 +266,7 @@ export abstract class Mutation {
266266
abstract readonly type: MutationType;
267267
abstract readonly key: DocumentKey;
268268
abstract readonly precondition: Precondition;
269-
}
270-
271-
/**
272-
* Used to represent Mutation classes that have a `fieldTransforms` field,
273-
* namely SetMutation and PatchMutation. This intermediate class makes it
274-
* easier to access the `fieldTransforms` field directly from a Mutation
275-
* object.
276-
*/
277-
export abstract class MutationWithTransforms extends Mutation {
278-
abstract readonly fieldTransforms?: FieldTransform[];
269+
abstract readonly fieldTransforms: FieldTransform[];
279270
}
280271

281272
/**
@@ -386,12 +377,9 @@ export function extractMutationBaseValue(
386377
mutation: Mutation,
387378
maybeDoc: MaybeDocument | null
388379
): ObjectValue | null {
389-
if (
390-
mutation instanceof MutationWithTransforms &&
391-
(mutation as MutationWithTransforms).fieldTransforms !== undefined
392-
) {
380+
if (mutation.fieldTransforms !== undefined) {
393381
return extractTransformMutationBaseValue(
394-
(mutation as MutationWithTransforms).fieldTransforms!,
382+
mutation.fieldTransforms,
395383
maybeDoc
396384
);
397385
}
@@ -441,24 +429,19 @@ export function mutationEquals(left: Mutation, right: Mutation): boolean {
441429
}
442430

443431
if (left.type === MutationType.Set) {
444-
const setLeft: SetMutation = left as SetMutation;
445-
const setRight: SetMutation = right as SetMutation;
446432
return (
447-
setLeft.value.isEqual(setRight.value) &&
448-
fieldTransformsAreEqual(setLeft.fieldTransforms, setRight.fieldTransforms)
433+
(left as SetMutation).value.isEqual((right as SetMutation).value) &&
434+
fieldTransformsAreEqual(left.fieldTransforms, right.fieldTransforms)
449435
);
450436
}
451437

452438
if (left.type === MutationType.Patch) {
453-
const patchLeft: PatchMutation = left as PatchMutation;
454-
const patchRight: PatchMutation = right as PatchMutation;
455439
return (
456-
patchLeft.data.isEqual(patchRight.data) &&
457-
patchLeft.fieldMask.isEqual(patchRight.fieldMask) &&
458-
fieldTransformsAreEqual(
459-
patchLeft.fieldTransforms,
460-
patchRight.fieldTransforms
461-
)
440+
(left as PatchMutation).data.isEqual((right as PatchMutation).data) &&
441+
(left as PatchMutation).fieldMask.isEqual(
442+
(right as PatchMutation).fieldMask
443+
) &&
444+
fieldTransformsAreEqual(left.fieldTransforms, right.fieldTransforms)
462445
);
463446
}
464447

@@ -497,12 +480,12 @@ function getPostMutationVersion(
497480
* A mutation that creates or replaces the document at the given key with the
498481
* object value contents.
499482
*/
500-
export class SetMutation extends MutationWithTransforms {
483+
export class SetMutation extends Mutation {
501484
constructor(
502485
readonly key: DocumentKey,
503486
readonly value: ObjectValue,
504487
readonly precondition: Precondition,
505-
readonly fieldTransforms?: FieldTransform[]
488+
readonly fieldTransforms: FieldTransform[] = []
506489
) {
507490
super();
508491
}
@@ -581,13 +564,13 @@ function applySetMutationToLocalView(
581564
* * When a field is not in the mask but is in the values, the values map is
582565
* ignored.
583566
*/
584-
export class PatchMutation extends MutationWithTransforms {
567+
export class PatchMutation extends Mutation {
585568
constructor(
586569
readonly key: DocumentKey,
587570
readonly data: ObjectValue,
588571
readonly fieldMask: FieldMask,
589572
readonly precondition: Precondition,
590-
readonly fieldTransforms?: FieldTransform[]
573+
readonly fieldTransforms: FieldTransform[] = []
591574
) {
592575
super();
593576
}
@@ -608,19 +591,14 @@ function applyPatchMutationToRemoteDocument(
608591
return new UnknownDocument(mutation.key, mutationResult.version);
609592
}
610593

611-
let newData = patchDocument(mutation, maybeDoc);
612-
if (mutation.fieldTransforms && mutationResult.transformResults) {
613-
const transformResults = serverTransformResults(
614-
mutation.fieldTransforms,
615-
maybeDoc,
616-
mutationResult.transformResults
617-
);
618-
newData = transformObject(
619-
mutation.fieldTransforms,
620-
newData,
621-
transformResults
622-
);
623-
}
594+
const transformResults = mutationResult.transformResults
595+
? serverTransformResults(
596+
mutation.fieldTransforms,
597+
maybeDoc,
598+
mutationResult.transformResults
599+
)
600+
: [];
601+
const newData = patchDocument(mutation, maybeDoc, transformResults);
624602
return new Document(mutation.key, mutationResult.version, newData, {
625603
hasCommittedMutations: true
626604
});
@@ -637,20 +615,13 @@ function applyPatchMutationToLocalView(
637615
}
638616

639617
const version = getPostMutationVersion(maybeDoc);
640-
let newData = patchDocument(mutation, maybeDoc);
641-
if (mutation.fieldTransforms) {
642-
const transformResults = localTransformResults(
643-
mutation.fieldTransforms,
644-
localWriteTime,
645-
maybeDoc,
646-
baseDoc
647-
);
648-
newData = transformObject(
649-
mutation.fieldTransforms,
650-
newData,
651-
transformResults
652-
);
653-
}
618+
const transformResults = localTransformResults(
619+
mutation.fieldTransforms,
620+
localWriteTime,
621+
maybeDoc,
622+
baseDoc
623+
);
624+
const newData = patchDocument(mutation, maybeDoc, transformResults);
654625
return new Document(mutation.key, version, newData, {
655626
hasLocalMutations: true
656627
});
@@ -663,15 +634,20 @@ function applyPatchMutationToLocalView(
663634
*/
664635
function patchDocument(
665636
mutation: PatchMutation,
666-
maybeDoc: MaybeDocument | null
637+
maybeDoc: MaybeDocument | null,
638+
transformResults?: ProtoValue[]
667639
): ObjectValue {
668640
let data: ObjectValue;
669641
if (maybeDoc instanceof Document) {
670642
data = maybeDoc.data();
671643
} else {
672644
data = ObjectValue.empty();
673645
}
674-
return patchObject(mutation, data);
646+
data = patchObject(mutation, data);
647+
if (transformResults) {
648+
data = transformObject(mutation.fieldTransforms, data, transformResults);
649+
}
650+
return data;
675651
}
676652

677653
function patchObject(mutation: PatchMutation, data: ObjectValue): ObjectValue {
@@ -801,6 +777,7 @@ export class DeleteMutation extends Mutation {
801777
}
802778

803779
readonly type: MutationType = MutationType.Delete;
780+
readonly fieldTransforms: FieldTransform[] = [];
804781
}
805782

806783
function applyDeleteMutationToRemoteDocument(
@@ -852,4 +829,5 @@ export class VerifyMutation extends Mutation {
852829
}
853830

854831
readonly type: MutationType = MutationType.Verify;
832+
readonly fieldTransforms: FieldTransform[] = [];
855833
}

packages/firestore/src/remote/serializer.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import {
4343
FieldTransform,
4444
Mutation,
4545
MutationResult,
46-
MutationWithTransforms,
4746
PatchMutation,
4847
Precondition,
4948
SetMutation,
@@ -635,11 +634,7 @@ export function toMutation(
635634
return fail('Unknown mutation type ' + mutation.type);
636635
}
637636

638-
if (
639-
mutation instanceof MutationWithTransforms &&
640-
mutation.fieldTransforms &&
641-
mutation.fieldTransforms.length > 0
642-
) {
637+
if (mutation.fieldTransforms && mutation.fieldTransforms.length > 0) {
643638
result.updateTransforms = mutation.fieldTransforms.map(transform =>
644639
toFieldTransform(serializer, transform)
645640
);

0 commit comments

Comments
 (0)