feat: Add support for fetch streaming to js SDK (#9065)
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"fetch-event-stream": "^0.1.5",
|
||||
"qs": "^6.12.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import qs from "qs"
|
||||
import { ClientFetch, Config, FetchArgs, FetchInput, Logger } from "./types"
|
||||
import { events } from "fetch-event-stream"
|
||||
import {
|
||||
ClientFetch,
|
||||
Config,
|
||||
FetchArgs,
|
||||
FetchInput,
|
||||
FetchStreamResponse,
|
||||
Logger,
|
||||
} from "./types"
|
||||
|
||||
export const PUBLISHABLE_KEY_HEADER = "x-publishable-api-key"
|
||||
|
||||
@@ -110,11 +118,39 @@ export class Client {
|
||||
* @param init: FetchArgs
|
||||
* @returns Promise<T>
|
||||
*/
|
||||
|
||||
fetch<T extends any>(input: FetchInput, init?: FetchArgs): Promise<T> {
|
||||
return this.fetch_(input, init) as unknown as Promise<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* `fetchStream` is a helper method to deal with server-sent events. It returns an object with a stream and an abort function.
|
||||
* It follows a very similar interface to `fetch`, with the return value being an async generator.
|
||||
* The stream is an async generator that yields `ServerSentEventMessage` objects, which contains the event name, stringified data, and few other properties.
|
||||
* The caller is responsible for handling `disconnect` events and aborting the stream. The caller is also responsible for parsing the data field.
|
||||
*
|
||||
* @param input: FetchInput
|
||||
* @param init: FetchArgs
|
||||
* @returns FetchStreamResponse
|
||||
*/
|
||||
async fetchStream(
|
||||
input: FetchInput,
|
||||
init?: FetchArgs
|
||||
): Promise<FetchStreamResponse> {
|
||||
let abort = new AbortController()
|
||||
|
||||
let res = await this.fetch_(input, {
|
||||
...init,
|
||||
signal: abort.signal,
|
||||
headers: { ...init?.headers, accept: "text/event-stream" },
|
||||
})
|
||||
|
||||
if (res.ok) {
|
||||
return { stream: events(res, abort.signal), abort: abort.abort }
|
||||
}
|
||||
|
||||
return { stream: null, abort: abort.abort }
|
||||
}
|
||||
|
||||
setToken(token: string) {
|
||||
this.setToken_(token)
|
||||
}
|
||||
|
||||
@@ -37,3 +37,22 @@ export type ClientFetch = (
|
||||
input: FetchInput,
|
||||
init?: FetchArgs
|
||||
) => Promise<Response>
|
||||
|
||||
// Defined in deno's standard library, and returned by fetch-event-stream package.
|
||||
export interface ServerSentEventMessage {
|
||||
/** Ignored by the client. */
|
||||
comment?: string
|
||||
/** A string identifying the type of event described. */
|
||||
event?: string
|
||||
/** The data field for the message. Split by new lines. */
|
||||
data?: string
|
||||
/** The event ID to set the {@linkcode EventSource} object's last event ID value. */
|
||||
id?: string | number
|
||||
/** The reconnection time. */
|
||||
retry?: number
|
||||
}
|
||||
|
||||
export interface FetchStreamResponse {
|
||||
stream: AsyncGenerator<ServerSentEventMessage, void, unknown> | null
|
||||
abort: () => void
|
||||
}
|
||||
|
||||
@@ -6023,6 +6023,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@medusajs/types": ^1.11.16
|
||||
cross-env: ^5.2.1
|
||||
fetch-event-stream: ^0.1.5
|
||||
jest: ^29.7.0
|
||||
msw: ^2.3.0
|
||||
qs: ^6.12.1
|
||||
@@ -19801,6 +19802,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fetch-event-stream@npm:^0.1.5":
|
||||
version: 0.1.5
|
||||
resolution: "fetch-event-stream@npm:0.1.5"
|
||||
checksum: f5979cbff7bcfc554ba9d80783c972fab99d5e0ab0e0f24bad14d461b31ae847d510bb53a5a06c7ec6e243a7b397475441bc23b6d1e325edc3eda4d0f50f7bbd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fetch-retry@npm:^5.0.2":
|
||||
version: 5.0.6
|
||||
resolution: "fetch-retry@npm:5.0.6"
|
||||
|
||||
Reference in New Issue
Block a user