diff --git a/app/stores/app.ts b/app/stores/app.ts index c73cbc4b..ba6db799 100644 --- a/app/stores/app.ts +++ b/app/stores/app.ts @@ -140,14 +140,21 @@ export const useAppStore = defineStore("app", () => { getExtensionEnabled, } = useAppExtensions(); - // oxlint-disable-next-line unicorn/consistent-function-scoping - async function upload(file: File, callbacks: RequestHandlers = {}): Promise { - const store = useAppStore(); + const request_counter = ref(0); + function start_request(): void { + request_counter.value += 1; + } + function stop_request(): void { + request_counter.value -= 1; + } + const is_busy = computed(() => request_counter.value > 0); + + async function upload(file: Readonly, callbacks: RequestHandlers = {}): Promise { const schema = opengeodeweb_front_schemas.api.local.extensions.upload; const { PROJECT: projectName } = useRuntimeConfig().public; const params = { projectName }; const result = await upload_file( - store, + { $id: "app", base_url: base_url.value, start_request, stop_request }, { schema, file, params }, { ...callbacks, @@ -167,9 +174,8 @@ export const useAppStore = defineStore("app", () => { { schema, params }: { schema: JsonRpcSchema; params?: Record }, callbacks: RequestHandlers = {}, ): Promise { - const store = useAppStore(); const result = await api_fetch( - store, + { $id: "app", base_url: base_url.value, start_request, stop_request }, // The app store is only ever used with HTTP ("front") schemas, which always carry `methods`; the wider JsonRpcSchema param above is kept as-is to match this action's public signature (e.g. relayed from get_version-style callers that only know about the shared, looser schema shape). // oxlint-disable-next-line no-unsafe-type-assertion -- narrowing optional `methods` to required is safe here; see comment above. { schema: schema as JsonRpcSchema & { methods: string[] }, params }, @@ -186,15 +192,6 @@ export const useAppStore = defineStore("app", () => { return result as TResult; } - const request_counter = ref(0); - function start_request(): void { - request_counter.value += 1; - } - function stop_request(): void { - request_counter.value -= 1; - } - const is_busy = computed(() => request_counter.value > 0); - const projectFolderPath = ref(""); async function createProjectFolder(): Promise { diff --git a/app/stores/viewer.ts b/app/stores/viewer.ts index 76cf17c2..4ffc7ea3 100644 --- a/app/stores/viewer.ts +++ b/app/stores/viewer.ts @@ -58,6 +58,12 @@ export const useViewerStore = defineStore( viewer_url += "/ws"; return viewer_url; }); + function start_request(): void { + request_counter.value += 1; + } + function stop_request(): void { + request_counter.value -= 1; + } const is_busy = computed(() => request_counter.value > 0); function toggle_picking_mode(value: boolean): void { picking_mode.value = value; @@ -75,9 +81,15 @@ export const useViewerStore = defineStore( }, callbacks: RequestHandlers = {}, ): Promise { - const store = useViewerStore(); + const microservice = { + $id: "viewer", + client: client.value, + base_url: base_url.value, + start_request, + stop_request, + }; const result = await viewer_call( - store, + microservice, { schema, params, @@ -148,13 +160,7 @@ export const useViewerStore = defineStore( } }); } - function start_request(): void { - request_counter.value += 1; - } - function stop_request(): void { - request_counter.value -= 1; - } - async function launch(args: { projectFolderPath?: string } = {}): Promise { + async function launch(args: Readonly<{ projectFolderPath?: string }> = {}): Promise { const appStore = useAppStore(); const { COMMAND_VIEWER, NUXT_ROOT_PATH } = useRuntimeConfig().public; const schema = opengeodeweb_front_schemas.api.local.app.run_viewer; diff --git a/internal/utils/api_fetch.ts b/internal/utils/api_fetch.ts index a48b9edf..9099a8fb 100644 --- a/internal/utils/api_fetch.ts +++ b/internal/utils/api_fetch.ts @@ -57,6 +57,7 @@ function toFetchErrorResponseLike(response: unknown): FetchErrorResponseLike { }; } +// oxlint-disable-next-line max-lines-per-function async function api_fetch( microservice: Microservice, { schema, params = {}, headers = {} }: ApiFetchParams, @@ -65,7 +66,8 @@ async function api_fetch( response_function, response_error_function, timeout, - }: RequestHandlersWithValidation & { timeout?: number } = {}, + skip_feedback_error, + }: RequestHandlersWithValidation & { timeout?: number; skip_feedback_error?: boolean } = {}, ): Promise { console.log("[API] Fetching", microservice.base_url); const feedbackStore = useFeedbackStore(); @@ -84,12 +86,14 @@ async function api_fetch( request_error_function(error: unknown) { microservice.stop_request(); const typedError = toFetchErrorLike(error); - feedbackStore.add_error( - typedError.code ?? 0, - schema.$id, - typedError.message ?? "", - typedError.stack ?? "", - ); + if (!skip_feedback_error) { + feedbackStore.add_error( + typedError.code ?? 0, + schema.$id, + typedError.message ?? "", + typedError.stack ?? "", + ); + } if (request_error_function) { request_error_function(error); } @@ -104,12 +108,14 @@ async function api_fetch( response_error_function(response: unknown) { microservice.stop_request(); const typedResponse = toFetchErrorResponseLike(response); - feedbackStore.add_error( - typedResponse.status ?? 0, - schema.$id, - typedResponse.name ?? "", - typedResponse.description ?? "", - ); + if (!skip_feedback_error) { + feedbackStore.add_error( + typedResponse.status ?? 0, + schema.$id, + typedResponse.name ?? "", + typedResponse.description ?? "", + ); + } if (response_error_function) { response_error_function(response); } diff --git a/shared/utils/fetch_raw.ts b/shared/utils/fetch_raw.ts index a15745bf..fa3d7169 100644 --- a/shared/utils/fetch_raw.ts +++ b/shared/utils/fetch_raw.ts @@ -67,8 +67,8 @@ async function performFetch({ }, async onResponse({ response, - // oxlint-disable-next-line eslint/id-length -- mirrors the real ofetch/vitest API field name (`ok`/`fn`) }: { + // oxlint-disable-next-line eslint/id-length -- mirrors the real ofetch/vitest API field name (`ok`/`fn`) response: { ok: boolean; _data?: unknown }; }) { if (response.ok && response_function) {