vlens
Version:
Data Centric Routing & Rendering Mini-Framework
92 lines (78 loc) • 2.47 kB
text/typescript
type error = string
export type Response<T> = [T | null, error]
export function ok<T>(t: T): Response<T> {
return [t, ""]
}
export function err<T>(e: string): Response<T> {
return [null, e];
}
function generateClientId() {
const bytes = new Uint8Array(8);
crypto.getRandomValues(bytes);
return btoa(String.fromCharCode.apply(null, bytes as any))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
let clientId = generateClientId()
sessionStorage.clientId = clientId
let auth_headers: Record<string, string> = {};
export function setAuthHeaders(headers: Record<string, string>) {
auth_headers = { ...headers };
}
export function getAuthHeaders(): Record<string, string> {
return { ...auth_headers }
}
export function asResponse<T>(obj: T): Promise<Response<T>> {
return Promise.resolve([obj, ""]);
}
export async function call<T>(name: string, body: BodyInit): Promise<Response<T>> {
let t = performance.now()
let method = "POST";
let url = "/rpc/" + name;
let headers = {
...auth_headers,
'X-Client-Id': clientId,
};
let req = new Request(url, { method, body, headers })
let resp = await fetch(req)
// let dur = performance.now() - t
// console.log(name, dur.toFixed(2) + "ms")
if (resp.status === 200) {
let data = await resp.json()
return [data, ""]
} else {
let error = await resp.text()
return [null, error]
}
}
// TODO test?
export function callUpload<T>(name: string, body: FormData, progressFn: (p: number) => void): Promise<Response<T>> {
return new Promise(resolve => {
const xhr = new XMLHttpRequest();
xhr.open('POST', name);
const headers = getAuthHeaders()
for (let key in headers) {
xhr.setRequestHeader(key, headers[key])
}
// progress tracking
xhr.upload.onprogress = (e: ProgressEvent) => {
if (e.lengthComputable) {
progressFn(e.loaded / e.total);
} else {
progressFn(-1); // special value for progress unknown
}
};
xhr.onloadend = () => {
progressFn(1)
};
xhr.onload = () => {
if (xhr.status === 200) {
resolve([JSON.parse(xhr.responseText), ""]);
} else {
resolve([null, xhr.responseText]);
}
};
xhr.send(body);
})
}