Skip to content

Commit 4526ad1

Browse files
committed
Fix circular dependency between user_data_reader and expressions
1 parent 83e2cfe commit 4526ad1

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

packages/firestore/src/lite-api/expressions.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Value as ProtoValue } from '../protos/firestore_proto_api';
2525
import {
2626
JsonProtoSerializer,
2727
ProtoSerializable,
28+
ProtoValueSerializable,
2829
toMapValue,
2930
toStringValue,
3031
UserData
@@ -129,14 +130,15 @@ function fieldOfOrExpr(value: any): Expr {
129130
* The `Expr` class provides a fluent API for building expressions. You can chain together
130131
* method calls to create complex expressions.
131132
*/
132-
export abstract class Expr implements ProtoSerializable<ProtoValue>, UserData {
133+
export abstract class Expr implements ProtoValueSerializable, UserData {
133134
abstract exprType: ExprType;
134135

135136
/**
136137
* @private
137138
* @internal
138139
*/
139140
abstract _toProto(serializer: JsonProtoSerializer): ProtoValue;
141+
_protoValueType = 'ProtoValue' as const;
140142

141143
/**
142144
* @private
@@ -2088,20 +2090,12 @@ export interface Selectable {
20882090
readonly expr: Expr;
20892091
}
20902092

2091-
export function _isSelectable(value: any): value is Selectable {
2092-
return value.selectable &&
2093-
typeof value.alias === 'string' &&
2094-
value.expr instanceof Expr;
2095-
}
2096-
20972093
/**
20982094
* @beta
20992095
*
21002096
* A class that represents an aggregate function.
21012097
*/
2102-
export class AggregateFunction
2103-
implements ProtoSerializable<ProtoValue>, UserData
2104-
{
2098+
export class AggregateFunction implements ProtoValueSerializable, UserData {
21052099
exprType: ExprType = 'AggregateFunction';
21062100

21072101
constructor(private name: string, private params: Expr[]) {}
@@ -2137,6 +2131,8 @@ export class AggregateFunction
21372131
};
21382132
}
21392133

2134+
_protoValueType = 'ProtoValue' as const;
2135+
21402136
/**
21412137
* @private
21422138
* @internal

packages/firestore/src/lite-api/user_data_reader.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ import {
5656
JsonProtoSerializer,
5757
toBytes,
5858
toResourceName,
59-
toTimestamp
59+
toTimestamp,
60+
isProtoValueSerializable
6061
} from '../remote/serializer';
6162
import { debugAssert, fail } from '../util/assert';
6263
import { Code, FirestoreError } from '../util/error';
@@ -65,7 +66,6 @@ import { Dict, forEach, isEmpty } from '../util/obj';
6566

6667
import { Bytes } from './bytes';
6768
import { Firestore } from './database';
68-
import { AggregateFunction, Expr } from './expressions';
6969
import { FieldPath } from './field_path';
7070
import { FieldValue } from './field_value';
7171
import { GeoPoint } from './geo_point';
@@ -910,9 +910,7 @@ export function parseScalarValue(
910910
};
911911
} else if (value instanceof VectorValue) {
912912
return parseVectorValue(value, context);
913-
} else if (value instanceof Expr) {
914-
return value._toProto(context.serializer);
915-
} else if (value instanceof AggregateFunction) {
913+
} else if (isProtoValueSerializable(value)) {
916914
return value._toProto(context.serializer);
917915
} else {
918916
throw context.createError(
@@ -972,8 +970,7 @@ export function looksLikeJsonObject(input: unknown): boolean {
972970
!(input instanceof DocumentReference) &&
973971
!(input instanceof FieldValue) &&
974972
!(input instanceof VectorValue) &&
975-
!(input instanceof Expr) &&
976-
!(input instanceof AggregateFunction)
973+
!isProtoValueSerializable(input)
977974
);
978975
}
979976

packages/firestore/src/remote/serializer.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,21 @@ export interface ProtoSerializable<ProtoType> {
14341434
_toProto(serializer: JsonProtoSerializer): ProtoType;
14351435
}
14361436

1437+
export interface ProtoValueSerializable extends ProtoSerializable<ProtoValue> {
1438+
// Supports runtime identification of the ProtoSerializable<ProtoValue> type.
1439+
_protoValueType: 'ProtoValue';
1440+
}
1441+
1442+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1443+
export function isProtoValueSerializable(
1444+
value: any
1445+
): value is ProtoValueSerializable {
1446+
return (
1447+
typeof value._toProto === 'function' &&
1448+
value._protoValueType === 'ProtoValue'
1449+
);
1450+
}
1451+
14371452
export interface UserData {
14381453
_readUserData(dataReader: UserDataReader): void;
14391454
}

0 commit comments

Comments
 (0)