@@ -33,26 +33,39 @@ import { AsyncQueue } from '../../../src/util/async_queue';
33
33
import { Deferred } from '../../../src/util/promise' ;
34
34
import { FieldPath as ExternalFieldPath } from '../../../src/api/field_path' ;
35
35
import { validateReference } from './write_batch' ;
36
- import { newUserDataReader } from './reference' ;
36
+ import { DocumentReference , newUserDataReader } from './reference' ;
37
37
import { FieldPath } from './field_path' ;
38
38
import { cast } from './util' ;
39
39
40
- export class Transaction implements firestore . Transaction {
41
- // This is the lite version of the Transaction API used in the legacy SDK. The
42
- // class is a close copy but takes different input types.
40
+ // TODO(mrschmidt) Consider using `BaseTransaction` as the base class in the
41
+ // legacy SDK.
42
+ export abstract class BaseTransaction {
43
+ // This is the tree-shakeable version of the Transaction class used in the
44
+ // legacy SDK. The class is a close copy but takes different input and output
45
+ // types. The Lite as well as the firestore-exp SDK further extend this class
46
+ // to provide their appropriate API types.
43
47
44
48
private readonly _dataReader : UserDataReader ;
45
49
46
50
constructor (
47
- private readonly _firestore : Firestore ,
51
+ protected readonly _firestore : Firestore ,
48
52
private readonly _transaction : InternalTransaction
49
53
) {
50
54
this . _dataReader = newUserDataReader ( _firestore ) ;
51
55
}
52
56
53
- get < T > (
54
- documentRef : firestore . DocumentReference < T >
55
- ) : Promise < firestore . DocumentSnapshot < T > > {
57
+ /**
58
+ * Wrapper around the `BatchGetDocuments` RPC that calls the provided
59
+ * converter with the resulting Document. The converter should return
60
+ * the QueryDocumentSnapshot type that is expected by the SDK user.
61
+ *
62
+ * @param documentRef The document to fetch.
63
+ * @param converter A function that returns a QueryDocumentSnapshot.
64
+ */
65
+ protected _getHelper < DocSnap , T > (
66
+ documentRef : firestore . DocumentReference < T > ,
67
+ converter : ( ref : DocumentReference < T > , doc : Document | null ) => DocSnap
68
+ ) : Promise < DocSnap > {
56
69
const ref = validateReference ( documentRef , this . _firestore ) ;
57
70
return this . _transaction
58
71
. lookup ( [ ref . _key ] )
@@ -62,19 +75,9 @@ export class Transaction implements firestore.Transaction {
62
75
}
63
76
const doc = docs [ 0 ] ;
64
77
if ( doc instanceof NoDocument ) {
65
- return new DocumentSnapshot < T > (
66
- this . _firestore ,
67
- ref . _key ,
68
- null ,
69
- ref . _converter
70
- ) ;
78
+ return converter ( ref , null ) ;
71
79
} else if ( doc instanceof Document ) {
72
- return new DocumentSnapshot < T > (
73
- this . _firestore ,
74
- doc . key ,
75
- doc ,
76
- ref . _converter
77
- ) ;
80
+ return converter ( ref , doc ) ;
78
81
} else {
79
82
throw fail (
80
83
`BatchGetDocumentsRequest returned unexpected document type: ${ doc . constructor . name } `
@@ -83,17 +86,17 @@ export class Transaction implements firestore.Transaction {
83
86
} ) ;
84
87
}
85
88
86
- set < T > ( documentRef : firestore . DocumentReference < T > , value : T ) : Transaction ;
89
+ set < T > ( documentRef : firestore . DocumentReference < T > , value : T ) : this ;
87
90
set < T > (
88
91
documentRef : firestore . DocumentReference < T > ,
89
92
value : Partial < T > ,
90
93
options : firestore . SetOptions
91
- ) : Transaction ;
94
+ ) : this ;
92
95
set < T > (
93
96
documentRef : firestore . DocumentReference < T > ,
94
97
value : T ,
95
98
options ?: firestore . SetOptions
96
- ) : Transaction {
99
+ ) : this {
97
100
const ref = validateReference ( documentRef , this . _firestore ) ;
98
101
const convertedValue = applyFirestoreDataConverter (
99
102
ref . _converter ,
@@ -114,19 +117,19 @@ export class Transaction implements firestore.Transaction {
114
117
update (
115
118
documentRef : firestore . DocumentReference < unknown > ,
116
119
value : firestore . UpdateData
117
- ) : Transaction ;
120
+ ) : this ;
118
121
update (
119
122
documentRef : firestore . DocumentReference < unknown > ,
120
123
field : string | ExternalFieldPath ,
121
124
value : unknown ,
122
125
...moreFieldsAndValues : unknown [ ]
123
- ) : Transaction ;
126
+ ) : this ;
124
127
update (
125
128
documentRef : firestore . DocumentReference < unknown > ,
126
129
fieldOrUpdateData : string | ExternalFieldPath | firestore . UpdateData ,
127
130
value ?: unknown ,
128
131
...moreFieldsAndValues : unknown [ ]
129
- ) : Transaction {
132
+ ) : this {
130
133
const ref = validateReference ( documentRef , this . _firestore ) ;
131
134
132
135
let parsed ;
@@ -153,13 +156,26 @@ export class Transaction implements firestore.Transaction {
153
156
return this ;
154
157
}
155
158
156
- delete ( documentRef : firestore . DocumentReference < unknown > ) : Transaction {
159
+ delete ( documentRef : firestore . DocumentReference < unknown > ) : this {
157
160
const ref = validateReference ( documentRef , this . _firestore ) ;
158
161
this . _transaction . delete ( ref . _key ) ;
159
162
return this ;
160
163
}
161
164
}
162
165
166
+ export class Transaction extends BaseTransaction
167
+ implements firestore . Transaction {
168
+ get < T > (
169
+ documentRef : firestore . DocumentReference < T >
170
+ ) : Promise < firestore . DocumentSnapshot < T > > {
171
+ return this . _getHelper < DocumentSnapshot < T > , T > (
172
+ documentRef ,
173
+ ( ref , doc ) =>
174
+ new DocumentSnapshot < T > ( this . _firestore , ref . _key , doc , ref . _converter )
175
+ ) ;
176
+ }
177
+ }
178
+
163
179
export function runTransaction < T > (
164
180
firestore : firestore . FirebaseFirestore ,
165
181
updateFunction : ( transaction : firestore . Transaction ) => Promise < T >
0 commit comments