@@ -15,6 +15,7 @@ import {
15
15
beginWriting ,
16
16
writeChunkAndReturn ,
17
17
stringToChunk ,
18
+ byteLengthOfChunk ,
18
19
completeWriting ,
19
20
close ,
20
21
closeWithError ,
@@ -171,7 +172,7 @@ export type Request = {
171
172
pingedTasks : Array < Task > ,
172
173
completedImportChunks : Array < Chunk > ,
173
174
completedHintChunks : Array < Chunk > ,
174
- completedJSONChunks : Array < Chunk > ,
175
+ completedRegularChunks : Array < Chunk > ,
175
176
completedErrorChunks : Array < Chunk > ,
176
177
writtenSymbols : Map < symbol , number> ,
177
178
writtenClientReferences : Map < ClientReferenceKey , number> ,
@@ -230,7 +231,7 @@ export function createRequest(
230
231
pingedTasks : pingedTasks ,
231
232
completedImportChunks : ( [ ] : Array < Chunk > ) ,
232
233
completedHintChunks : ( [ ] : Array < Chunk > ) ,
233
- completedJSONChunks : ( [ ] : Array < Chunk > ) ,
234
+ completedRegularChunks : ( [ ] : Array < Chunk > ) ,
234
235
completedErrorChunks : ( [ ] : Array < Chunk > ) ,
235
236
writtenSymbols : new Map ( ) ,
236
237
writtenClientReferences : new Map ( ) ,
@@ -715,11 +716,25 @@ function serializeServerReference(
715
716
metadataId ,
716
717
serverReferenceMetadata ,
717
718
) ;
718
- request . completedJSONChunks . push ( processedChunk ) ;
719
+ request . completedRegularChunks . push ( processedChunk ) ;
719
720
writtenServerReferences . set ( serverReference , metadataId ) ;
720
721
return serializeServerReferenceID ( metadataId ) ;
721
722
}
722
723
724
+ function serializeLargeTextString ( request : Request , text : string ) : string {
725
+ request . pendingChunks += 2 ;
726
+ const textId = request . nextChunkId ++ ;
727
+ const textChunk = stringToChunk ( text ) ;
728
+ const headerChunk = processTextHeader (
729
+ request ,
730
+ textId ,
731
+ text ,
732
+ byteLengthOfChunk ( textChunk ) ,
733
+ ) ;
734
+ request . completedRegularChunks . push ( headerChunk , textChunk ) ;
735
+ return serializeByValueID ( textId ) ;
736
+ }
737
+
723
738
function escapeStringValue ( value : string ) : string {
724
739
if ( value [ 0 ] === '$' ) {
725
740
// We need to escape $ prefixed strings since we use those to encode
@@ -960,7 +975,12 @@ function resolveModelToJSON(
960
975
return serializeDateFromDateJSON ( value ) ;
961
976
}
962
977
}
963
-
978
+ if ( value . length > 1024 ) {
979
+ // For large strings, we encode them outside the JSON payload so that we
980
+ // don't have to double encode and double parse the strings. This can also
981
+ // be more compact in case the string has a lot of escaped characters.
982
+ return serializeLargeTextString ( request , value ) ;
983
+ }
964
984
return escapeStringValue ( value ) ;
965
985
}
966
986
@@ -1152,7 +1172,7 @@ function emitProviderChunk(
1152
1172
) : void {
1153
1173
const contextReference = serializeProviderReference ( contextName ) ;
1154
1174
const processedChunk = processReferenceChunk ( request , id , contextReference ) ;
1155
- request . completedJSONChunks . push ( processedChunk ) ;
1175
+ request . completedRegularChunks . push ( processedChunk ) ;
1156
1176
}
1157
1177
1158
1178
function retryTask ( request : Request , task : Task ) : void {
@@ -1216,7 +1236,7 @@ function retryTask(request: Request, task: Task): void {
1216
1236
}
1217
1237
1218
1238
const processedChunk = processModelChunk ( request , task . id , value ) ;
1219
- request . completedJSONChunks . push ( processedChunk ) ;
1239
+ request . completedRegularChunks . push ( processedChunk ) ;
1220
1240
request . abortableTasks . delete ( task ) ;
1221
1241
task . status = COMPLETED ;
1222
1242
} catch ( thrownValue ) {
@@ -1323,7 +1343,7 @@ function flushCompletedChunks(
1323
1343
hintChunks . splice ( 0 , i ) ;
1324
1344
1325
1345
// Next comes model data.
1326
- const jsonChunks = request . completedJSONChunks ;
1346
+ const jsonChunks = request . completedRegularChunks ;
1327
1347
i = 0 ;
1328
1348
for ( ; i < jsonChunks . length ; i ++ ) {
1329
1349
request . pendingChunks -- ;
@@ -1545,3 +1565,13 @@ function processHintChunk(
1545
1565
const row = serializeRowHeader ( 'H' + code , id ) + json + '\n' ;
1546
1566
return stringToChunk ( row ) ;
1547
1567
}
1568
+
1569
+ function processTextHeader (
1570
+ request : Request ,
1571
+ id : number ,
1572
+ text : string ,
1573
+ binaryLength : number ,
1574
+ ) : Chunk {
1575
+ const row = id . toString ( 16 ) + ':T' + binaryLength . toString ( 16 ) + ',' ;
1576
+ return stringToChunk ( row ) ;
1577
+ }
0 commit comments