feat: Add support for fetch streaming to js SDK (#9065)

This commit is contained in:
Stevche Radevski
2024-09-10 09:14:10 +02:00
committed by GitHub
parent 0714315792
commit 3244067ee4
4 changed files with 66 additions and 2 deletions

View File

@@ -28,6 +28,7 @@
"typescript": "^5.1.6"
},
"dependencies": {
"fetch-event-stream": "^0.1.5",
"qs": "^6.12.1"
},
"scripts": {

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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"