@@ -33,23 +33,29 @@ import { ParseContext, parseData, UserDataSource } from './user_data_reader';
33
33
import { debugAssert } from '../util/assert' ;
34
34
35
35
/**
36
- * An opaque base class for FieldValue sentinel objects in our public API,
37
- * with public static methods for creating said sentinel objects .
36
+ * An opaque base class for FieldValue sentinel objects in our public API that
37
+ * is shared between the full, lite and legacy SDK .
38
38
*/
39
- export abstract class FieldValueImpl {
40
- protected constructor ( readonly _methodName : string ) { }
39
+ export abstract class SerializableFieldValue {
40
+ /** A pointer to the implementing class. */
41
+ abstract readonly _delegate : SerializableFieldValue ;
41
42
42
- abstract toFieldTransform ( context : ParseContext ) : FieldTransform | null ;
43
+ /** The public API endpoint that returns this class. */
44
+ abstract readonly _methodName : string ;
43
45
44
- abstract isEqual ( other : FieldValue ) : boolean ;
46
+ abstract _toFieldTransform ( context : ParseContext ) : FieldTransform | null ;
47
+
48
+ abstract isEqual ( other : SerializableFieldValue ) : boolean ;
45
49
}
46
50
47
- export class DeleteFieldValueImpl extends FieldValueImpl {
48
- constructor ( ) {
49
- super ( 'FieldValue.delete' ) ;
51
+ export class DeleteFieldValueImpl extends SerializableFieldValue {
52
+ _delegate = this ;
53
+
54
+ constructor ( readonly _methodName : string ) {
55
+ super ( ) ;
50
56
}
51
57
52
- toFieldTransform ( context : ParseContext ) : null {
58
+ _toFieldTransform ( context : ParseContext ) : null {
53
59
if ( context . dataSource === UserDataSource . MergeSet ) {
54
60
// No transform to add for a delete, but we need to add it to our
55
61
// fieldMask so it gets deleted.
@@ -79,12 +85,14 @@ export class DeleteFieldValueImpl extends FieldValueImpl {
79
85
}
80
86
}
81
87
82
- export class ServerTimestampFieldValueImpl extends FieldValueImpl {
83
- constructor ( ) {
84
- super ( 'FieldValue.serverTimestamp' ) ;
88
+ export class ServerTimestampFieldValueImpl extends SerializableFieldValue {
89
+ _delegate = this ;
90
+
91
+ constructor ( readonly _methodName : string ) {
92
+ super ( ) ;
85
93
}
86
94
87
- toFieldTransform ( context : ParseContext ) : FieldTransform {
95
+ _toFieldTransform ( context : ParseContext ) : FieldTransform {
88
96
return new FieldTransform ( context . path ! , ServerTimestampTransform . instance ) ;
89
97
}
90
98
@@ -93,12 +101,17 @@ export class ServerTimestampFieldValueImpl extends FieldValueImpl {
93
101
}
94
102
}
95
103
96
- export class ArrayUnionFieldValueImpl extends FieldValueImpl {
97
- constructor ( private readonly _elements : unknown [ ] ) {
98
- super ( 'FieldValue.arrayUnion' ) ;
104
+ export class ArrayUnionFieldValueImpl extends SerializableFieldValue {
105
+ _delegate = this ;
106
+
107
+ constructor (
108
+ readonly _methodName : string ,
109
+ private readonly _elements : unknown [ ]
110
+ ) {
111
+ super ( ) ;
99
112
}
100
113
101
- toFieldTransform ( context : ParseContext ) : FieldTransform {
114
+ _toFieldTransform ( context : ParseContext ) : FieldTransform {
102
115
// Although array transforms are used with writes, the actual elements
103
116
// being uniomed or removed are not considered writes since they cannot
104
117
// contain any FieldValue sentinels, etc.
@@ -125,12 +138,14 @@ export class ArrayUnionFieldValueImpl extends FieldValueImpl {
125
138
}
126
139
}
127
140
128
- export class ArrayRemoveFieldValueImpl extends FieldValueImpl {
129
- constructor ( readonly _elements : unknown [ ] ) {
130
- super ( 'FieldValue.arrayRemove' ) ;
141
+ export class ArrayRemoveFieldValueImpl extends SerializableFieldValue {
142
+ _delegate = this ;
143
+
144
+ constructor ( readonly _methodName : string , readonly _elements : unknown [ ] ) {
145
+ super ( ) ;
131
146
}
132
147
133
- toFieldTransform ( context : ParseContext ) : FieldTransform {
148
+ _toFieldTransform ( context : ParseContext ) : FieldTransform {
134
149
// Although array transforms are used with writes, the actual elements
135
150
// being unioned or removed are not considered writes since they cannot
136
151
// contain any FieldValue sentinels, etc.
@@ -157,12 +172,14 @@ export class ArrayRemoveFieldValueImpl extends FieldValueImpl {
157
172
}
158
173
}
159
174
160
- export class NumericIncrementFieldValueImpl extends FieldValueImpl {
161
- constructor ( private readonly _operand : number ) {
162
- super ( 'FieldValue.increment' ) ;
175
+ export class NumericIncrementFieldValueImpl extends SerializableFieldValue {
176
+ _delegate = this ;
177
+
178
+ constructor ( readonly _methodName : string , private readonly _operand : number ) {
179
+ super ( ) ;
163
180
}
164
181
165
- toFieldTransform ( context : ParseContext ) : FieldTransform {
182
+ _toFieldTransform ( context : ParseContext ) : FieldTransform {
166
183
const parseContext = new ParseContext (
167
184
{
168
185
dataSource : UserDataSource . Argument ,
@@ -186,38 +203,75 @@ export class NumericIncrementFieldValueImpl extends FieldValueImpl {
186
203
}
187
204
}
188
205
189
- export class FieldValue implements firestore . FieldValue {
190
- static delete ( ) : FieldValueImpl {
206
+ /** The public FieldValue class of the lite API. */
207
+ export abstract class FieldValue extends SerializableFieldValue
208
+ implements firestore . FieldValue {
209
+ static delete ( ) : firestore . FieldValue {
191
210
validateNoArgs ( 'FieldValue.delete' , arguments ) ;
192
- return new DeleteFieldValueImpl ( ) ;
211
+ return new FieldValueDelegate (
212
+ new DeleteFieldValueImpl ( 'FieldValue.delete' )
213
+ ) ;
193
214
}
194
215
195
- static serverTimestamp ( ) : FieldValueImpl {
216
+ static serverTimestamp ( ) : firestore . FieldValue {
196
217
validateNoArgs ( 'FieldValue.serverTimestamp' , arguments ) ;
197
- return new ServerTimestampFieldValueImpl ( ) ;
218
+ return new FieldValueDelegate (
219
+ new ServerTimestampFieldValueImpl ( 'FieldValue.serverTimestamp' )
220
+ ) ;
198
221
}
199
222
200
- static arrayUnion ( ...elements : unknown [ ] ) : FieldValueImpl {
223
+ static arrayUnion ( ...elements : unknown [ ] ) : firestore . FieldValue {
201
224
validateAtLeastNumberOfArgs ( 'FieldValue.arrayUnion' , arguments , 1 ) ;
202
225
// NOTE: We don't actually parse the data until it's used in set() or
203
226
// update() since we need access to the Firestore instance.
204
- return new ArrayUnionFieldValueImpl ( elements ) ;
227
+ return new FieldValueDelegate (
228
+ new ArrayUnionFieldValueImpl ( 'FieldValue.arrayUnion' , elements )
229
+ ) ;
205
230
}
206
231
207
- static arrayRemove ( ...elements : unknown [ ] ) : FieldValueImpl {
232
+ static arrayRemove ( ...elements : unknown [ ] ) : firestore . FieldValue {
208
233
validateAtLeastNumberOfArgs ( 'FieldValue.arrayRemove' , arguments , 1 ) ;
209
234
// NOTE: We don't actually parse the data until it's used in set() or
210
235
// update() since we need access to the Firestore instance.
211
- return new ArrayRemoveFieldValueImpl ( elements ) ;
236
+ return new FieldValueDelegate (
237
+ new ArrayRemoveFieldValueImpl ( 'FieldValue.arrayRemove' , elements )
238
+ ) ;
212
239
}
213
240
214
- static increment ( n : number ) : FieldValueImpl {
241
+ static increment ( n : number ) : firestore . FieldValue {
215
242
validateArgType ( 'FieldValue.increment' , 'number' , 1 , n ) ;
216
243
validateExactNumberOfArgs ( 'FieldValue.increment' , arguments , 1 ) ;
217
- return new NumericIncrementFieldValueImpl ( n ) ;
244
+ return new FieldValueDelegate (
245
+ new NumericIncrementFieldValueImpl ( 'FieldValue.increment' , n )
246
+ ) ;
218
247
}
248
+ }
219
249
220
- isEqual ( other : FieldValue ) : boolean {
221
- return this === other ;
250
+ /**
251
+ * A delegate class that allows the FieldValue implementations returned by
252
+ * deleteField(), serverTimestamp(), arrayUnion(), arrayRemove() and
253
+ * increment() to be an instance of the legacy FieldValue class declared above.
254
+ *
255
+ * We don't directly subclass `FieldValue` in the various field value
256
+ * implementations as the base FieldValue class differs between the lite, full
257
+ * and legacy SDK.
258
+ */
259
+ class FieldValueDelegate extends FieldValue implements firestore . FieldValue {
260
+ readonly _methodName : string ;
261
+
262
+ constructor ( readonly _delegate : SerializableFieldValue ) {
263
+ super ( ) ;
264
+ this . _methodName = _delegate . _methodName ;
265
+ }
266
+
267
+ _toFieldTransform ( context : ParseContext ) : FieldTransform | null {
268
+ return this . _delegate . _toFieldTransform ( context ) ;
269
+ }
270
+
271
+ isEqual ( other : firestore . FieldValue ) : boolean {
272
+ if ( ! ( other instanceof FieldValueDelegate ) ) {
273
+ return false ;
274
+ }
275
+ return this . _delegate . isEqual ( other . _delegate ) ;
222
276
}
223
277
}
0 commit comments