Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: send mocked response body as ReadableStream to the worker (#1288)
- Loading branch information
1 parent
dd60fc9
commit 78c7d7e
Showing
13 changed files
with
341 additions
and
194 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
ServiceWorkerFetchEventMap, | ||
ServiceWorkerIncomingEventsMap, | ||
} from '../../glossary' | ||
|
||
export interface ServiceWorkerMessage< | ||
EventType extends keyof ServiceWorkerIncomingEventsMap, | ||
EventPayload, | ||
> { | ||
type: EventType | ||
payload: EventPayload | ||
} | ||
|
||
export interface WorkerMessageChannel { | ||
send<Event extends keyof ServiceWorkerFetchEventMap>( | ||
message: Parameters<ServiceWorkerFetchEventMap[Event]>[0] extends undefined | ||
? { type: Event } | ||
: { | ||
type: Event | ||
payload: Parameters<ServiceWorkerFetchEventMap[Event]>[0] | ||
}, | ||
): void | ||
} | ||
|
||
/** | ||
* Creates a communication channel between the client | ||
* and the Service Worker associated with the given event. | ||
*/ | ||
export function createMessageChannel( | ||
event: MessageEvent, | ||
): WorkerMessageChannel { | ||
const port = event.ports[0] | ||
|
||
return { | ||
/** | ||
* Send a text message to the connected Service Worker. | ||
*/ | ||
send(message) { | ||
if (!port) { | ||
return | ||
} | ||
|
||
port.postMessage(message) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { invariant } from 'outvariant' | ||
import { StrictBroadcastChannel } from '../../../utils/internal/StrictBroadcastChannel' | ||
import { | ||
SerializedResponse, | ||
ServiceWorkerBroadcastChannelMessageMap, | ||
} from '../../glossary' | ||
import { WorkerMessageChannel } from './createMessageChannel' | ||
|
||
export async function streamResponse( | ||
operationChannel: StrictBroadcastChannel<ServiceWorkerBroadcastChannelMessageMap>, | ||
messageChannel: WorkerMessageChannel, | ||
mockedResponse: SerializedResponse, | ||
): Promise<void> { | ||
const response = new Response(mockedResponse.body, mockedResponse) | ||
|
||
/** | ||
* Delete the ReadableStream response body | ||
* so it doesn't get sent via the message channel. | ||
* @note Otherwise, an error: cannot clone a ReadableStream if | ||
* it hasn't been transformed yet. | ||
*/ | ||
delete mockedResponse.body | ||
|
||
// Signal the mock response stream start event on the global | ||
// message channel because the worker expects an event in response | ||
// to the sent "REQUEST" global event. | ||
messageChannel.send({ | ||
type: 'MOCK_RESPONSE_START', | ||
payload: mockedResponse, | ||
}) | ||
|
||
invariant(response.body, 'Failed to stream mocked response with no body') | ||
|
||
// Read the mocked response body as stream | ||
// and pipe it to the worker. | ||
const reader = response.body.getReader() | ||
|
||
while (true) { | ||
const { done, value } = await reader.read() | ||
|
||
if (!done) { | ||
operationChannel.postMessage({ | ||
type: 'MOCK_RESPONSE_CHUNK', | ||
payload: value, | ||
}) | ||
continue | ||
} | ||
|
||
operationChannel.postMessage({ | ||
type: 'MOCK_RESPONSE_END', | ||
}) | ||
operationChannel.close() | ||
reader.releaseLock() | ||
break | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const ParentClass = | ||
typeof BroadcastChannel == 'undefined' | ||
? class UnsupportedEnvironment { | ||
constructor() { | ||
throw new Error( | ||
'Cannot construct BroadcastChannel in a non-browser environment', | ||
) | ||
} | ||
} | ||
: BroadcastChannel | ||
|
||
export class StrictBroadcastChannel< | ||
MessageMap extends Record<string, any>, | ||
> extends (ParentClass as unknown as { new (name: string): BroadcastChannel }) { | ||
public postMessage<MessageType extends keyof MessageMap>( | ||
message: Parameters<MessageMap[MessageType]>[0] extends undefined | ||
? { | ||
type: MessageType | ||
} | ||
: { | ||
type: MessageType | ||
payload: Parameters<MessageMap[MessageType]>[0] | ||
}, | ||
): void { | ||
return super.postMessage(message) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters