import { defaultSerializeError } from './router' export const TSR_DEFERRED_PROMISE = Symbol.for('TSR_DEFERRED_PROMISE') export type DeferredPromiseState = | { status: 'pending' data?: T error?: unknown } | { status: 'success' data: T } | { status: 'error' data?: T error: unknown } export type DeferredPromise = Promise & { [TSR_DEFERRED_PROMISE]: DeferredPromiseState } export function defer( _promise: Promise, options?: { serializeError?: typeof defaultSerializeError }, ) { const promise = _promise as DeferredPromise // this is already deferred promise if ((promise as any)[TSR_DEFERRED_PROMISE]) { return promise } promise[TSR_DEFERRED_PROMISE] = { status: 'pending' } promise .then((data) => { promise[TSR_DEFERRED_PROMISE].status = 'success' promise[TSR_DEFERRED_PROMISE].data = data }) .catch((error) => { promise[TSR_DEFERRED_PROMISE].status = 'error' ;(promise[TSR_DEFERRED_PROMISE] as any).error = { data: (options?.serializeError ?? defaultSerializeError)(error), __isServerError: true, } }) return promise }