62 lines
1.4 KiB
TypeScript
62 lines
1.4 KiB
TypeScript
import type { App } from "@riwa/api-types";
|
|
import { treaty } from "@elysiajs/eden";
|
|
import { toastController } from "@ionic/vue";
|
|
|
|
const client = treaty<App>(window.location.origin, {
|
|
fetch: {
|
|
credentials: "include",
|
|
},
|
|
});
|
|
|
|
export interface SafeClientOptions {
|
|
silent?: boolean;
|
|
immediate?: boolean;
|
|
}
|
|
|
|
export async function safeClient<T, E>(
|
|
requestPromise: () => Promise<{ data: T; error: E }>,
|
|
options: SafeClientOptions = {},
|
|
) {
|
|
const { immediate = true } = options;
|
|
const data = ref<T | null>(null);
|
|
const error = ref<E | null>(null);
|
|
let responseCallback: ((data: T, error: E) => void) | null = null;
|
|
|
|
const execute = async () => {
|
|
const res = await requestPromise();
|
|
|
|
if (res.error) {
|
|
if (!options.silent) {
|
|
const toast = await toastController.create({
|
|
message: typeof error === "string" ? error : "Request failed. Please try again.",
|
|
duration: 3000,
|
|
position: "bottom",
|
|
color: "danger",
|
|
});
|
|
await toast.present();
|
|
}
|
|
|
|
throw res.error;
|
|
}
|
|
data.value = res.data;
|
|
error.value = res.error;
|
|
|
|
// 调用注册的回调函数
|
|
if (responseCallback) {
|
|
responseCallback(res.data, res.error);
|
|
}
|
|
};
|
|
|
|
function onFetchResponse(callback: (data: T, error: E) => void) {
|
|
responseCallback = callback;
|
|
}
|
|
|
|
if (immediate) {
|
|
await execute();
|
|
}
|
|
|
|
return { data, error, refresh: execute, onFetchResponse };
|
|
}
|
|
|
|
export { client };
|