Files
SnowLuma/.pnpm-store/v11/files/b3/495a99f2963329637cac7b0990965813aee3115eedd81b45bb01cbf2ad7ea4ff671011e3e4d1186d5dc55422a9c63e9b29ca73441b9580a4e485fb799dc48d
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

70 lines
1.9 KiB
Plaintext

import { defaultSerializeError } from './router'
/**
* Well-known symbol used by {@link defer} to tag a promise with
* its deferred state. Consumers can read `promise[TSR_DEFERRED_PROMISE]`
* to access `status`, `data`, or `error`.
*/
export const TSR_DEFERRED_PROMISE = Symbol.for('TSR_DEFERRED_PROMISE')
export type DeferredPromiseState<T> =
| {
status: 'pending'
data?: T
error?: unknown
}
| {
status: 'success'
data: T
}
| {
status: 'error'
data?: T
error: unknown
}
export type DeferredPromise<T> = Promise<T> & {
[TSR_DEFERRED_PROMISE]: DeferredPromiseState<T>
}
/**
* Wrap a promise with a deferred state for use with `<Await>` and `useAwaited`.
*
* The returned promise is augmented with internal state (status/data/error)
* so UI can read progress or suspend until it settles.
*
* @param _promise The promise to wrap.
* @param options Optional config. Provide `serializeError` to customize how
* errors are serialized for transfer.
* @returns The same promise with attached deferred metadata.
* @link https://tanstack.com/router/latest/docs/framework/react/api/router/deferFunction
*/
export function defer<T>(
_promise: Promise<T>,
options?: {
serializeError?: typeof defaultSerializeError
},
) {
const promise = _promise as DeferredPromise<T>
// 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
}