@@ -144,41 +144,16 @@ export class StateMessage {
144
144
) : Promise < void > {
145
145
// TODO: decide how to handle individual errors from decoding values. currently we throw first ever error we get
146
146
147
- const decodeMapEntry = async (
148
- entry : StateMapEntry ,
149
- ctx : ChannelOptions ,
150
- decode : typeof decodeData ,
151
- ) : Promise < void > => {
152
- const { data, encoding, error } = await decode ( entry . data . value , entry . data . encoding , ctx ) ;
153
- entry . data . value = data ;
154
- entry . data . encoding = encoding ?? undefined ;
155
-
156
- if ( error ) {
157
- throw error ;
158
- }
159
- } ;
160
-
161
147
if ( message . object ?. map ?. entries ) {
162
- for ( const entry of Object . values ( message . object . map . entries ) ) {
163
- await decodeMapEntry ( entry , inputContext , decodeDataFn ) ;
164
- }
148
+ await this . _decodeMapEntries ( message . object . map . entries , inputContext , decodeDataFn ) ;
165
149
}
166
150
167
151
if ( message . operation ?. map ?. entries ) {
168
- for ( const entry of Object . values ( message . operation . map . entries ) ) {
169
- await decodeMapEntry ( entry , inputContext , decodeDataFn ) ;
170
- }
152
+ await this . _decodeMapEntries ( message . operation . map . entries , inputContext , decodeDataFn ) ;
171
153
}
172
154
173
- if ( message . operation ?. mapOp ?. data && 'value' in message . operation ?. mapOp ?. data ) {
174
- const mapOpData = message . operation . mapOp . data ;
175
- const { data, encoding, error } = await decodeDataFn ( mapOpData . value , mapOpData . encoding , inputContext ) ;
176
- mapOpData . value = data ;
177
- mapOpData . encoding = encoding ?? undefined ;
178
-
179
- if ( error ) {
180
- throw error ;
181
- }
155
+ if ( message . operation ?. mapOp ?. data && 'value' in message . operation . mapOp . data ) {
156
+ await this . _decodeStateData ( message . operation . mapOp . data , inputContext , decodeDataFn ) ;
182
157
}
183
158
}
184
159
@@ -197,6 +172,114 @@ export class StateMessage {
197
172
return result ;
198
173
}
199
174
175
+ private static async _decodeMapEntries (
176
+ mapEntries : Record < string , StateMapEntry > ,
177
+ inputContext : ChannelOptions ,
178
+ decodeDataFn : typeof decodeData ,
179
+ ) : Promise < void > {
180
+ for ( const entry of Object . values ( mapEntries ) ) {
181
+ await this . _decodeStateData ( entry . data , inputContext , decodeDataFn ) ;
182
+ }
183
+ }
184
+
185
+ private static async _decodeStateData (
186
+ stateData : StateData ,
187
+ inputContext : ChannelOptions ,
188
+ decodeDataFn : typeof decodeData ,
189
+ ) : Promise < void > {
190
+ const { data, encoding, error } = await decodeDataFn ( stateData . value , stateData . encoding , inputContext ) ;
191
+ stateData . value = data ;
192
+ stateData . encoding = encoding ?? undefined ;
193
+
194
+ if ( error ) {
195
+ throw error ;
196
+ }
197
+ }
198
+
199
+ private static _encodeStateOperation (
200
+ platform : typeof Platform ,
201
+ stateOperation : StateOperation ,
202
+ withBase64Encoding : boolean ,
203
+ ) : StateOperation {
204
+ // deep copy "stateOperation" object so we can modify the copy here.
205
+ // buffer values won't be correctly copied, so we will need to set them again explictly.
206
+ const stateOperationCopy = JSON . parse ( JSON . stringify ( stateOperation ) ) as StateOperation ;
207
+
208
+ if ( stateOperationCopy . mapOp ?. data && 'value' in stateOperationCopy . mapOp . data ) {
209
+ // use original "stateOperation" object when encoding values, so we have access to the original buffer values.
210
+ stateOperationCopy . mapOp . data = this . _encodeStateData ( platform , stateOperation . mapOp ?. data ! , withBase64Encoding ) ;
211
+ }
212
+
213
+ if ( stateOperationCopy . map ?. entries ) {
214
+ Object . entries ( stateOperationCopy . map . entries ) . forEach ( ( [ key , entry ] ) => {
215
+ // use original "stateOperation" object when encoding values, so we have access to original buffer values.
216
+ entry . data = this . _encodeStateData ( platform , stateOperation ?. map ?. entries ?. [ key ] . data ! , withBase64Encoding ) ;
217
+ } ) ;
218
+ }
219
+
220
+ return stateOperationCopy ;
221
+ }
222
+
223
+ private static _encodeStateObject (
224
+ platform : typeof Platform ,
225
+ stateObject : StateObject ,
226
+ withBase64Encoding : boolean ,
227
+ ) : StateObject {
228
+ // deep copy "stateObject" object so we can modify the copy here.
229
+ // buffer values won't be correctly copied, so we will need to set them again explictly.
230
+ const stateObjectCopy = JSON . parse ( JSON . stringify ( stateObject ) ) as StateObject ;
231
+
232
+ if ( stateObjectCopy . map ?. entries ) {
233
+ Object . entries ( stateObjectCopy . map . entries ) . forEach ( ( [ key , entry ] ) => {
234
+ // use original "stateObject" object when encoding values, so we have access to original buffer values.
235
+ entry . data = StateMessage . _encodeStateData (
236
+ platform ,
237
+ stateObject ?. map ?. entries ?. [ key ] . data ! ,
238
+ withBase64Encoding ,
239
+ ) ;
240
+ } ) ;
241
+ }
242
+
243
+ return stateObjectCopy ;
244
+ }
245
+
246
+ private static _encodeStateData ( platform : typeof Platform , data : StateData , withBase64Encoding : boolean ) : StateData {
247
+ const { value, encoding } = this . _encodeStateValue ( platform , data ?. value , data ?. encoding , withBase64Encoding ) ;
248
+ return {
249
+ ...data ,
250
+ value,
251
+ encoding,
252
+ } ;
253
+ }
254
+
255
+ private static _encodeStateValue (
256
+ platform : typeof Platform ,
257
+ value : StateValue | undefined ,
258
+ encoding : string | undefined ,
259
+ withBase64Encoding : boolean ,
260
+ ) : {
261
+ value : StateValue | undefined ;
262
+ encoding : string | undefined ;
263
+ } {
264
+ if ( ! value || ! platform . BufferUtils . isBuffer ( value ) ) {
265
+ return { value, encoding } ;
266
+ }
267
+
268
+ if ( withBase64Encoding ) {
269
+ return {
270
+ value : platform . BufferUtils . base64Encode ( value ) ,
271
+ encoding : encoding ? encoding + '/base64' : 'base64' ,
272
+ } ;
273
+ }
274
+
275
+ // toBuffer returns a datatype understandable by
276
+ // that platform's msgpack implementation (Buffer in node, Uint8Array in browsers)
277
+ return {
278
+ value : platform . BufferUtils . toBuffer ( value ) ,
279
+ encoding,
280
+ } ;
281
+ }
282
+
200
283
/**
201
284
* Overload toJSON() to intercept JSON.stringify()
202
285
* @return {* }
@@ -215,44 +298,18 @@ export class StateMessage {
215
298
// if withBase64Encoding = false - we were called by msgpack
216
299
const withBase64Encoding = arguments . length > 0 ;
217
300
218
- let operationCopy : StateOperation | undefined = undefined ;
219
- if ( this . operation ) {
220
- // deep copy "operation" prop so we can modify it here.
221
- // buffer values won't be correctly copied, so we will need to set them again explictly
222
- operationCopy = JSON . parse ( JSON . stringify ( this . operation ) ) as StateOperation ;
223
-
224
- if ( operationCopy . mapOp ?. data && 'value' in operationCopy . mapOp . data ) {
225
- // use original "operation" prop when encoding values, so we have access to original buffer values.
226
- operationCopy . mapOp . data = this . _encodeStateData ( this . operation . mapOp ?. data ! , withBase64Encoding ) ;
227
- }
228
-
229
- if ( operationCopy . map ?. entries ) {
230
- Object . entries ( operationCopy . map . entries ) . forEach ( ( [ key , entry ] ) => {
231
- // use original "operation" prop when encoding values, so we have access to original buffer values.
232
- entry . data = this . _encodeStateData ( this . operation ?. map ?. entries ?. [ key ] . data ! , withBase64Encoding ) ;
233
- } ) ;
234
- }
235
- }
236
-
237
- let object : StateObject | undefined = undefined ;
238
- if ( this . object ) {
239
- // deep copy "object" prop so we can modify it here.
240
- // buffer values won't be correctly copied, so we will need to set them again explictly
241
- object = JSON . parse ( JSON . stringify ( this . object ) ) as StateObject ;
242
-
243
- if ( object . map ?. entries ) {
244
- Object . entries ( object . map . entries ) . forEach ( ( [ key , entry ] ) => {
245
- // use original "object" prop when encoding values, so we have access to original buffer values.
246
- entry . data = this . _encodeStateData ( this . object ?. map ?. entries ?. [ key ] . data ! , withBase64Encoding ) ;
247
- } ) ;
248
- }
249
- }
301
+ const encodedOperation = this . operation
302
+ ? StateMessage . _encodeStateOperation ( this . _platform , this . operation , withBase64Encoding )
303
+ : undefined ;
304
+ const encodedObject = this . object
305
+ ? StateMessage . _encodeStateObject ( this . _platform , this . object , withBase64Encoding )
306
+ : undefined ;
250
307
251
308
return {
252
309
id : this . id ,
253
310
clientId : this . clientId ,
254
- operation : operationCopy ,
255
- object : object ,
311
+ operation : encodedOperation ,
312
+ object : encodedObject ,
256
313
extras : this . extras ,
257
314
} ;
258
315
}
@@ -275,40 +332,4 @@ export class StateMessage {
275
332
276
333
return result ;
277
334
}
278
-
279
- private _encodeStateData ( data : StateData , withBase64Encoding : boolean ) : StateData {
280
- const { value, encoding } = this . _encodeStateValue ( data ?. value , data ?. encoding , withBase64Encoding ) ;
281
- return {
282
- ...data ,
283
- value,
284
- encoding,
285
- } ;
286
- }
287
-
288
- private _encodeStateValue (
289
- value : StateValue | undefined ,
290
- encoding : string | undefined ,
291
- withBase64Encoding : boolean ,
292
- ) : {
293
- value : StateValue | undefined ;
294
- encoding : string | undefined ;
295
- } {
296
- if ( ! value || ! this . _platform . BufferUtils . isBuffer ( value ) ) {
297
- return { value, encoding } ;
298
- }
299
-
300
- if ( withBase64Encoding ) {
301
- return {
302
- value : this . _platform . BufferUtils . base64Encode ( value ) ,
303
- encoding : encoding ? encoding + '/base64' : 'base64' ,
304
- } ;
305
- }
306
-
307
- // toBuffer returns a datatype understandable by
308
- // that platform's msgpack implementation (Buffer in node, Uint8Array in browsers)
309
- return {
310
- value : this . _platform . BufferUtils . toBuffer ( value ) ,
311
- encoding,
312
- } ;
313
- }
314
335
}
0 commit comments