mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
59 lines
1.1 KiB
TypeScript
59 lines
1.1 KiB
TypeScript
type SuspenseRecord<T> =
|
|
| {
|
|
status: 'resolved';
|
|
value: T;
|
|
}
|
|
| {
|
|
status: 'rejected';
|
|
error: Error;
|
|
}
|
|
| {
|
|
status: 'pending';
|
|
promise: Promise<T>;
|
|
};
|
|
|
|
export function createAsyncSuspenseValue<T>(getValue: () => Promise<T>) {
|
|
let record: SuspenseRecord<T> | undefined;
|
|
|
|
const load = () => {
|
|
const promise = getValue().then(
|
|
(value) => {
|
|
record = { status: 'resolved', value };
|
|
return value;
|
|
},
|
|
(error) => {
|
|
record = { status: 'rejected', error };
|
|
throw error;
|
|
},
|
|
);
|
|
|
|
record = { status: 'pending', promise };
|
|
return promise;
|
|
};
|
|
|
|
const asyncValue = {
|
|
read() {
|
|
if (!record) {
|
|
throw load();
|
|
}
|
|
|
|
switch (record.status) {
|
|
case 'pending':
|
|
throw record.promise;
|
|
case 'resolved':
|
|
return record.value;
|
|
case 'rejected':
|
|
throw record.error;
|
|
}
|
|
},
|
|
preload() {
|
|
if (record) {
|
|
return;
|
|
}
|
|
load().catch(() => {});
|
|
},
|
|
};
|
|
|
|
return asyncValue;
|
|
}
|