@@ -114,7 +114,7 @@ export async function encodeRequestMessage<T extends keyof RequestMessageMap>(
114114
115115 const request = payload as RequestMessageMap [ MessageType . REQUEST ]
116116
117- const { body : processedBody , headers : processedHeaders } = await prepareBodyAndHeadersForSerialization (
117+ const { body : processedBody , headers : processedHeaders } = await serializeBodyAndHeaders (
118118 request . body ,
119119 request . headers ,
120120 )
@@ -139,7 +139,7 @@ export async function encodeRequestMessage<T extends keyof RequestMessageMap>(
139139}
140140
141141export async function decodeRequestMessage ( raw : EncodedMessage ) : Promise < DecodedRequestMessage > {
142- const { json : message , blobData } = await decodeRawMessage ( raw )
142+ const { json : message , buffer } = await decodeRawMessage ( raw )
143143
144144 const id : string = message . i
145145 const type : MessageType = message . t
@@ -157,26 +157,7 @@ export async function decodeRequestMessage(raw: EncodedMessage): Promise<Decoded
157157 const payload = message . p as SerializedRequestPayload
158158
159159 const headers = payload . h ?? { }
160- let body : StandardBody = payload . b
161-
162- const contentType = flattenHeader ( headers [ 'content-type' ] )
163-
164- if ( blobData ) {
165- const contentDisposition = flattenHeader ( headers [ 'content-disposition' ] )
166-
167- if ( contentDisposition === undefined && contentType ?. startsWith ( 'multipart/form-data' ) ) {
168- const tempRes = new Response ( blobData , { headers : { 'content-type' : contentType } } )
169- body = await tempRes . formData ( )
170- }
171- else {
172- // if the body is a file, contentDisposition must be defined
173- const filename = getFilenameFromContentDisposition ( contentDisposition ! ) ?? 'blob'
174- body = new File ( [ blobData ] , filename , { type : contentType } )
175- }
176- }
177- else if ( contentType ?. startsWith ( 'application/x-www-form-urlencoded' ) && typeof body === 'string' ) {
178- body = new URLSearchParams ( body )
179- }
160+ const body = await deserializeBody ( headers , payload . b , buffer )
180161
181162 return [ id , MessageType . REQUEST , { url : new URL ( payload . u , 'orpc:/' ) , headers, method : payload . m ?? 'POST' , body } ]
182163}
@@ -201,7 +182,7 @@ export async function encodeResponseMessage<T extends keyof ResponseMessageMap>(
201182 }
202183
203184 const response = payload as StandardResponse
204- const { body : processedBody , headers : processedHeaders } = await prepareBodyAndHeadersForSerialization (
185+ const { body : processedBody , headers : processedHeaders } = await serializeBodyAndHeaders (
205186 response . body ,
206187 response . headers ,
207188 )
@@ -225,7 +206,7 @@ export async function encodeResponseMessage<T extends keyof ResponseMessageMap>(
225206}
226207
227208export async function decodeResponseMessage ( raw : EncodedMessage ) : Promise < DecodedResponseMessage > {
228- const { json : message , blobData } = await decodeRawMessage ( raw )
209+ const { json : message , buffer } = await decodeRawMessage ( raw )
229210
230211 const id : string = message . i
231212 const type : MessageType | undefined = message . t
@@ -243,32 +224,16 @@ export async function decodeResponseMessage(raw: EncodedMessage): Promise<Decode
243224 const payload = message . p as SerializedResponsePayload
244225
245226 const headers = payload . h ?? { }
246- let body : StandardBody = payload . b
247-
248- const contentType = flattenHeader ( headers [ 'content-type' ] )
249-
250- if ( blobData ) {
251- const contentDisposition = flattenHeader ( headers [ 'content-disposition' ] )
252-
253- // Handle FormData specifically
254- if ( contentDisposition === undefined && contentType ?. startsWith ( 'multipart/form-data' ) ) {
255- const tempRes = new Response ( blobData , { headers : { 'content-type' : contentType } } )
256- body = await tempRes . formData ( )
257- }
258- else {
259- // if the body is a file, contentDisposition must be defined
260- const filename = getFilenameFromContentDisposition ( contentDisposition ! ) ?? 'blob'
261- body = new File ( [ blobData ] , filename , { type : contentType } )
262- }
263- }
264- else if ( contentType ?. startsWith ( 'application/x-www-form-urlencoded' ) && typeof body === 'string' ) {
265- body = new URLSearchParams ( body )
266- }
227+ const body = await deserializeBody ( headers , payload . b , buffer )
267228
268229 return [ id , MessageType . RESPONSE , { status : payload . s ?? 200 , headers, body } ]
269230}
270231
271- async function prepareBodyAndHeadersForSerialization (
232+ /**
233+ * Helper to deal with body and headers
234+ */
235+
236+ async function serializeBodyAndHeaders (
272237 body : StandardBody ,
273238 originalHeaders : StandardHeaders | undefined ,
274239) : Promise < { body : StandardBody | Blob | string | undefined , headers : StandardHeaders } > {
@@ -307,8 +272,25 @@ async function prepareBodyAndHeadersForSerialization(
307272 return { body, headers }
308273}
309274
310- export function isEventIteratorHeaders ( headers : StandardHeaders ) : boolean {
311- return Boolean ( flattenHeader ( headers [ 'content-type' ] ) ?. startsWith ( 'text/event-stream' ) && headers [ 'content-disposition' ] === undefined )
275+ async function deserializeBody ( headers : StandardHeaders , body : unknown , buffer : Uint8Array | undefined ) : Promise < StandardBody > {
276+ const contentType = flattenHeader ( headers [ 'content-type' ] )
277+ const contentDisposition = flattenHeader ( headers [ 'content-disposition' ] )
278+
279+ if ( typeof contentDisposition === 'string' ) {
280+ const filename = getFilenameFromContentDisposition ( contentDisposition ) ?? 'blob'
281+ return new File ( buffer === undefined ? [ ] : [ buffer ] , filename , { type : contentType } )
282+ }
283+
284+ if ( contentType ?. startsWith ( 'multipart/form-data' ) ) {
285+ const tempRes = new Response ( buffer , { headers : { 'content-type' : contentType } } )
286+ return tempRes . formData ( )
287+ }
288+
289+ if ( contentType ?. startsWith ( 'application/x-www-form-urlencoded' ) && typeof body === 'string' ) {
290+ return new URLSearchParams ( body )
291+ }
292+
293+ return body
312294}
313295
314296/**
@@ -318,21 +300,21 @@ export function isEventIteratorHeaders(headers: StandardHeaders): boolean {
318300 */
319301const JSON_AND_BINARY_DELIMITER = 0xFF
320302
321- async function encodeRawMessage ( data : object , blobData ?: Blob ) : Promise < EncodedMessage > {
303+ async function encodeRawMessage ( data : object , blob ?: Blob ) : Promise < EncodedMessage > {
322304 const json = stringifyJSON ( data )
323305
324- if ( blobData === undefined ) {
306+ if ( blob === undefined || blob . size === 0 ) {
325307 return json
326308 }
327309
328310 return new Blob ( [
329311 new TextEncoder ( ) . encode ( json ) ,
330312 new Uint8Array ( [ JSON_AND_BINARY_DELIMITER ] ) ,
331- blobData ,
313+ blob ,
332314 ] ) . arrayBuffer ( )
333315}
334316
335- async function decodeRawMessage ( raw : EncodedMessage ) : Promise < { json : any , blobData ?: Uint8Array } > {
317+ async function decodeRawMessage ( raw : EncodedMessage ) : Promise < { json : any , buffer ?: Uint8Array } > {
336318 if ( typeof raw === 'string' ) {
337319 return { json : JSON . parse ( raw ) }
338320 }
@@ -347,10 +329,10 @@ async function decodeRawMessage(raw: EncodedMessage): Promise<{ json: any, blobD
347329 }
348330
349331 const jsonPart = new TextDecoder ( ) . decode ( buffer . subarray ( 0 , delimiterIndex ) )
350- const blobData = buffer . subarray ( delimiterIndex + 1 )
332+ const bufferPart = buffer . subarray ( delimiterIndex + 1 )
351333
352334 return {
353335 json : JSON . parse ( jsonPart ) ,
354- blobData ,
336+ buffer : bufferPart ,
355337 }
356338}
0 commit comments