Skip to content

Commit

Permalink
Add HttpStack using Fetch API
Browse files Browse the repository at this point in the history
  • Loading branch information
Acconut committed Jan 17, 2025
1 parent 14d583d commit 6b42194
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
5 changes: 5 additions & 0 deletions browser/FetchHttpStack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"//": "Generated by scripts/setup-exports.js",
"main": "../../lib.cjs/browser/FetchHttpStack.js",
"types": "../../lib.cjs/browser/FetchHttpStack.d.ts"
}
92 changes: 92 additions & 0 deletions lib/browser/FetchHttpStack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type { HttpProgressHandler, HttpRequest, HttpResponse, HttpStack } from '../options.js'

// TODO: Add tests for this.
export class FetchHttpStack implements HttpStack {
createRequest(method: string, url: string) {
return new FetchRequest(method, url)
}

getName() {
return 'FetchHttpStack'
}
}

class FetchRequest implements HttpRequest {
_method: string
_url: string
_headers: Record<string, string> = {}
_controller = new AbortController()

constructor(method: string, url: string) {
this._method = method
this._url = url
}

getMethod(): string {
return this._method
}

getURL(): string {
return this._url
}

setHeader(header: string, value: string): void {
this._headers[header] = value
}

getHeader(header: string) {
return this._headers[header]
}

setProgressHandler(_progressHandler: HttpProgressHandler): void {
// The Fetch API currently does not expose a way to track upload progress.
}

async send(body?: Blob): Promise<FetchResponse> {
const res = await fetch(this._url, {
method: this._method,
headers: this._headers,
body,
signal: this._controller.signal,
})

const resBody = await res.text()
return new FetchResponse(res, resBody)
}

abort(): Promise<void> {
this._controller.abort()
return Promise.resolve()
}

getUnderlyingObject(): undefined {
// In the Fetch API, there is no object representing the request.
return undefined
}
}

class FetchResponse implements HttpResponse {
_res: Response
_body: string

constructor(res: Response, body: string) {
this._res = res
this._body = body
}

getStatus(): number {
return this._res.status
}

getHeader(header: string): string | undefined {
return this._res.headers.get(header) || undefined
}

getBody(): string {
return this._body
}

getUnderlyingObject(): Response {
return this._res
}
}
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,19 @@
"types": "./lib.cjs/node/NodeHttpStack.d.ts",
"default": "./lib.cjs/node/NodeHttpStack.js"
}
},
"./browser/FetchHttpStack": {
"import": {
"types": "./lib.esm/browser/FetchHttpStack.d.ts",
"default": "./lib.esm/browser/FetchHttpStack.js"
},
"require": {
"types": "./lib.cjs/browser/FetchHttpStack.d.ts",
"default": "./lib.cjs/browser/FetchHttpStack.js"
}
}
},
"files": ["lib.cjs/", "lib.esm/", "dist/", "node"],
"files": ["lib.cjs/", "lib.esm/", "dist/", "node", "browser"],
"engines": {
"node": ">=18"
},
Expand Down
7 changes: 6 additions & 1 deletion scripts/setup-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { mkdir, readFile, writeFile } from 'fs/promises'
/**
* Each entry is a "subpackage" that users should be able to import as `tus-js-client/${entry}`.
*/
const EXPORTS = ['node/sources/StreamFileSource', 'node/FileUrlStorage', 'node/NodeHttpStack']
const EXPORTS = [
'node/sources/StreamFileSource',
'node/FileUrlStorage',
'node/NodeHttpStack',
'browser/FetchHttpStack',
]

const root = path.join(import.meta.dirname, '..')

Expand Down

0 comments on commit 6b42194

Please sign in to comment.