This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / api / load.ts
1.8 kB 60 lines
1import { error, type NumericRange } from "@sveltejs/kit"; 2import { ClientResponseError } from "./client"; 3 4export const httpStatusFor = (cause: unknown): number => { 5 if (cause instanceof ClientResponseError) { 6 if (cause.status >= 400 && cause.status <= 599) return cause.status; 7 switch (cause.error) { 8 case "RecordNotFound": 9 return 404; 10 case "InvalidRequest": 11 return 400; 12 case "UpstreamFailed": 13 case "UpstreamGone": 14 case "InvalidRecord": 15 return 502; 16 case "Overloaded": 17 return 503; 18 default: 19 return 500; 20 } 21 } 22 return 500; 23}; 24 25export const toHttpError = (cause: unknown, fallbackMessage = "Request failed"): never => { 26 const status = httpStatusFor(cause) as NumericRange<400, 599>; 27 const message = 28 cause instanceof ClientResponseError ? (cause.description ?? cause.error) : fallbackMessage; 29 throw error(status, message); 30}; 31 32export const parallel = async <T extends Record<string, Promise<unknown>>>( 33 tasks: T 34): Promise<{ [K in keyof T]: Awaited<T[K]> }> => { 35 const keys = Object.keys(tasks) as (keyof T)[]; 36 const values = await Promise.all(keys.map((key) => tasks[key])); 37 const out = {} as { [K in keyof T]: Awaited<T[K]> }; 38 keys.forEach((key, index) => { 39 out[key] = values[index] as Awaited<T[keyof T]>; 40 }); 41 return out; 42}; 43 44// per-request promise de-dupe cache. 45export interface RequestCache { 46 run<T>(key: string, load: () => Promise<T>): Promise<T>; 47} 48 49export const createRequestCache = (): RequestCache => { 50 const entries = new Map<string, Promise<unknown>>(); 51 return { 52 run<T>(key: string, load: () => Promise<T>): Promise<T> { 53 const existing = entries.get(key) as Promise<T> | undefined; 54 if (existing) return existing; 55 const pending = load(); 56 entries.set(key, pending); 57 return pending; 58 } 59 }; 60};