Skip to content

Instantly share code, notes, and snippets.

@jonathantneal
Created August 23, 2022 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathantneal/a6b6e0b76b47644ac5444196055d262b to your computer and use it in GitHub Desktop.
Save jonathantneal/a6b6e0b76b47644ac5444196055d262b to your computer and use it in GitHub Desktop.
Create a Request, Stringify a Request into JSON, Hydrate JSON back into a Request
// @ts-check
/** Creates a new Request. */
export const create = /** @type {(input: RequestInfo | URL, init?: RequestInit) => Request} */ (
(input, config = any) => new Request(input, config)
)
/** Stringifies a Request into JSON. */
export const stringify = /** @type {(request: Request) => Promise<StringifiedRequest>} */ (async (request) => {
/** URL of the request. */
const input = request.url
/** Configuration of the request. */
const config = /** @type {StringifiedRequestConfig} */ ({})
// assign any unique configuration from the request
for (const name in defaultRequest) {
if (request[name] !== defaultRequest[name]) {
config[name] = request[name]
}
}
// assign any headers from the request
config.headers = Object.fromEntries(request.headers)
// assign any body from the request
if (!request.bodyUsed) {
/** Blob retreived from the request. */
const blob = await request.clone().blob()
// serialize the type and array of the blob
/** @type {[ string, number[] ]} */
config.body = [
blob.type,
[
...new Uint8Array(
await blob.arrayBuffer()
)
]
]
}
return [ input, config ]
})
/** Hydrates JSON back into a Request. */
export const hydrate = /** @type {(json: StringifiedRequest) => Request} */ (
([ input, options ]) => new Request(
input,
{
...options,
body: options.body ? new Blob([
new Uint8Array(options.body[1])
], {
type: options.body[0]
}) : null,
}
)
)
const defaultRequest = {
method: 'GET',
referrer: 'about:client',
/** @type {ReferrerPolicy} */
referrerPolicy: '',
/** @type {RequestMode} */
mode: 'cors',
/** @type {RequestCredentials} */
credentials: 'same-origin',
/** @type {RequestCache} */
cache: 'default',
/** @type {RequestRedirect} */
redirect: 'follow',
integrity: '',
keepalive: false,
}
const any = /** @type {any} */ (null)
/** @typedef {typeof defaultRequest & { headers: { [name: string]: string }, body: [ string, number[] ] | null }} StringifiedRequestConfig */
/** @typedef {[ string, StringifiedRequestConfig ]} StringifiedRequest */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment